summaryrefslogtreecommitdiff
path: root/win32_threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32_threads.c')
-rwxr-xr-xwin32_threads.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/win32_threads.c b/win32_threads.c
index 1f9ab94..a2f65a5 100755
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -1,6 +1,7 @@
#if defined(GC_WIN32_THREADS)
#include "private/gc_priv.h"
+#include <windows.h>
#ifdef CYGWIN32
# include <errno.h>
@@ -19,14 +20,10 @@
#endif
-
-#if 0
-#define STRICT
-#include <windows.h>
+#ifndef MAX_THREADS
+# define MAX_THREADS 64
#endif
-#define MAX_THREADS 64
-
struct thread_entry {
LONG in_use;
DWORD id;
@@ -58,7 +55,7 @@ void GC_push_thread_structures GC_PROTO((void))
for (i = 0; i < MAX_THREADS; i++)
if (thread_table[i].in_use) GC_push_all((ptr_t)&(thread_table[i].status),(ptr_t)(&(thread_table[i].status)+1));
}
-#endif
+# endif
}
void GC_stop_world()
@@ -87,14 +84,15 @@ void GC_stop_world()
DWORD exitCode;
if (GetExitCodeThread(thread_table[i].handle,&exitCode) &&
exitCode != STILL_ACTIVE) {
- thread_table[i].stack = 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].stack = 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);
BZERO((void *)(&thread_table[i].context), sizeof(CONTEXT));
-#endif
- continue;
+# endif
+ continue;
}
if (SuspendThread(thread_table[i].handle) == (DWORD)-1)
ABORT("SuspendThread failed");
@@ -372,9 +370,13 @@ void GC_get_next_stack(char *start, char **lo, char **hi)
if (*lo < start) *lo = start;
}
-#if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))
+#if !defined(CYGWIN32)
-HANDLE WINAPI GC_CreateThread(
+#if !defined(MSWINCE) && defined(GC_DLL)
+
+/* We register threads from DllMain */
+
+GC_API HANDLE GC_CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
@@ -383,7 +385,10 @@ HANDLE WINAPI GC_CreateThread(
lpParameter, dwCreationFlags, lpThreadId);
}
-#else /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */
+#else /* defined(MSWINCE) || !defined(GC_DLL)) */
+
+/* We have no DllMain to take care of new threads. Thus we */
+/* must properly intercept thread creation. */
typedef struct {
HANDLE child_ready_h, parent_ready_h;
@@ -509,6 +514,8 @@ static DWORD WINAPI thread_start(LPVOID arg)
}
#endif /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */
+#endif /* !CYGWIN32 */
+
#ifdef MSWINCE
typedef struct {
@@ -564,10 +571,11 @@ DWORD WINAPI main_thread_start(LPVOID arg)
LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
-/* threadAttach/threadDetach routines used by both CYGWIN and DLL implementation,
- since both recieve explicit notification on thread creation/destruction
+/* threadAttach/threadDetach routines used by both CYGWIN and DLL
+ * implementation, since both recieve explicit notification on thread
+ * creation/destruction.
*/
-void threadAttach() {
+static void threadAttach() {
int i;
/* It appears to be unsafe to acquire a lock here, since this */
/* code is apparently not preeemptible on some systems. */
@@ -616,7 +624,7 @@ void threadAttach() {
while (GC_please_stop) Sleep(20);
}
-void threadDetach(DWORD thread_id) {
+static void threadDetach(DWORD thread_id) {
int i;
LOCK();
@@ -782,7 +790,8 @@ void GC_thread_exit_proc(void *arg)
int i;
# if DEBUG_CYGWIN_THREADS
- GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",(int)pthread_self(),GetCurrentThreadId());
+ GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",
+ (int)pthread_self(),GetCurrentThreadId());
# endif
LOCK();
@@ -805,13 +814,13 @@ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {
int GC_pthread_detach(pthread_t thread) {
return pthread_detach(thread);
}
-#else
+#else /* !CYGWIN32 */
/*
- * This isn't generally safe, since DllMain is not premptible.
- * If another thread holds the lock while this runs we're in trouble.
+ * 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
BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
{
switch (reason) {
@@ -852,7 +861,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
}
return TRUE;
}
-#endif /* CYGWIN32 */
+#endif /* GC_DLL */
+#endif /* !CYGWIN32 */
# endif /* !MSWINCE */