blob: d65569c0d41b1eb74a46fcaea5dafacbfc9cc60d [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
34#include "windows.h"
35#include "limits.h"
36
37long get_thread_ident(void);
38
39/*
40 * Change all headers to pure ANSI as no one will use K&R style on an
41 * NT
42 */
43
44/*
45 * Initialization of the C package, should not be needed.
46 */
47static void _init_thread(void)
48{
49}
50
51/*
52 * Thread support.
53 */
54int start_new_thread(void (*func)(void *), void *arg)
55{
56 HANDLE aThread;
57 DWORD aThreadId;
58
59 int success = 0; /* init not needed when SOLARIS_THREADS and */
60 /* C_THREADS implemented properly */
61 dprintf(("%ld: start_new_thread called\n", get_thread_ident()));
62 if (!initialized)
63 init_thread();
64
65 aThread = CreateThread(
66 NULL, /* No security attributes */
67 0, /* use default stack size */
68 (LPTHREAD_START_ROUTINE) func, /* thread function */
69 (LPVOID) arg, /* argument to thread function */
70 0, /* use the default creation flags */
71 &aThreadId); /* returns the thread identifier */
72
73 if (aThread != NULL) {
74 CloseHandle(aThread); /* We do not want to have any zombies hanging around */
75 success = 1;
76 dprintf(("%ld: start_new_thread succeeded: %ld\n", get_thread_ident(), aThreadId));
77 }
78
79 return success;
80}
81
82/*
83 * Return the thread Id instead of an handle. The Id is said to uniquely identify the
84 * thread in the system
85 */
86long get_thread_ident(void)
87{
88 if (!initialized)
89 init_thread();
90
91 return GetCurrentThreadId();
92}
93
94static void do_exit_thread(int no_cleanup)
95{
96 dprintf(("%ld: exit_thread called\n", get_thread_ident()));
97 if (!initialized)
98 if (no_cleanup)
99 _exit(0);
100 else
101 exit(0);
102 ExitThread(0);
103}
104
105void exit_thread(void)
106{
107 do_exit_thread(0);
108}
109
110void _exit_thread(void)
111{
112 do_exit_thread(1);
113}
114
115#ifndef NO_EXIT_PROG
116static void do_exit_prog(int status, int no_cleanup)
117{
118 dprintf(("exit_prog(%d) called\n", status));
119 if (!initialized)
120 if (no_cleanup)
121 _exit(status);
122 else
123 exit(status);
124}
125
126void exit_prog(int status)
127{
128 do_exit_prog(status, 0);
129}
130
131void _exit_prog _P1(int status)
132{
133 do_exit_prog(status, 1);
134}
135#endif /* NO_EXIT_PROG */
136
137/*
138 * Lock support. It has too be implemented as semaphores.
139 * I [Dag] tried to implement it with mutex but I could find a way to
140 * tell whether a thread already own the lock or not.
141 */
142type_lock allocate_lock(void)
143{
144 HANDLE aLock;
145
146 dprintf(("allocate_lock called\n"));
147 if (!initialized)
148 init_thread();
149
150 aLock = CreateSemaphore(NULL, /* Security attributes */
151 1, /* Initial value */
152 1, /* Maximum value */
153 NULL);
154 /* Name of semaphore */
155
156 dprintf(("%ld: allocate_lock() -> %lx\n", get_thread_ident(), (long)aLock));
157
158 return (type_lock) aLock;
159}
160
161void free_lock(type_lock aLock)
162{
163 dprintf(("%ld: free_lock(%lx) called\n", get_thread_ident(),(long)aLock));
164
165 CloseHandle((HANDLE) aLock);
166}
167
168/*
169 * Return 1 on success if the lock was acquired
170 *
171 * and 0 if the lock was not acquired. This means a 0 is returned
172 * if the lock has already been acquired by this thread!
173 */
174int acquire_lock(type_lock aLock, int waitflag)
175{
176 int success = 1;
177 DWORD waitResult;
178
179 dprintf(("%ld: acquire_lock(%lx, %d) called\n", get_thread_ident(),(long)aLock, waitflag));
180
181 waitResult = WaitForSingleObject((HANDLE) aLock, (waitflag == 1 ? INFINITE : 0));
182
183 if (waitResult != WAIT_OBJECT_0) {
184 success = 0; /* We failed */
185 }
186
187 dprintf(("%ld: acquire_lock(%lx, %d) -> %d\n", get_thread_ident(),(long)aLock, waitflag, success));
188
189 return success;
190}
191
192void release_lock(type_lock aLock)
193{
194 dprintf(("%ld: release_lock(%lx) called\n", get_thread_ident(),(long)aLock));
195
196 if (!ReleaseSemaphore(
197 (HANDLE) aLock, /* Handle of semaphore */
198 1, /* increment count by one */
199 NULL)) /* not interested in previous count */
200 {
201 dprintf(("%ld: Could not release_lock(%lx) error: %l\n", get_thread_ident(), (long)aLock, GetLastError()));
202 }
203}
204
205/*
206 * Semaphore support.
207 */
208type_sema allocate_sema(int value)
209{
210 HANDLE aSemaphore;
211
212 dprintf(("%ld: allocate_sema called\n", get_thread_ident()));
213 if (!initialized)
214 init_thread();
215
216 aSemaphore = CreateSemaphore( NULL, /* Security attributes */
217 value, /* Initial value */
218 INT_MAX, /* Maximum value */
219 NULL); /* Name of semaphore */
220
221 dprintf(("%ld: allocate_sema() -> %lx\n", get_thread_ident(), (long)aSemaphore));
222
223 return (type_sema) aSemaphore;
224}
225
226void free_sema(type_sema aSemaphore)
227{
228 dprintf(("%ld: free_sema(%lx) called\n", get_thread_ident(), (long)aSemaphore));
229
230 CloseHandle((HANDLE) aSemaphore);
231}
232
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000233/*
234 XXX must do something about waitflag
235 */
236int down_sema(type_sema aSemaphore, int waitflag)
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000237{
238 DWORD waitResult;
239
240 dprintf(("%ld: down_sema(%lx) called\n", get_thread_ident(), (long)aSemaphore));
241
242 waitResult = WaitForSingleObject( (HANDLE) aSemaphore, INFINITE);
243
244 dprintf(("%ld: down_sema(%lx) return: %l\n", get_thread_ident(),(long) aSemaphore, waitResult));
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000245 return 0;
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000246}
247
248void up_sema(type_sema aSemaphore)
249{
250 ReleaseSemaphore(
251 (HANDLE) aSemaphore, /* Handle of semaphore */
252 1, /* increment count by one */
253 NULL); /* not interested in previous count */
254
255 dprintf(("%ld: up_sema(%lx)\n", get_thread_ident(), (long)aSemaphore));
256}