X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fwin32_threads.c;h=a9569c83f00e4badf914f06ef241abfab210fb42;hb=83569e1ef07325ec30b00d3e2b955718f210e608;hp=681e1c2b82e85b8652403a21c41589176bef3089;hpb=234225d112c4b018b8d1796f4c06a15812137500;p=mono.git diff --git a/libgc/win32_threads.c b/libgc/win32_threads.c index 681e1c2b82e..a9569c83f00 100644 --- a/libgc/win32_threads.c +++ b/libgc/win32_threads.c @@ -1,6 +1,7 @@ +#include "private/gc_priv.h" + #if defined(GC_WIN32_THREADS) -#include "private/gc_priv.h" #include #ifdef CYGWIN32 @@ -10,6 +11,7 @@ # undef pthread_create # undef pthread_sigmask # undef pthread_join +# undef pthread_detach # undef dlopen # define DEBUG_CYGWIN_THREADS 0 @@ -74,7 +76,13 @@ extern LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info); int GC_thread_is_registered (void) { +#if defined(GC_DLL) || defined(GC_INSIDE_DLL) + /* Registered by DllMain */ return 1; +#else + /* FIXME: */ + return 0; +#endif } /* @@ -189,7 +197,7 @@ static void GC_delete_thread(DWORD thread_id) { /* Must still be in_use, since nobody else can store our thread_id. */ i++) {} if (i > my_max) { - WARN("Removing nonexisiting thread %ld\n", (GC_word)thread_id); + WARN("Removing nonexistent thread %ld\n", (GC_word)thread_id); } else { GC_delete_gc_thread(thread_table+i); } @@ -236,6 +244,9 @@ void GC_push_thread_structures GC_PROTO((void)) # endif } +/* Defined in misc.c */ +extern CRITICAL_SECTION GC_write_cs; + void GC_stop_world() { DWORD thread_id = GetCurrentThreadId(); @@ -244,6 +255,9 @@ void GC_stop_world() if (!GC_thr_initialized) ABORT("GC_stop_world() called before GC_thr_init()"); GC_please_stop = TRUE; +# ifndef CYGWIN32 + EnterCriticalSection(&GC_write_cs); +# endif /* !CYGWIN32 */ for (i = 0; i <= GC_get_max_thread_index(); i++) if (thread_table[i].stack_base != 0 && thread_table[i].id != thread_id) { @@ -269,11 +283,21 @@ void GC_stop_world() # endif continue; } - if (SuspendThread(thread_table[i].handle) == (DWORD)-1) - ABORT("SuspendThread failed"); + if (SuspendThread(thread_table[i].handle) == (DWORD)-1) { + thread_table[i].stack_base = 0; /* prevent stack from being pushed */ +# ifndef CYGWIN32 + /* this breaks pthread_join on Cygwin, which is guaranteed to */ + /* only see user pthreads */ + thread_table[i].in_use = FALSE; + CloseHandle(thread_table[i].handle); +# endif + } # endif thread_table[i].suspended = TRUE; } +# ifndef CYGWIN32 + LeaveCriticalSection(&GC_write_cs); +# endif /* !CYGWIN32 */ } void GC_start_world() @@ -753,7 +777,7 @@ int GC_pthread_detach(pthread_t thread) * We avoid acquiring locks here, since this doesn't seem to be preemptable. * Pontus Rydin suggests wrapping the thread start routine instead. */ -#ifdef GC_DLL +#if defined(GC_DLL) || defined(GC_INSIDE_DLL) BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) { switch (reason) {