blob: 0044551c900a7e46c1ccd149442519a8e82230c8 [file] [log] [blame]
Guido van Rossumc3f82b61995-01-17 16:29:31 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumc3f82b61995-01-17 16:29:31 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumc3f82b61995-01-17 16:29:31 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumc3f82b61995-01-17 16:29:31 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumc3f82b61995-01-17 16:29:31 +000029
30******************************************************************/
31
32/* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */
33
Guido van Rossum49b12261997-08-14 20:12:58 +000034#include <windows.h>
35#include <limits.h>
36#include <process.h>
Guido van Rossumc3f82b61995-01-17 16:29:31 +000037
Guido van Rossum65d5b571998-12-21 19:32:43 +000038long PyThread_get_thread_ident(void);
Guido van Rossumc3f82b61995-01-17 16:29:31 +000039
40/*
41 * Change all headers to pure ANSI as no one will use K&R style on an
42 * NT
43 */
44
45/*
46 * Initialization of the C package, should not be needed.
47 */
Guido van Rossum65d5b571998-12-21 19:32:43 +000048static void PyThread__init_thread(void)
Guido van Rossumc3f82b61995-01-17 16:29:31 +000049{
50}
51
52/*
53 * Thread support.
54 */
Guido van Rossum65d5b571998-12-21 19:32:43 +000055int PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossumc3f82b61995-01-17 16:29:31 +000056{
Guido van Rossum49b12261997-08-14 20:12:58 +000057 long rv;
58 int success = 0;
Guido van Rossumc3f82b61995-01-17 16:29:31 +000059
Guido van Rossum65d5b571998-12-21 19:32:43 +000060 dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
Guido van Rossumc3f82b61995-01-17 16:29:31 +000061 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000062 PyThread_init_thread();
Guido van Rossumc3f82b61995-01-17 16:29:31 +000063
Guido van Rossum49b12261997-08-14 20:12:58 +000064 rv = _beginthread(func, 0, arg); /* use default stack size */
Guido van Rossumc3f82b61995-01-17 16:29:31 +000065
Guido van Rossum49b12261997-08-14 20:12:58 +000066 if (rv != -1) {
Guido van Rossumc3f82b61995-01-17 16:29:31 +000067 success = 1;
Guido van Rossum65d5b571998-12-21 19:32:43 +000068 dprintf(("%ld: PyThread_start_new_thread succeeded: %ld\n", PyThread_get_thread_ident(), aThreadId));
Guido van Rossumc3f82b61995-01-17 16:29:31 +000069 }
70
71 return success;
72}
73
74/*
75 * Return the thread Id instead of an handle. The Id is said to uniquely identify the
76 * thread in the system
77 */
Guido van Rossum65d5b571998-12-21 19:32:43 +000078long PyThread_get_thread_ident(void)
Guido van Rossumc3f82b61995-01-17 16:29:31 +000079{
80 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +000081 PyThread_init_thread();
Guido van Rossumc3f82b61995-01-17 16:29:31 +000082
83 return GetCurrentThreadId();
84}
85
Guido van Rossum65d5b571998-12-21 19:32:43 +000086static void do_PyThread_exit_thread(int no_cleanup)
Guido van Rossumc3f82b61995-01-17 16:29:31 +000087{
Guido van Rossum65d5b571998-12-21 19:32:43 +000088 dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
Guido van Rossumc3f82b61995-01-17 16:29:31 +000089 if (!initialized)
90 if (no_cleanup)
91 _exit(0);
92 else
93 exit(0);
Guido van Rossum49b12261997-08-14 20:12:58 +000094 _endthread();
Guido van Rossumc3f82b61995-01-17 16:29:31 +000095}
96
Guido van Rossum65d5b571998-12-21 19:32:43 +000097void PyThread_exit_thread(void)
Guido van Rossumc3f82b61995-01-17 16:29:31 +000098{
Guido van Rossum65d5b571998-12-21 19:32:43 +000099 do_PyThread_exit_thread(0);
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000100}
101
Guido van Rossum65d5b571998-12-21 19:32:43 +0000102void PyThread__exit_thread(void)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000103{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000104 do_PyThread_exit_thread(1);
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000105}
106
107#ifndef NO_EXIT_PROG
Guido van Rossum65d5b571998-12-21 19:32:43 +0000108static void do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000109{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000110 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000111 if (!initialized)
112 if (no_cleanup)
113 _exit(status);
114 else
115 exit(status);
116}
117
Guido van Rossum65d5b571998-12-21 19:32:43 +0000118void PyThread_exit_prog(int status)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000119{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000120 do_PyThread_exit_prog(status, 0);
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000121}
122
Guido van Rossum65d5b571998-12-21 19:32:43 +0000123void PyThread__exit_prog _P1(int status)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000124{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000125 do_PyThread_exit_prog(status, 1);
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000126}
127#endif /* NO_EXIT_PROG */
128
129/*
130 * Lock support. It has too be implemented as semaphores.
131 * I [Dag] tried to implement it with mutex but I could find a way to
132 * tell whether a thread already own the lock or not.
133 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000134PyThread_type_lock PyThread_allocate_lock(void)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000135{
136 HANDLE aLock;
137
Guido van Rossum65d5b571998-12-21 19:32:43 +0000138 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000139 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000140 PyThread_init_thread();
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000141
142 aLock = CreateSemaphore(NULL, /* Security attributes */
143 1, /* Initial value */
144 1, /* Maximum value */
145 NULL);
146 /* Name of semaphore */
147
Guido van Rossum65d5b571998-12-21 19:32:43 +0000148 dprintf(("%ld: PyThread_allocate_lock() -> %lx\n", PyThread_get_thread_ident(), (long)aLock));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000149
Guido van Rossum65d5b571998-12-21 19:32:43 +0000150 return (PyThread_type_lock) aLock;
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000151}
152
Guido van Rossum65d5b571998-12-21 19:32:43 +0000153void PyThread_free_lock(PyThread_type_lock aLock)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000154{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 dprintf(("%ld: PyThread_free_lock(%lx) called\n", PyThread_get_thread_ident(),(long)aLock));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000156
157 CloseHandle((HANDLE) aLock);
158}
159
160/*
161 * Return 1 on success if the lock was acquired
162 *
163 * and 0 if the lock was not acquired. This means a 0 is returned
164 * if the lock has already been acquired by this thread!
165 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000166int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000167{
168 int success = 1;
169 DWORD waitResult;
170
Guido van Rossum65d5b571998-12-21 19:32:43 +0000171 dprintf(("%ld: PyThread_acquire_lock(%lx, %d) called\n", PyThread_get_thread_ident(),(long)aLock, waitflag));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000172
173 waitResult = WaitForSingleObject((HANDLE) aLock, (waitflag == 1 ? INFINITE : 0));
174
175 if (waitResult != WAIT_OBJECT_0) {
176 success = 0; /* We failed */
177 }
178
Guido van Rossum65d5b571998-12-21 19:32:43 +0000179 dprintf(("%ld: PyThread_acquire_lock(%lx, %d) -> %d\n", PyThread_get_thread_ident(),(long)aLock, waitflag, success));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000180
181 return success;
182}
183
Guido van Rossum65d5b571998-12-21 19:32:43 +0000184void PyThread_release_lock(PyThread_type_lock aLock)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000185{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000186 dprintf(("%ld: PyThread_release_lock(%lx) called\n", PyThread_get_thread_ident(),(long)aLock));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000187
188 if (!ReleaseSemaphore(
189 (HANDLE) aLock, /* Handle of semaphore */
190 1, /* increment count by one */
191 NULL)) /* not interested in previous count */
192 {
Guido van Rossum65d5b571998-12-21 19:32:43 +0000193 dprintf(("%ld: Could not PyThread_release_lock(%lx) error: %l\n", PyThread_get_thread_ident(), (long)aLock, GetLastError()));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000194 }
195}
196
197/*
198 * Semaphore support.
199 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000200PyThread_type_sema PyThread_allocate_sema(int value)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000201{
202 HANDLE aSemaphore;
203
Guido van Rossum65d5b571998-12-21 19:32:43 +0000204 dprintf(("%ld: PyThread_allocate_sema called\n", PyThread_get_thread_ident()));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000205 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000206 PyThread_init_thread();
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000207
208 aSemaphore = CreateSemaphore( NULL, /* Security attributes */
209 value, /* Initial value */
210 INT_MAX, /* Maximum value */
211 NULL); /* Name of semaphore */
212
Guido van Rossum65d5b571998-12-21 19:32:43 +0000213 dprintf(("%ld: PyThread_allocate_sema() -> %lx\n", PyThread_get_thread_ident(), (long)aSemaphore));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000214
Guido van Rossum65d5b571998-12-21 19:32:43 +0000215 return (PyThread_type_sema) aSemaphore;
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000216}
217
Guido van Rossum65d5b571998-12-21 19:32:43 +0000218void PyThread_free_sema(PyThread_type_sema aSemaphore)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000219{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000220 dprintf(("%ld: PyThread_free_sema(%lx) called\n", PyThread_get_thread_ident(), (long)aSemaphore));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000221
222 CloseHandle((HANDLE) aSemaphore);
223}
224
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000225/*
226 XXX must do something about waitflag
227 */
Guido van Rossum65d5b571998-12-21 19:32:43 +0000228int PyThread_down_sema(PyThread_type_sema aSemaphore, int waitflag)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000229{
230 DWORD waitResult;
231
Guido van Rossum65d5b571998-12-21 19:32:43 +0000232 dprintf(("%ld: PyThread_down_sema(%lx) called\n", PyThread_get_thread_ident(), (long)aSemaphore));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000233
234 waitResult = WaitForSingleObject( (HANDLE) aSemaphore, INFINITE);
235
Guido van Rossum65d5b571998-12-21 19:32:43 +0000236 dprintf(("%ld: PyThread_down_sema(%lx) return: %l\n", PyThread_get_thread_ident(),(long) aSemaphore, waitResult));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000237 return 0;
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000238}
239
Guido van Rossum65d5b571998-12-21 19:32:43 +0000240void PyThread_up_sema(PyThread_type_sema aSemaphore)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000241{
242 ReleaseSemaphore(
243 (HANDLE) aSemaphore, /* Handle of semaphore */
244 1, /* increment count by one */
245 NULL); /* not interested in previous count */
246
Guido van Rossum65d5b571998-12-21 19:32:43 +0000247 dprintf(("%ld: PyThread_up_sema(%lx)\n", PyThread_get_thread_ident(), (long)aSemaphore));
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000248}