]> git.sur5r.net Git - openldap/blob - libraries/libldap_r/thr_nt.c
Happy new year!
[openldap] / libraries / libldap_r / thr_nt.c
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-2006 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
17 #include "portable.h"
18
19 #if defined( HAVE_NT_THREADS )
20
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
25 typedef struct ldap_int_thread_s {
26         long tid;
27         HANDLE thd;
28 } ldap_int_thread_s;
29
30 #ifndef NT_MAX_THREADS
31 #define NT_MAX_THREADS  1024
32 #endif
33
34 static ldap_int_thread_s tids[NT_MAX_THREADS];
35 static int ntids;
36
37
38 /* mingw compiler very sensitive about getting prototypes right */
39 typedef unsigned __stdcall thrfunc_t(void *);
40
41 int
42 ldap_int_thread_initialize( void )
43 {
44         return 0;
45 }
46
47 int
48 ldap_int_thread_destroy( void )
49 {
50         return 0;
51 }
52
53 int 
54 ldap_pvt_thread_create( ldap_pvt_thread_t * thread, 
55         int detach,
56         void *(*start_routine)( void *),
57         void *arg)
58 {
59         unsigned tid;
60         HANDLE thd;
61         int rc = -1;
62
63         thd = (HANDLE) _beginthreadex(NULL, LDAP_PVT_THREAD_STACK_SIZE, (thrfunc_t *) start_routine,
64                                       arg, 0, &tid);
65
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         
76 void 
77 ldap_pvt_thread_exit( void *retval )
78 {
79         _endthread( );
80 }
81
82 int 
83 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
84 {
85         DWORD status;
86         int i;
87
88         for (i=0; i<ntids; i++) {
89                 if ( tids[i].tid == thread )
90                         break;
91         }
92         if ( i > ntids ) return -1;
93
94         status = WaitForSingleObject( tids[i].thd, INFINITE );
95         for (; i<ntids; i++) {
96                 tids[i] = tids[i+1];
97         }
98         ntids--;
99         return status == WAIT_FAILED ? -1 : 0;
100 }
101
102 int 
103 ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
104 {
105         return 0;
106 }
107
108 int 
109 ldap_pvt_thread_yield( void )
110 {
111         Sleep( 0 );
112         return 0;
113 }
114
115 int 
116 ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
117 {
118         *cond = CreateEvent( NULL, FALSE, FALSE, NULL );
119         return( 0 );
120 }
121
122 int
123 ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
124 {
125         CloseHandle( *cv );
126         return( 0 );
127 }
128
129 int 
130 ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
131 {
132         SetEvent( *cond );
133         return( 0 );
134 }
135
136 int 
137 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
138         ldap_pvt_thread_mutex_t *mutex )
139 {
140         SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE );
141         WaitForSingleObject( *mutex, INFINITE );
142         return( 0 );
143 }
144
145 int
146 ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
147 {
148         while ( WaitForSingleObject( *cond, 0 ) == WAIT_TIMEOUT )
149                 SetEvent( *cond );
150         return( 0 );
151 }
152
153 int 
154 ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
155 {
156         *mutex = CreateMutex( NULL, 0, NULL );
157         return ( 0 );
158 }
159
160 int 
161 ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
162 {
163         CloseHandle( *mutex );
164         return ( 0 );   
165 }
166
167 int 
168 ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
169 {
170         DWORD status;
171         status = WaitForSingleObject( *mutex, INFINITE );
172         return status == WAIT_FAILED ? -1 : 0;
173 }
174
175 int 
176 ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
177 {
178         ReleaseMutex( *mutex );
179         return ( 0 );
180 }
181
182 int
183 ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
184 {
185         DWORD status;
186         status = WaitForSingleObject( *mp, 0 );
187         return status == WAIT_FAILED || status == WAIT_TIMEOUT
188                 ? -1 : 0;
189 }
190
191 ldap_pvt_thread_t
192 ldap_pvt_thread_self( void )
193 {
194         return GetCurrentThreadId();
195 }
196
197 #endif