diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-06-12 12:09:34 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-06-12 12:09:34 -0400 |
commit | 1036ef2bf468611d37b5df06fc4424f2002e3837 (patch) | |
tree | f0859a6d903c2570a0a00c918da88139f8f7d065 /src/mesa/main/hash.c | |
parent | 917f8bc1a85e61311cef6478127b387df70fba14 (diff) | |
parent | 1cd0afffc9edbcac690f8ab436aecfced26b0aba (diff) |
Merge master and fix conflicts
Diffstat (limited to 'src/mesa/main/hash.c')
-rw-r--r-- | src/mesa/main/hash.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c index 976f9d999b..08c64568c8 100644 --- a/src/mesa/main/hash.c +++ b/src/mesa/main/hash.c @@ -63,6 +63,7 @@ struct _mesa_HashTable { struct HashEntry *Table[TABLE_SIZE]; /**< the lookup table */ GLuint MaxKey; /**< highest key inserted so far */ _glthread_Mutex Mutex; /**< mutual exclusion lock */ + _glthread_Mutex WalkMutex; /**< for _mesa_HashWalk() */ GLboolean InDeleteAll; /**< Debug check */ }; @@ -79,6 +80,7 @@ _mesa_NewHashTable(void) struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable); if (table) { _glthread_INIT_MUTEX(table->Mutex); + _glthread_INIT_MUTEX(table->WalkMutex); } return table; } @@ -111,6 +113,7 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table) } } _glthread_DESTROY_MUTEX(table->Mutex); + _glthread_DESTROY_MUTEX(table->WalkMutex); _mesa_free(table); } @@ -285,6 +288,11 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table, /** * Walk over all entries in a hash table, calling callback function for each. + * Note: we use a separate mutex in this function to avoid a recursive + * locking deadlock (in case the callback calls _mesa_HashRemove()) and to + * prevent multiple threads/contexts from getting tangled up. + * A lock-less version of this function could be used when the table will + * not be modified. * \param table the hash table to walk * \param callback the callback function * \param userData arbitrary pointer to pass along to the callback @@ -300,14 +308,16 @@ _mesa_HashWalk(const struct _mesa_HashTable *table, GLuint pos; ASSERT(table); ASSERT(callback); - _glthread_LOCK_MUTEX(table2->Mutex); + _glthread_LOCK_MUTEX(table2->WalkMutex); for (pos = 0; pos < TABLE_SIZE; pos++) { - struct HashEntry *entry; - for (entry = table->Table[pos]; entry; entry = entry->Next) { + struct HashEntry *entry, *next; + for (entry = table->Table[pos]; entry; entry = next) { + /* save 'next' pointer now in case the callback deletes the entry */ + next = entry->Next; callback(entry->Key, entry->Data, userData); } } - _glthread_UNLOCK_MUTEX(table2->Mutex); + _glthread_UNLOCK_MUTEX(table2->WalkMutex); } |