4 * Copyright 1998 Alexandre Julliard
18 THREAD_QUEUE wait_queue;
23 static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id );
24 static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id );
25 static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id );
26 static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id );
27 static void SEMAPHORE_Destroy( K32OBJ *obj );
29 const K32OBJ_OPS SEMAPHORE_Ops =
31 SEMAPHORE_Signaled, /* signaled */
32 SEMAPHORE_Satisfied, /* satisfied */
33 SEMAPHORE_AddWait, /* add_wait */
34 SEMAPHORE_RemoveWait, /* remove_wait */
35 SEMAPHORE_Destroy /* destroy */
39 /***********************************************************************
40 * CreateSemaphore32A (KERNEL32.174)
42 HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
43 LONG max, LPCSTR name )
48 /* Check parameters */
50 if ((max <= 0) || (initial < 0) || (initial > max))
52 SetLastError( ERROR_INVALID_PARAMETER );
53 return INVALID_HANDLE_VALUE32;
57 sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
58 name, SEMAPHORE_ALL_ACCESS, &handle );
61 /* Finish initializing it */
62 sem->wait_queue = NULL;
65 K32OBJ_DecCount( &sem->header );
72 /***********************************************************************
73 * CreateSemaphore32W (KERNEL32.175)
75 HANDLE32 WINAPI CreateSemaphore32W( SECURITY_ATTRIBUTES *sa, LONG initial,
76 LONG max, LPCWSTR name )
78 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
79 HANDLE32 ret = CreateSemaphore32A( sa, initial, max, nameA );
80 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
85 /***********************************************************************
86 * OpenSemaphore32A (KERNEL32.545)
88 HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
93 if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
95 handle = HANDLE_Alloc( obj, access, inherit );
96 K32OBJ_DecCount( obj );
103 /***********************************************************************
104 * OpenSemaphore32W (KERNEL32.546)
106 HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
108 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
109 HANDLE32 ret = OpenSemaphore32A( access, inherit, nameA );
110 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
115 /***********************************************************************
116 * ReleaseSemaphore (KERNEL32.583)
118 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
123 if (!(sem = (SEMAPHORE *)HANDLE_GetObjPtr( handle, K32OBJ_SEMAPHORE,
124 SEMAPHORE_MODIFY_STATE )))
129 if (previous) *previous = sem->count;
130 if (sem->count + count > sem->max)
133 SetLastError( ERROR_TOO_MANY_POSTS );
138 /* There cannot be any thread waiting if the count is > 0 */
139 assert( sem->wait_queue == NULL );
145 SYNC_WakeUp( &sem->wait_queue, count );
147 K32OBJ_DecCount( &sem->header );
153 /***********************************************************************
156 static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id )
158 SEMAPHORE *sem = (SEMAPHORE *)obj;
159 assert( obj->type == K32OBJ_SEMAPHORE );
160 return (sem->count > 0);
164 /***********************************************************************
165 * SEMAPHORE_Satisfied
167 * Wait on this object has been satisfied.
169 static BOOL32 SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id )
171 SEMAPHORE *sem = (SEMAPHORE *)obj;
172 assert( obj->type == K32OBJ_SEMAPHORE );
173 assert( sem->count > 0 );
175 return FALSE; /* Not abandoned */
179 /***********************************************************************
182 * Add current thread to object wait queue.
184 static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id )
186 SEMAPHORE *sem = (SEMAPHORE *)obj;
187 assert( obj->type == K32OBJ_SEMAPHORE );
188 THREAD_AddQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
192 /***********************************************************************
193 * SEMAPHORE_RemoveWait
195 * Remove thread from object wait queue.
197 static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id )
199 SEMAPHORE *sem = (SEMAPHORE *)obj;
200 assert( obj->type == K32OBJ_SEMAPHORE );
201 THREAD_RemoveQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) );
205 /***********************************************************************
208 static void SEMAPHORE_Destroy( K32OBJ *obj )
210 SEMAPHORE *sem = (SEMAPHORE *)obj;
211 assert( obj->type == K32OBJ_SEMAPHORE );
212 /* There cannot be any thread on the list since the ref count is 0 */
213 assert( sem->wait_queue == NULL );
214 obj->type = K32OBJ_UNKNOWN;
215 HeapFree( SystemHeap, 0, sem );