• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* This code implemented by Mark Hammond (MHammond@skippinet.com.au) */
3 
4 #include <windows.h>
5 #include <limits.h>
6 #include <pydebug.h>
7 
8 long PyThread_get_thread_ident(void);
9 
10 /*
11  * Change all headers to pure ANSI as no one will use K&R style on an
12  * NT
13  */
14 
15 /*
16  * Initialization of the C package, should not be needed.
17  */
PyThread__init_thread(void)18 static void PyThread__init_thread(void)
19 {
20 }
21 
22 /*
23  * Thread support.
24  */
PyThread_start_new_thread(void (* func)(void *),void * arg)25 long PyThread_start_new_thread(void (*func)(void *), void *arg)
26 {
27     long rv;
28     int success = -1;
29 
30     dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
31     if (!initialized)
32         PyThread_init_thread();
33 
34     rv = _beginthread(func, 0, arg); /* use default stack size */
35 
36     if (rv != -1) {
37         success = 0;
38         dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
39     }
40 
41     return success;
42 }
43 
44 /*
45  * Return the thread Id instead of a handle. The Id is said to uniquely identify the
46  * thread in the system
47  */
PyThread_get_thread_ident(void)48 long PyThread_get_thread_ident(void)
49 {
50     if (!initialized)
51         PyThread_init_thread();
52 
53     return GetCurrentThreadId();
54 }
55 
PyThread_exit_thread(void)56 void PyThread_exit_thread(void)
57 {
58     dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
59     if (!initialized)
60         exit(0);
61     _endthread();
62 }
63 
64 /*
65  * Lock support. It has to be implemented using Mutexes, as
66  * CE doesnt support semaphores.  Therefore we use some hacks to
67  * simulate the non reentrant requirements of Python locks
68  */
PyThread_allocate_lock(void)69 PyThread_type_lock PyThread_allocate_lock(void)
70 {
71     HANDLE aLock;
72 
73     dprintf(("PyThread_allocate_lock called\n"));
74     if (!initialized)
75         PyThread_init_thread();
76 
77     aLock = CreateEvent(NULL,           /* Security attributes      */
78                         0,              /* Manual-Reset               */
79                         1,              /* Is initially signalled  */
80                         NULL);          /* Name of event            */
81 
82     dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
83 
84     return (PyThread_type_lock) aLock;
85 }
86 
PyThread_free_lock(PyThread_type_lock aLock)87 void PyThread_free_lock(PyThread_type_lock aLock)
88 {
89     dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
90 
91     CloseHandle(aLock);
92 }
93 
94 /*
95  * Return 1 on success if the lock was acquired
96  *
97  * and 0 if the lock was not acquired. This means a 0 is returned
98  * if the lock has already been acquired by this thread!
99  */
PyThread_acquire_lock(PyThread_type_lock aLock,int waitflag)100 int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
101 {
102     int success = 1;
103     DWORD waitResult;
104 
105     dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
106 
107 #ifndef DEBUG
108     waitResult = WaitForSingleObject(aLock, (waitflag ? INFINITE : 0));
109 #else
110     /* To aid in debugging, we regularly wake up.  This allows us to
111     break into the debugger */
112     while (TRUE) {
113         waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
114         if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0))
115             break;
116     }
117 #endif
118 
119     if (waitResult != WAIT_OBJECT_0) {
120         success = 0;    /* We failed */
121     }
122 
123     dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
124 
125     return success;
126 }
127 
PyThread_release_lock(PyThread_type_lock aLock)128 void PyThread_release_lock(PyThread_type_lock aLock)
129 {
130     dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
131 
132     if (!SetEvent(aLock))
133         dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
134 }
135 
136 
137