thr_nt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* thr_nt.c - wrapper around NT threads */
  2. /* $OpenLDAP$ */
  3. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  4. *
  5. * Copyright 1998-2024 The OpenLDAP Foundation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. #include "portable.h"
  17. #if defined( HAVE_NT_THREADS )
  18. #define _WIN32_WINNT 0x0400
  19. #include <windows.h>
  20. #include <process.h>
  21. #include "ldap_pvt_thread.h" /* Get the thread interface */
  22. #define LDAP_THREAD_IMPLEMENTATION
  23. #include "ldap_thr_debug.h" /* May rename the symbols defined below */
  24. typedef struct ldap_int_thread_s {
  25. long tid;
  26. HANDLE thd;
  27. } ldap_int_thread_s;
  28. #ifndef NT_MAX_THREADS
  29. #define NT_MAX_THREADS 1024
  30. #endif
  31. static ldap_int_thread_s tids[NT_MAX_THREADS];
  32. static int ntids;
  33. /* mingw compiler very sensitive about getting prototypes right */
  34. typedef unsigned __stdcall thrfunc_t(void *);
  35. int
  36. ldap_int_thread_initialize( void )
  37. {
  38. return 0;
  39. }
  40. int
  41. ldap_int_thread_destroy( void )
  42. {
  43. return 0;
  44. }
  45. int
  46. ldap_int_mutex_firstcreate( ldap_int_thread_mutex_t *mutex )
  47. {
  48. if ( *mutex == NULL ) {
  49. HANDLE p = CreateMutex( NULL, 0, NULL );
  50. if ( InterlockedCompareExchangePointer((PVOID*)mutex, (PVOID)p, NULL) != NULL)
  51. CloseHandle( p );
  52. }
  53. return 0;
  54. }
  55. int
  56. ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
  57. int detach,
  58. void *(*start_routine)( void *),
  59. void *arg)
  60. {
  61. unsigned tid;
  62. HANDLE thd;
  63. int rc = -1;
  64. thd = (HANDLE) _beginthreadex(NULL, LDAP_PVT_THREAD_STACK_SIZE, (thrfunc_t *) start_routine,
  65. arg, 0, &tid);
  66. if ( thd ) {
  67. *thread = (ldap_pvt_thread_t) tid;
  68. tids[ntids].tid = tid;
  69. tids[ntids].thd = thd;
  70. ntids++;
  71. rc = 0;
  72. }
  73. return rc;
  74. }
  75. void
  76. ldap_pvt_thread_exit( void *retval )
  77. {
  78. _endthread( );
  79. }
  80. int
  81. ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
  82. {
  83. DWORD status;
  84. int i;
  85. for (i=0; i<ntids; i++) {
  86. if ( tids[i].tid == thread )
  87. break;
  88. }
  89. if ( i > ntids ) return -1;
  90. status = WaitForSingleObject( tids[i].thd, INFINITE );
  91. for (; i<ntids; i++) {
  92. tids[i] = tids[i+1];
  93. }
  94. ntids--;
  95. return status == WAIT_FAILED ? -1 : 0;
  96. }
  97. int
  98. ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
  99. {
  100. return 0;
  101. }
  102. int
  103. ldap_pvt_thread_yield( void )
  104. {
  105. Sleep( 0 );
  106. return 0;
  107. }
  108. int
  109. ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
  110. {
  111. *cond = CreateEvent( NULL, FALSE, FALSE, NULL );
  112. return( 0 );
  113. }
  114. int
  115. ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
  116. {
  117. CloseHandle( *cv );
  118. return( 0 );
  119. }
  120. int
  121. ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
  122. {
  123. SetEvent( *cond );
  124. return( 0 );
  125. }
  126. int
  127. ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
  128. ldap_pvt_thread_mutex_t *mutex )
  129. {
  130. SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE );
  131. WaitForSingleObject( *mutex, INFINITE );
  132. return( 0 );
  133. }
  134. int
  135. ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
  136. {
  137. while ( WaitForSingleObject( *cond, 0 ) == WAIT_TIMEOUT )
  138. SetEvent( *cond );
  139. return( 0 );
  140. }
  141. int
  142. ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
  143. {
  144. *mutex = CreateMutex( NULL, 0, NULL );
  145. return ( 0 );
  146. }
  147. int
  148. ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_t *mutex )
  149. {
  150. /* All NT mutexes are recursive */
  151. return ldap_pvt_thread_mutex_init( mutex );
  152. }
  153. int
  154. ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
  155. {
  156. CloseHandle( *mutex );
  157. return ( 0 );
  158. }
  159. int
  160. ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
  161. {
  162. DWORD status;
  163. status = WaitForSingleObject( *mutex, INFINITE );
  164. return status == WAIT_FAILED ? -1 : 0;
  165. }
  166. int
  167. ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
  168. {
  169. ReleaseMutex( *mutex );
  170. return ( 0 );
  171. }
  172. int
  173. ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
  174. {
  175. DWORD status;
  176. status = WaitForSingleObject( *mp, 0 );
  177. return status == WAIT_FAILED || status == WAIT_TIMEOUT
  178. ? -1 : 0;
  179. }
  180. ldap_pvt_thread_t
  181. ldap_pvt_thread_self( void )
  182. {
  183. return GetCurrentThreadId();
  184. }
  185. int
  186. ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *keyp )
  187. {
  188. DWORD key = TlsAlloc();
  189. if ( key != TLS_OUT_OF_INDEXES ) {
  190. *keyp = key;
  191. return 0;
  192. } else {
  193. return -1;
  194. }
  195. }
  196. int
  197. ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
  198. {
  199. /* TlsFree returns 0 on failure */
  200. return( TlsFree( key ) == 0 );
  201. }
  202. int
  203. ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
  204. {
  205. return ( TlsSetValue( key, data ) == 0 );
  206. }
  207. int
  208. ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
  209. {
  210. void *ptr = TlsGetValue( key );
  211. *data = ptr;
  212. return( ptr ? GetLastError() : 0 );
  213. }
  214. #endif