Release 990226.
[wine/gsoc-2012-control.git] / scheduler / semaphore.c
blobd329ec9aa578eb211f32e9e462cc3debc8e57f55
1 /*
2 * Win32 semaphores
4 * Copyright 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include "winerror.h"
9 #include "k32obj.h"
10 #include "process.h"
11 #include "thread.h"
12 #include "heap.h"
13 #include "server/request.h"
14 #include "server.h"
16 typedef struct
18 K32OBJ header;
19 } SEMAPHORE;
22 /***********************************************************************
23 * CreateSemaphore32A (KERNEL32.174)
25 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial,
26 LONG max, LPCSTR name )
28 struct create_semaphore_request req;
29 struct create_semaphore_reply reply;
30 int len = name ? strlen(name) + 1 : 0;
31 HANDLE handle;
32 SEMAPHORE *sem;
34 /* Check parameters */
36 if ((max <= 0) || (initial < 0) || (initial > max))
38 SetLastError( ERROR_INVALID_PARAMETER );
39 return 0;
42 req.initial = (unsigned int)initial;
43 req.max = (unsigned int)max;
44 req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
46 CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
47 CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
48 if (reply.handle == -1) return 0;
50 SYSTEM_LOCK();
51 sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
52 name, reply.handle, SEMAPHORE_ALL_ACCESS,
53 sa, &handle);
54 if (sem) K32OBJ_DecCount( &sem->header );
55 SYSTEM_UNLOCK();
56 if (handle == INVALID_HANDLE_VALUE) handle = 0;
57 return handle;
61 /***********************************************************************
62 * CreateSemaphore32W (KERNEL32.175)
64 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
65 LONG max, LPCWSTR name )
67 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
68 HANDLE ret = CreateSemaphoreA( sa, initial, max, nameA );
69 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
70 return ret;
74 /***********************************************************************
75 * OpenSemaphore32A (KERNEL32.545)
77 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
79 HANDLE handle = 0;
80 K32OBJ *obj;
81 struct open_named_obj_request req;
82 struct open_named_obj_reply reply;
83 int len = name ? strlen(name) + 1 : 0;
85 req.type = OPEN_SEMAPHORE;
86 req.access = access;
87 req.inherit = inherit;
88 CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
89 CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
90 if (reply.handle != -1)
92 SYSTEM_LOCK();
93 if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
95 handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
96 K32OBJ_DecCount( obj );
97 if (handle == INVALID_HANDLE_VALUE)
98 handle = 0; /* must return 0 on failure, not -1 */
100 else CLIENT_CloseHandle( reply.handle );
101 SYSTEM_UNLOCK();
103 return handle;
107 /***********************************************************************
108 * OpenSemaphore32W (KERNEL32.546)
110 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
112 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
113 HANDLE ret = OpenSemaphoreA( access, inherit, nameA );
114 if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
115 return ret;
119 /***********************************************************************
120 * ReleaseSemaphore (KERNEL32.583)
122 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
124 struct release_semaphore_request req;
125 struct release_semaphore_reply reply;
127 if (count < 0)
129 SetLastError( ERROR_INVALID_PARAMETER );
130 return FALSE;
132 req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
133 K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
134 if (req.handle == -1) return FALSE;
135 req.count = (unsigned int)count;
136 CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
137 if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
138 if (previous) *previous = reply.prev_count;
139 return TRUE;