summaryrefslogtreecommitdiff
path: root/win32_threads.c
diff options
context:
space:
mode:
authorivmai <ivmai>2009-12-18 13:09:55 +0100
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 19:06:52 +0200
commitb795ce4a19e8edb6981b03ec76ad7d3e3d4e6db4 (patch)
tree43cdb55def385452af835f582ca91def6e36d131 /win32_threads.c
parent1ee6cb76f3b12d7f8a50c5367a10e9fcb13e5bfb (diff)
2009-12-18 Ivan Maidanski <ivmai@mail.ru> (with input from
Jean-Claude Beaudoin) * include/gc.h (GC_unregister_my_thread): Fix a typo; update the comment. * pthread_support.c (GC_delete_thread): Allow to delete the main thread (don't call GC_INTERNAL_FREE for it); update the comment. * win32_threads.c (GC_delete_thread): Ditto. * pthread_support.c (GC_unregister_my_thread): Add an assertion for FINISHED flag is unset. * tests/test.c (check_heap_stats): Test the main thread unregistering (only if THREADS). * win32_threads.c (GC_register_my_thread_inner): Set flags to DETACHED (only if GC_PTHREADS). * win32_threads.c (GC_unregister_my_thread): Add FIXME (for GC_wait_for_gc_completion). * win32_threads.c (GC_pthread_start_inner): Clear flags detached state if needed; set pthread_id and flags while holding the lock.
Diffstat (limited to 'win32_threads.c')
-rw-r--r--win32_threads.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/win32_threads.c b/win32_threads.c
index 82d1d53..3b0e818 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -442,6 +442,7 @@ STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb,
# ifdef GC_PTHREADS
/* me can be NULL -> segfault */
me -> pthread_id = pthread_self();
+ me -> flags = DETACHED; /* cleared in GC_pthread_start_inner if needed */
# endif
# ifndef MSWINCE
/* GetCurrentThread() returns a pseudohandle (a const value). */
@@ -652,11 +653,11 @@ STATIC void GC_delete_gc_thread(GC_vthread gc_id)
}
/* Delete a thread from GC_threads. We assume it is there. */
-/* (The code intentionally traps if it wasn't.) */
-/* Assumes we hold the allocation lock unless */
-/* GC_win32_dll_threads is set. */
-/* If GC_win32_dll_threads is set it should be called from the */
-/* thread being deleted. */
+/* (The code intentionally traps if it wasn't.) Assumes we */
+/* hold the allocation lock unless GC_win32_dll_threads is set. */
+/* If GC_win32_dll_threads is set then it should be called from */
+/* the thread being deleted. It is also safe to delete the */
+/* main thread (unless GC_win32_dll_threads). */
STATIC void GC_delete_thread(DWORD id)
{
if (GC_win32_dll_threads) {
@@ -685,7 +686,9 @@ STATIC void GC_delete_thread(DWORD id)
} else {
prev -> tm.next = p -> tm.next;
}
- GC_INTERNAL_FREE(p);
+ if (p != &first_thread) {
+ GC_INTERNAL_FREE(p);
+ }
}
}
@@ -723,7 +726,7 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb)
GC_API int GC_CALL GC_unregister_my_thread(void)
{
DWORD t = GetCurrentThreadId();
-
+ /* FIXME: is GC_wait_for_gc_completion(FALSE) needed here? */
if (GC_win32_dll_threads) {
# if defined(THREAD_LOCAL_ALLOC)
/* Can't happen: see GC_use_DllMain(). */
@@ -2433,12 +2436,12 @@ GC_INNER void GC_thr_init(void)
/* we don't need to hold the allocation lock during pthread_create. */
me = GC_register_my_thread_inner(sb, thread_id);
SET_PTHREAD_MAP_CACHE(pthread_id, thread_id);
+ me -> pthread_id = pthread_id;
+ if (!si->detached) me -> flags &= ~DETACHED;
UNLOCK();
start = si -> start_routine;
start_arg = si -> arg;
- if (si-> detached) me -> flags |= DETACHED;
- me -> pthread_id = pthread_id;
GC_free(si); /* was allocated uncollectable */