Use Win32 file handles instead of Unix ones.
[wine/multimedia.git] / scheduler / semaphore.c
blob561d536d69c93909062631b4b86345a305b78573
1 /*
2 * Win32 semaphores
4 * Copyright 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include "windows.h"
9 #include "winerror.h"
10 #include "k32obj.h"
11 #include "process.h"
12 #include "thread.h"
13 #include "heap.h"
14 #include "server/request.h"
15 #include "server.h"
17 typedef struct
19 K32OBJ header;
20 } SEMAPHORE;
22 static void SEMAPHORE_Destroy( K32OBJ *obj );
24 const K32OBJ_OPS SEMAPHORE_Ops =
26 SEMAPHORE_Destroy /* destroy */
30 /***********************************************************************
31 * CreateSemaphore32A (KERNEL32.174)
33 HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
34 LONG max, LPCSTR name )
36 struct create_semaphore_request req;
37 struct create_semaphore_reply reply;
38 int len = name ? strlen(name) + 1 : 0;
39 HANDLE32 handle;
40 SEMAPHORE *sem;
42 /* Check parameters */
44 if ((max <= 0) || (initial < 0) || (initial > max))
46 SetLastError( ERROR_INVALID_PARAMETER );
47 return 0;
50 req.initial = (unsigned int)initial;
51 req.max = (unsigned int)max;
52 req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
54 CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
55 CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
56 CHECK_LEN( len, sizeof(reply) );
57 if (reply.handle == -1) return 0;
59 SYSTEM_LOCK();
60 sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
61 name, reply.handle, SEMAPHORE_ALL_ACCESS,
62 sa, &handle);
63 if (sem) K32OBJ_DecCount( &sem->header );
64 SYSTEM_UNLOCK();
65 if (handle == INVALID_HANDLE_VALUE32) handle = 0;
66 return handle;
70 /***********************************************************************
71 * CreateSemaphore32W (KERNEL32.175)
73 HANDLE32 WINAPI CreateSemaphore32W( SECURITY_ATTRIBUTES *sa, LONG initial,
74 LONG max, LPCWSTR name )
76 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
77 HANDLE32 ret = CreateSemaphore32A( sa, initial, max, nameA );
78 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
79 return ret;
83 /***********************************************************************
84 * OpenSemaphore32A (KERNEL32.545)
86 HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
88 HANDLE32 handle = 0;
89 K32OBJ *obj;
90 struct open_named_obj_request req;
91 struct open_named_obj_reply reply;
92 int len = name ? strlen(name) + 1 : 0;
94 req.type = OPEN_SEMAPHORE;
95 req.access = access;
96 req.inherit = inherit;
97 CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
98 CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) );
99 CHECK_LEN( len, sizeof(reply) );
100 if (reply.handle != -1)
102 SYSTEM_LOCK();
103 if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
105 handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
106 K32OBJ_DecCount( obj );
107 if (handle == INVALID_HANDLE_VALUE32)
108 handle = 0; /* must return 0 on failure, not -1 */
110 else CLIENT_CloseHandle( reply.handle );
111 SYSTEM_UNLOCK();
113 return handle;
117 /***********************************************************************
118 * OpenSemaphore32W (KERNEL32.546)
120 HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
122 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
123 HANDLE32 ret = OpenSemaphore32A( access, inherit, nameA );
124 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
125 return ret;
129 /***********************************************************************
130 * ReleaseSemaphore (KERNEL32.583)
132 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
134 struct release_semaphore_request req;
135 struct release_semaphore_reply reply;
136 int len;
138 if (count < 0)
140 SetLastError( ERROR_INVALID_PARAMETER );
141 return FALSE;
143 req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
144 K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
145 if (req.handle == -1) return FALSE;
146 req.count = (unsigned int)count;
147 CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
148 if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) return FALSE;
149 CHECK_LEN( len, sizeof(reply) );
150 if (previous) *previous = reply.prev_count;
151 return TRUE;
155 /***********************************************************************
156 * SEMAPHORE_Destroy
158 static void SEMAPHORE_Destroy( K32OBJ *obj )
160 SEMAPHORE *sem = (SEMAPHORE *)obj;
161 assert( obj->type == K32OBJ_SEMAPHORE );
162 /* There cannot be any thread on the list since the ref count is 0 */
163 obj->type = K32OBJ_UNKNOWN;
164 HeapFree( SystemHeap, 0, sem );