Author: axeld Date: 2009-11-16 14:08:36 +0100 (Mon, 16 Nov 2009) New Revision: 34074 Changeset: http://dev.haiku-os.org/changeset/34074/haiku Ticket: http://dev.haiku-os.org/ticket/4917 Modified: haiku/trunk/src/system/kernel/sem.cpp Log: * Change get_next_sem_info() to be index based, not ID based - the semaphore IDs aren't monotonically increasing which this code was assuming. This fixes bug #4917. Modified: haiku/trunk/src/system/kernel/sem.cpp =================================================================== --- haiku/trunk/src/system/kernel/sem.cpp 2009-11-16 11:57:19 UTC (rev 34073) +++ haiku/trunk/src/system/kernel/sem.cpp 2009-11-16 13:08:36 UTC (rev 34074) @@ -1123,47 +1123,39 @@ if (team == NULL) return B_BAD_TEAM_ID; - int32 id = *_cookie; - sem_entry* sem = NULL; - - if (id != 0) { - // shortcut to the first entry - sem = &sSems[id % sMaxSems]; - GRAB_SEM_LOCK(*sem); - - // Check if the semaphore got deleted or reused in the mean time - if (sem->id != id) - sem = NULL; - - RELEASE_SEM_LOCK(*sem); - } - if (sem == NULL) - sem = (sem_entry*)list_get_first_item(&team->sem_list); - + // TODO: find a way to iterate the list that is more reliable + sem_entry* sem = (sem_entry*)list_get_first_item(&team->sem_list); + int32 newIndex = *_cookie; + int32 index = 0; bool found = false; while (!found) { // find the next entry to be returned - while (sem != NULL && id >= sem->id) + while (sem != NULL && index < newIndex) { sem = (sem_entry*)list_get_next_item(&team->sem_list, sem); + index++; + } if (sem == NULL) return B_BAD_VALUE; GRAB_SEM_LOCK(*sem); + if (sem->id != -1 && sem->u.used.owner == team) { // found one! fill_sem_info(sem, info, size); - id = sem->id; + newIndex = index + 1; found = true; - } + } else + newIndex++; + RELEASE_SEM_LOCK(*sem); } if (!found) return B_BAD_VALUE; - *_cookie = id; + *_cookie = newIndex; return B_OK; }