Mercurial > gnulib
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 |
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 /* ========================================================================= */ |