summaryrefslogtreecommitdiff
path: root/pthread_support.c
diff options
context:
space:
mode:
authorivmai <ivmai>2011-05-17 10:59:42 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 19:06:59 +0200
commit77ffb1ff58523f4ee461e1d1ae1a1ae1ddd9b601 (patch)
treecd94370e23c830020d44e5802f4bc3b0ec74cfd1 /pthread_support.c
parentd6f2674f15e848495b2ed9db1689e425cd2e1115 (diff)
2011-05-17 Ivan Maidanski <ivmai@mail.ru>
* pthread_support.c (pthread_join): Add assertion (check thread is finished). * pthread_support.c (GC_register_my_thread): Don't detach the thread if invoked from the thread destructor. * win32_threads.c (GC_register_my_thread): Ditto. * win32_threads.c (GC_unregister_my_thread): Don't delete the thread (just set FINISHED) if the thread is not detached (only if GC_PTHREADS); add assertion (check the thread is not finished). * tests/threadkey_test.c (main): Join some created threads.
Diffstat (limited to 'pthread_support.c')
-rw-r--r--pthread_support.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/pthread_support.c b/pthread_support.c
index 58d515d..f2d1754 100644
--- a/pthread_support.c
+++ b/pthread_support.c
@@ -1250,6 +1250,7 @@ GC_API int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
if (result == 0) {
LOCK();
/* Here the pthread thread id may have been recycled. */
+ GC_ASSERT((t -> flags & FINISHED) != 0);
GC_delete_gc_thread(t);
UNLOCK();
}
@@ -1402,20 +1403,8 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb)
LOCK();
me = GC_lookup_thread(self);
- if (0 == me || (me -> flags & FINISHED) != 0) {
- if (me == 0) {
- me = GC_register_my_thread_inner(sb, self);
- } else {
- /* This code is executed when a thread is registered from the */
- /* client thread key destructor. */
- GC_record_stack_base(me, sb);
- me -> flags &= ~FINISHED;
-# ifdef GC_EXPLICIT_SIGNALS_UNBLOCK
- /* Since this could be executed from a thread destructor, */
- /* our signals might be blocked. */
- GC_unblock_gc_signals();
-# endif
- }
+ if (0 == me) {
+ me = GC_register_my_thread_inner(sb, self);
me -> flags |= DETACHED;
/* Treat as detached, since we do not need to worry about */
/* pointer results. */
@@ -1424,6 +1413,21 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb)
# endif
UNLOCK();
return GC_SUCCESS;
+ } else if ((me -> flags & FINISHED) != 0) {
+ /* This code is executed when a thread is registered from the */
+ /* client thread key destructor. */
+ GC_record_stack_base(me, sb);
+ me -> flags &= ~FINISHED; /* but not DETACHED */
+# ifdef GC_EXPLICIT_SIGNALS_UNBLOCK
+ /* Since this could be executed from a thread destructor, */
+ /* our signals might be blocked. */
+ GC_unblock_gc_signals();
+# endif
+# if defined(THREAD_LOCAL_ALLOC)
+ GC_init_thread_local(&(me->tlfs));
+# endif
+ UNLOCK();
+ return GC_SUCCESS;
} else {
UNLOCK();
return GC_DUPLICATE;