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 8long 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 */ 18static void PyThread__init_thread(void) 19{ 20} 21 22/* 23 * Thread support. 24 */ 25long 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 */ 48long PyThread_get_thread_ident(void) 49{ 50 if (!initialized) 51 PyThread_init_thread(); 52 53 return GetCurrentThreadId(); 54} 55 56void 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 */ 69PyThread_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 87void 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 */ 100int 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 128void 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