mesa: fix deadlock in _mesa_HashFindFreeKeyBlock()

Fixes fd.o bug 27340.
(cherry picked from commit 8fe3b3f66ae57a1a6eca7f6dcb0455e14ad92075)
This commit is contained in:
Brian Paul 2010-03-27 08:58:59 -06:00
parent 7996f0fc2c
commit 038d2607ab
1 changed files with 13 additions and 6 deletions

View File

@ -127,8 +127,8 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table)
* *
* \return pointer to user's data or NULL if key not in table * \return pointer to user's data or NULL if key not in table
*/ */
void * static INLINE void *
_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key) _mesa_HashLookup_unlocked(struct _mesa_HashTable *table, GLuint key)
{ {
GLuint pos; GLuint pos;
const struct HashEntry *entry; const struct HashEntry *entry;
@ -137,19 +137,26 @@ _mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
assert(key); assert(key);
pos = HASH_FUNC(key); pos = HASH_FUNC(key);
_glthread_LOCK_MUTEX(table->Mutex);
entry = table->Table[pos]; entry = table->Table[pos];
while (entry) { while (entry) {
if (entry->Key == key) { if (entry->Key == key) {
_glthread_UNLOCK_MUTEX(table->Mutex);
return entry->Data; return entry->Data;
} }
entry = entry->Next; entry = entry->Next;
} }
_glthread_UNLOCK_MUTEX(table->Mutex);
return NULL; return NULL;
} }
void *
_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
{
void *res;
assert(table);
_glthread_LOCK_MUTEX(table->Mutex);
res = _mesa_HashLookup_unlocked(table, key);
_glthread_UNLOCK_MUTEX(table->Mutex);
return res;
}
/** /**
@ -447,7 +454,7 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
GLuint freeStart = 1; GLuint freeStart = 1;
GLuint key; GLuint key;
for (key = 1; key != maxKey; key++) { for (key = 1; key != maxKey; key++) {
if (_mesa_HashLookup(table, key)) { if (_mesa_HashLookup_unlocked(table, key)) {
/* darn, this key is already in use */ /* darn, this key is already in use */
freeCount = 0; freeCount = 0;
freeStart = key+1; freeStart = key+1;