You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.5 KiB

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