diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2017-08-28 09:27:07 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2017-08-28 10:46:55 +0300 |
commit | 6383cee08869517ec3dee257d0adb582c4fc7805 (patch) | |
tree | d8e2caa793f41722461489048ce0929ad334b3e0 /specific.c | |
parent | eb41b8b6ad7efbf740db8c717a2e019cb0bb71d3 (diff) | |
download | bdwgc-6383cee08869517ec3dee257d0adb582c4fc7805.tar.gz |
Fix GC_remove_specific invocation from remove_all_threads_but_me
(fix commits fcfae7f, 38e65ea)
* include/private/specific.h (GC_remove_specific): Define as macro
(calls GC_remove_specific_after_fork).
* include/private/specific.h (GC_remove_specific_after_fork): New
GC_INNER function declaration.
* include/private/thread_local_alloc.h [USE_PTHREAD_SPECIFIC
|| USE_COMPILER_TLS || USE_WIN32_COMPILER_TLS || USE_WIN32_SPECIFIC]
(GC_remove_specific_after_fork): New macro (defined to no-op).
* pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Call GC_remove_specific_after_fork
instead of GC_remove_specific (i.e. delete thread-specific control data
for the given thread instead of the current one).
* win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC] Like
* specific.c [USE_CUSTOM_SPECIFIC] (GC_setspecific): Add assertion that
the allocation lock is held; remove the corresponding comment.
* specific.c [USE_CUSTOM_SPECIFIC] (GC_remove_specific): Replace to
GC_remove_specific_after_fork (add t argument); replace self local
variable with t argument; update comment;
* specific.c [USE_CUSTOM_SPECIFIC && CAN_HANDLE_FORK]
(GC_remove_specific_after_fork): Add assertion that the allocation lock
is held; add comment.
Diffstat (limited to 'specific.c')
-rw-r--r-- | specific.c | 20 |
1 files changed, 13 insertions, 7 deletions
@@ -46,13 +46,13 @@ 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; + GC_ASSERT(I_HOLD_LOCK()); GC_ASSERT(self != INVALID_THREADID); GC_dont_gc++; /* disable GC */ entry = (volatile tse *)MALLOC_CLEAR(sizeof(tse)); @@ -72,18 +72,24 @@ GC_INNER int GC_setspecific(tsd * key, void * value) return 0; } -/* Remove thread-specific data for this thread. Should be called on */ -/* thread exit. */ -GC_INNER void GC_remove_specific(tsd * key) +/* Remove thread-specific data for a given thread. This function is */ +/* called at fork from the child process for all threads except for the */ +/* survived one. GC_remove_specific() should be called on thread exit. */ +GC_INNER void GC_remove_specific_after_fork(tsd * key, pthread_t t) { - pthread_t self = pthread_self(); - unsigned hash_val = HASH(self); + unsigned hash_val = HASH(t); tse *entry; tse **link = &key->hash[hash_val].p; +# ifdef CAN_HANDLE_FORK + /* Both GC_setspecific and GC_remove_specific should be called */ + /* with the allocation lock held to ensure the consistency of */ + /* the hash table in the forked child. */ + GC_ASSERT(I_HOLD_LOCK()); +# endif pthread_mutex_lock(&(key -> lock)); entry = *link; - while (entry != NULL && entry -> thread != self) { + while (entry != NULL && entry -> thread != t) { link = &(entry -> next); entry = *link; } |