annotate lib/glthread/thread.c @ 30245:df7871e79216

Fix the Win32 implementation of the 'thread' module.
author Bruno Haible <bruno@clisp.org>
date Wed, 01 Oct 2008 02:28:35 +0200
parents 031c5ec89598
children b40075443afa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Creating and controlling threads.
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
2 Copyright (C) 2005-2008 Free Software Foundation, Inc.
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software; you can redistribute it and/or modify
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 2, or (at your option)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 any later version.
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 along with this program; if not, write to the Free Software Foundation,
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 /* Written by Bruno Haible <bruno@clisp.org>, 2005.
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 gthr-win32.h. */
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <config.h>
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
24 /* Specification. */
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include "glthread/thread.h"
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdlib.h>
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include "glthread/lock.h"
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 /* ========================================================================= */
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 #if USE_WIN32_THREADS
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 /* -------------------------- gl_thread_t datatype -------------------------- */
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
36 /* The Thread-Local Storage (TLS) key that allows to access each thread's
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
37 'struct gl_thread_struct *' pointer. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
38 static DWORD self_key = (DWORD)-1;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
39
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
40 /* Initializes self_key. This function must only be called once. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
41 static void
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
42 do_init_self_key (void)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
43 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
44 self_key = TlsAlloc ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
45 /* If this fails, we're hosed. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
46 if (self_key == (DWORD)-1)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
47 abort ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
48 }
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
49
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
50 /* Initializes self_key. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
51 static void
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
52 init_self_key (void)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
53 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
54 gl_once_define(static, once)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
55 gl_once (once, do_init_self_key);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
56 }
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
57
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
58 /* This structure contains information about a thread.
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
59 It is stored in TLS under key self_key. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
60 struct gl_thread_struct
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
61 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
62 /* Fields for managing the handle. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
63 HANDLE volatile handle;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
64 CRITICAL_SECTION handle_lock;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
65 /* Fields for managing the exit value. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
66 void * volatile result;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
67 /* Fields for managing the thread start. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
68 void * (*func) (void *);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
69 void *arg;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
70 };
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
71
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
72 /* Return a real HANDLE object for the current thread. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
73 static inline HANDLE
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
74 get_current_thread_handle (void)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
75 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
76 HANDLE this_handle;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
78 /* GetCurrentThread() returns a pseudo-handle, i.e. only a symbolic
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
79 identifier, not a real handle. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
80 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
81 GetCurrentProcess (), &this_handle,
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
82 0, FALSE, DUPLICATE_SAME_ACCESS))
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
83 abort ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
84 return this_handle;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
85 }
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
86
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
87 gl_thread_t
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
88 gl_thread_self_func (void)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
89 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
90 gl_thread_t thread;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
92 if (self_key == (DWORD)-1)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
93 init_self_key ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
94 thread = TlsGetValue (self_key);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
95 if (thread == NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
96 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
97 /* This happens only in threads that have not been created through
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
98 glthread_create(), such as the main thread. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
99 for (;;)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
100 {
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
101 thread =
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
102 (struct gl_thread_struct *)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
103 malloc (sizeof (struct gl_thread_struct));
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
104 if (thread != NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
105 break;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
106 /* Memory allocation failed. There is not much we can do. Have to
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
107 busy-loop, waiting for the availability of memory. */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
108 Sleep (1);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
109 }
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
111 thread->handle = get_current_thread_handle ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
112 InitializeCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
113 thread->result = NULL; /* just to be deterministic */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
114 TlsSetValue (self_key, thread);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
115 }
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
116 return thread;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
117 }
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
118
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
119 /* The main function of a freshly creating thread. It's a wrapper around
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
120 the FUNC and ARG arguments passed to glthread_create_func. */
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 static DWORD WINAPI
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 wrapper_func (void *varg)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 {
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
124 struct gl_thread_struct *thread = (struct gl_thread_struct *)varg;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
126 EnterCriticalSection (&thread->handle_lock);
30026
031c5ec89598 Avoid forcing a context switch right after thread creation.
Bruno Haible <bruno@clisp.org>
parents: 30024
diff changeset
127 /* Create a new handle for the thread only if the parent thread did not yet
031c5ec89598 Avoid forcing a context switch right after thread creation.
Bruno Haible <bruno@clisp.org>
parents: 30024
diff changeset
128 fill in the handle. */
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
129 if (thread->handle == NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
130 thread->handle = get_current_thread_handle ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
131 LeaveCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
132
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
133 if (self_key == (DWORD)-1)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
134 init_self_key ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
135 TlsSetValue (self_key, thread);
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 /* Run the thread. Store the exit value if the thread was not terminated
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 otherwise. */
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
139 thread->result = thread->func (thread->arg);
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 return 0;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 }
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 int
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 glthread_create_func (gl_thread_t *threadp, void * (*func) (void *), void *arg)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 {
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
146 struct gl_thread_struct *thread =
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
147 (struct gl_thread_struct *) malloc (sizeof (struct gl_thread_struct));
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
148 if (thread == NULL)
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149 return ENOMEM;
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
150 thread->handle = NULL;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
151 InitializeCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
152 thread->result = NULL; /* just to be deterministic */
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
153 thread->func = func;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
154 thread->arg = arg;
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
155
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 {
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 DWORD thread_id;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158 HANDLE thread_handle;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
160 thread_handle =
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
161 CreateThread (NULL, 100000, wrapper_func, thread, 0, &thread_id);
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 if (thread_handle == NULL)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 {
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
164 DeleteCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
165 free (thread);
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166 return EAGAIN;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 }
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
168
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
169 EnterCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
170 if (thread->handle == NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
171 thread->handle = thread_handle;
30026
031c5ec89598 Avoid forcing a context switch right after thread creation.
Bruno Haible <bruno@clisp.org>
parents: 30024
diff changeset
172 else
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
173 /* thread->handle was already set by the thread itself. */
30026
031c5ec89598 Avoid forcing a context switch right after thread creation.
Bruno Haible <bruno@clisp.org>
parents: 30024
diff changeset
174 CloseHandle (thread_handle);
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
175 LeaveCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
176
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
177 *threadp = thread;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
178 return 0;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179 }
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180 }
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
182 int
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
183 glthread_join_func (gl_thread_t thread, void **retvalp)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
184 {
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
185 if (thread == NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
186 return EINVAL;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 if (thread == gl_thread_self ())
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 return EDEADLK;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
191 if (WaitForSingleObject (thread->handle, INFINITE) == WAIT_FAILED)
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
192 return EINVAL;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
193
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
194 if (retvalp != NULL)
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
195 *retvalp = thread->result;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
196
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
197 DeleteCriticalSection (&thread->handle_lock);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
198 CloseHandle (thread->handle);
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
199 free (thread);
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 return 0;
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202 }
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204 int
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 gl_thread_exit_func (void *retval)
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 {
30245
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
207 gl_thread_t thread = gl_thread_self ();
df7871e79216 Fix the Win32 implementation of the 'thread' module.
Bruno Haible <bruno@clisp.org>
parents: 30026
diff changeset
208 thread->result = retval;
30024
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 ExitThread (0);
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 }
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 #endif
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
213
4f084a93186e Implement thread control primitives for Win32.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 /* ========================================================================= */