summaryrefslogtreecommitdiff
path: root/lib/glthread/thread.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2019-06-20 04:16:20 +0200
committerBruno Haible <bruno@clisp.org>2019-06-20 04:17:11 +0200
commit0894f96f89e0e44bdf2921e6cd51fca429bf9802 (patch)
tree24ba548ed51d2b75af2299102410646764738c67 /lib/glthread/thread.c
parent7435d61f26ef6dece4f94ea00972145b587ef7ab (diff)
downloadgnulib-0894f96f89e0e44bdf2921e6cd51fca429bf9802.tar.gz
windows-thread: New module.
* lib/windows-thread.h: New file, based on lib/glthread/thread.h. * lib/windows-thread.c: New file, based on lib/glthread/thread.c. * lib/glthread/thread.h: Include windows-thread.h. (gl_thread_t): Define using glwthread_thread_t. (glthread_create): Define using glwthread_thread_create. (glthread_join): Define using glwthread_thread_join. (gl_thread_self): Define using glwthread_thread_self. (gl_thread_exit): Define using glwthread_thread_exit. (glthread_create_func, glthread_join_func, gl_thread_self_func, gl_thread_exit_func): Remove declarations. * lib/glthread/thread.c (self_key): Remove variable. (do_init_self_key, init_self_key): Remove functions. (struct gl_thread_struct): Remove type. (get_current_thread_handle, gl_thread_self_func, wrapper_func, glthread_create_func, glthread_join_func, gl_thread_exit_func): Remove functions. * modules/windows-thread: New file. * modules/thread (Depends-on): Add windows-thread.
Diffstat (limited to 'lib/glthread/thread.c')
-rw-r--r--lib/glthread/thread.c182
1 files changed, 0 insertions, 182 deletions
diff --git a/lib/glthread/thread.c b/lib/glthread/thread.c
index 9461949911..9da054242b 100644
--- a/lib/glthread/thread.c
+++ b/lib/glthread/thread.c
@@ -45,188 +45,6 @@ const gl_thread_t gl_null_thread /* = { .p = NULL } */;
#if USE_WINDOWS_THREADS
-#include <process.h>
-
-/* -------------------------- gl_thread_t datatype -------------------------- */
-
-/* The Thread-Local Storage (TLS) key that allows to access each thread's
- 'struct gl_thread_struct *' pointer. */
-static DWORD self_key = (DWORD)-1;
-
-/* Initializes self_key. This function must only be called once. */
-static void
-do_init_self_key (void)
-{
- self_key = TlsAlloc ();
- /* If this fails, we're hosed. */
- if (self_key == (DWORD)-1)
- abort ();
-}
-
-/* Initializes self_key. */
-static void
-init_self_key (void)
-{
- gl_once_define(static, once)
- gl_once (once, do_init_self_key);
-}
-
-/* This structure contains information about a thread.
- It is stored in TLS under key self_key. */
-struct gl_thread_struct
-{
- /* Fields for managing the handle. */
- HANDLE volatile handle;
- CRITICAL_SECTION handle_lock;
- /* Fields for managing the exit value. */
- void * volatile result;
- /* Fields for managing the thread start. */
- void * (*func) (void *);
- void *arg;
-};
-
-/* Return a real HANDLE object for the current thread. */
-static HANDLE
-get_current_thread_handle (void)
-{
- HANDLE this_handle;
-
- /* GetCurrentThread() returns a pseudo-handle, i.e. only a symbolic
- identifier, not a real handle. */
- if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
- GetCurrentProcess (), &this_handle,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- abort ();
- return this_handle;
-}
-
-gl_thread_t
-gl_thread_self_func (void)
-{
- gl_thread_t thread;
-
- if (self_key == (DWORD)-1)
- init_self_key ();
- thread = TlsGetValue (self_key);
- if (thread == NULL)
- {
- /* This happens only in threads that have not been created through
- glthread_create(), such as the main thread. */
- for (;;)
- {
- thread =
- (struct gl_thread_struct *)
- malloc (sizeof (struct gl_thread_struct));
- if (thread != NULL)
- break;
- /* Memory allocation failed. There is not much we can do. Have to
- busy-loop, waiting for the availability of memory. */
- Sleep (1);
- }
-
- thread->handle = get_current_thread_handle ();
- InitializeCriticalSection (&thread->handle_lock);
- thread->result = NULL; /* just to be deterministic */
- TlsSetValue (self_key, thread);
- }
- return thread;
-}
-
-/* The main function of a freshly creating thread. It's a wrapper around
- the FUNC and ARG arguments passed to glthread_create_func. */
-static unsigned int WINAPI
-wrapper_func (void *varg)
-{
- struct gl_thread_struct *thread = (struct gl_thread_struct *)varg;
-
- EnterCriticalSection (&thread->handle_lock);
- /* Create a new handle for the thread only if the parent thread did not yet
- fill in the handle. */
- if (thread->handle == NULL)
- thread->handle = get_current_thread_handle ();
- LeaveCriticalSection (&thread->handle_lock);
-
- if (self_key == (DWORD)-1)
- init_self_key ();
- TlsSetValue (self_key, thread);
-
- /* Run the thread. Store the exit value if the thread was not terminated
- otherwise. */
- thread->result = thread->func (thread->arg);
- return 0;
-}
-
-int
-glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg)
-{
- struct gl_thread_struct *thread =
- (struct gl_thread_struct *) malloc (sizeof (struct gl_thread_struct));
- if (thread == NULL)
- return ENOMEM;
- thread->handle = NULL;
- InitializeCriticalSection (&thread->handle_lock);
- thread->result = NULL; /* just to be deterministic */
- thread->func = func;
- thread->arg = arg;
-
- {
- unsigned int thread_id;
- HANDLE thread_handle;
-
- thread_handle = (HANDLE)
- _beginthreadex (NULL, 100000, wrapper_func, thread, 0, &thread_id);
- /* calls CreateThread with the same arguments */
- if (thread_handle == NULL)
- {
- DeleteCriticalSection (&thread->handle_lock);
- free (thread);
- return EAGAIN;
- }
-
- EnterCriticalSection (&thread->handle_lock);
- if (thread->handle == NULL)
- thread->handle = thread_handle;
- else
- /* thread->handle was already set by the thread itself. */
- CloseHandle (thread_handle);
- LeaveCriticalSection (&thread->handle_lock);
-
- *threadp = thread;
- return 0;
- }
-}
-
-int
-glthread_join_func (gl_thread_t thread, void **retvalp)
-{
- if (thread == NULL)
- return EINVAL;
-
- if (thread == gl_thread_self ())
- return EDEADLK;
-
- if (WaitForSingleObject (thread->handle, INFINITE) == WAIT_FAILED)
- return EINVAL;
-
- if (retvalp != NULL)
- *retvalp = thread->result;
-
- DeleteCriticalSection (&thread->handle_lock);
- CloseHandle (thread->handle);
- free (thread);
-
- return 0;
-}
-
-int
-gl_thread_exit_func (void *retval)
-{
- gl_thread_t thread = gl_thread_self ();
- thread->result = retval;
- _endthreadex (0); /* calls ExitThread (0) */
- abort ();
-}
-
#endif
/* ========================================================================= */