blob: a5423f6de4e708466e71e4c307977878fcc04e4a [file] [log] [blame]
Guido van Rossumb738d261999-04-08 13:57:06 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumb738d261999-04-08 13:57:06 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumb738d261999-04-08 13:57:06 +00009******************************************************************/
10
11/* This code implemented by Mark Hammond (MHammond@skippinet.com.au) */
12
13#include <windows.h>
14#include <limits.h>
15#include <pydebug.h>
16
17long PyThread_get_thread_ident(void);
18
19/*
20 * Change all headers to pure ANSI as no one will use K&R style on an
21 * NT
22 */
23
24/*
25 * Initialization of the C package, should not be needed.
26 */
27static void PyThread__init_thread(void)
28{
29}
30
31/*
32 * Thread support.
33 */
34int PyThread_start_new_thread(void (*func)(void *), void *arg)
35{
36 long rv;
37 int success = 0;
38
39 dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
40 if (!initialized)
41 PyThread_init_thread();
42
43 rv = _beginthread(func, 0, arg); /* use default stack size */
44
45 if (rv != -1) {
46 success = 1;
47 dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
48 }
49
50 return success;
51}
52
53/*
54 * Return the thread Id instead of an handle. The Id is said to uniquely identify the
55 * thread in the system
56 */
57long PyThread_get_thread_ident(void)
58{
59 if (!initialized)
60 PyThread_init_thread();
61
62 return GetCurrentThreadId();
63}
64
65static void do_PyThread_exit_thread(int no_cleanup)
66{
67 dprintf(("%ld: do_PyThread_exit_thread called\n", PyThread_get_thread_ident()));
68 if (!initialized)
69 if (no_cleanup)
70 exit(0); /* XXX - was _exit()!! */
71 else
72 exit(0);
73 _endthread();
74}
75
76void PyThread_exit_thread(void)
77{
78 do_PyThread_exit_thread(0);
79}
80
81void PyThread__exit_thread(void)
82{
83 do_PyThread_exit_thread(1);
84}
85
86#ifndef NO_EXIT_PROG
87static void do_PyThread_exit_prog(int status, int no_cleanup)
88{
89 dprintf(("PyThread_exit_prog(%d) called\n", status));
90 if (!initialized)
91 if (no_cleanup)
92 _exit(status);
93 else
94 exit(status);
95}
96
97void PyThread_exit_prog(int status)
98{
99 do_PyThread_exit_prog(status, 0);
100}
101
102void PyThread__exit_prog _P1(int status)
103{
104 do_PyThread_exit_prog(status, 1);
105}
106#endif /* NO_EXIT_PROG */
107
108/*
109 * Lock support. It has to be implemented using Mutexes, as
110 * CE doesnt support semaphores. Therefore we use some hacks to
111 * simulate the non reentrant requirements of Python locks
112 */
113PyThread_type_lock PyThread_allocate_lock(void)
114{
115 HANDLE aLock;
116
117 dprintf(("PyThread_allocate_lock called\n"));
118 if (!initialized)
119 PyThread_init_thread();
120
121 aLock = CreateEvent(NULL, /* Security attributes */
122 0, /* Manual-Reset */
123 1, /* Is initially signalled */
124 NULL); /* Name of event */
125
Fred Drakea44d3532000-06-30 15:01:00 +0000126 dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
Guido van Rossumb738d261999-04-08 13:57:06 +0000127
128 return (PyThread_type_lock) aLock;
129}
130
131void PyThread_free_lock(PyThread_type_lock aLock)
132{
Fred Drakea44d3532000-06-30 15:01:00 +0000133 dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
Guido van Rossumb738d261999-04-08 13:57:06 +0000134
135 CloseHandle(aLock);
136}
137
138/*
139 * Return 1 on success if the lock was acquired
140 *
141 * and 0 if the lock was not acquired. This means a 0 is returned
142 * if the lock has already been acquired by this thread!
143 */
144int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
145{
146 int success = 1;
147 DWORD waitResult;
148
Fred Drakea44d3532000-06-30 15:01:00 +0000149 dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
Guido van Rossumb738d261999-04-08 13:57:06 +0000150
151#ifndef DEBUG
152 waitResult = WaitForSingleObject(aLock, (waitflag == 1 ? INFINITE : 0));
153#else
154 /* To aid in debugging, we regularly wake up. This allows us to
155 break into the debugger */
156 while (TRUE) {
157 waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
158 if (waitflag==0 || (waitflag==1 && waitResult == WAIT_OBJECT_0))
159 break;
160 }
161#endif
162
163 if (waitResult != WAIT_OBJECT_0) {
164 success = 0; /* We failed */
165 }
166
Fred Drakea44d3532000-06-30 15:01:00 +0000167 dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
Guido van Rossumb738d261999-04-08 13:57:06 +0000168
169 return success;
170}
171
172void PyThread_release_lock(PyThread_type_lock aLock)
173{
Fred Drakea44d3532000-06-30 15:01:00 +0000174 dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
Guido van Rossumb738d261999-04-08 13:57:06 +0000175
176 if (!SetEvent(aLock))
Fred Drakea44d3532000-06-30 15:01:00 +0000177 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
Guido van Rossumb738d261999-04-08 13:57:06 +0000178}
179
180