GC_threads table may contain several elements with the same pthread id,
so GC_remove_all_threads_but_me should remove all elements except for
the first found element matching the id of the current thread.
* pthread_support.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Do not assign me if it is already non-null; add comment.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Likewise.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Remove GC_ASSERT(me==NULL).
me = 0;
for (p = GC_threads[hv]; 0 != p; p = next) {
next = p -> next;
- if (THREAD_EQUAL(p -> id, self)) {
+ if (THREAD_EQUAL(p -> id, self)
+ && me == NULL) { /* ignore dead threads with the same id */
me = p;
p -> next = 0;
# ifdef GC_DARWIN_THREADS
for (hv = 0; hv < THREAD_TABLE_SZ; ++hv) {
for (p = GC_threads[hv]; 0 != p; p = next) {
next = p -> tm.next;
- if (THREAD_EQUAL(p -> pthread_id, pthread_id)) {
- GC_ASSERT(me == NULL);
+ if (THREAD_EQUAL(p -> pthread_id, pthread_id)
+ && me == NULL) { /* ignore dead threads with the same id */
me = p;
p -> tm.next = 0;
} else {