X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fwin32_threads.c;h=a9569c83f00e4badf914f06ef241abfab210fb42;hb=83569e1ef07325ec30b00d3e2b955718f210e608;hp=d2e97dee7d0b2cec1e1fca50fe6434ace6579daf;hpb=0abc2e6270020edc4a5b4c66f93b4ae582815f20;p=mono.git diff --git a/libgc/win32_threads.c b/libgc/win32_threads.c index d2e97dee7d0..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 @@ -72,6 +74,17 @@ volatile LONG GC_max_thread_index = 0; /* Largest index in thread_table */ 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 +} + /* * This may be called from DllMain, and hence operates under unusual * constraints. @@ -184,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); } @@ -231,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(); @@ -239,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) { @@ -264,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() @@ -748,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) {