summaryrefslogtreecommitdiff
path: root/specific.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-04-21 14:31:26 +0400
committerIvan Maidanski <ivmai@mail.ru>2012-04-21 14:31:26 +0400
commitb71fcac4d1b65e2f412cf7edd3a6979aeb870a33 (patch)
tree47ed3f1157499e56bc542f9118660b6115c9933c /specific.c
parent92da43f0a4725ce2a3b3b260dbd2f420ac9c1b25 (diff)
downloadbdwgc-b71fcac4d1b65e2f412cf7edd3a6979aeb870a33.tar.gz
Fix GC_setspecific to prevent garbage collection inside
* specific.c (GC_setspecific): Call MALLOC_CLEAR with GC temporarily disabled; add comment about lock.
Diffstat (limited to 'specific.c')
-rw-r--r--specific.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/specific.c b/specific.c
index 5f4765df..a7114cb2 100644
--- a/specific.c
+++ b/specific.c
@@ -47,14 +47,19 @@ GC_INNER int GC_key_create_inner(tsd ** key_ptr)
return 0;
}
+/* Called with the lock held. */
GC_INNER int GC_setspecific(tsd * key, void * value)
{
pthread_t self = pthread_self();
int hash_val = HASH(self);
- volatile tse * entry = (volatile tse *)MALLOC_CLEAR(sizeof (tse));
+ volatile tse * entry;
GC_ASSERT(self != INVALID_THREADID);
+ GC_dont_gc++; /* disable GC */
+ entry = (volatile tse *)MALLOC_CLEAR(sizeof(tse));
+ GC_dont_gc--;
if (0 == entry) return ENOMEM;
+
pthread_mutex_lock(&(key -> lock));
/* Could easily check for an existing entry here. */
entry -> next = key->hash[hash_val].p;