- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / scheduler / semaphore.c
1 /*
2  * Win32 semaphores
3  *
4  * Copyright 1998 Alexandre Julliard
5  */
6
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"
16
17 typedef struct
18 {
19     K32OBJ        header;
20 } SEMAPHORE;
21
22
23 /***********************************************************************
24  *           CreateSemaphore32A   (KERNEL32.174)
25  */
26 HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial,
27                                     LONG max, LPCSTR name )
28 {
29     struct create_semaphore_request req;
30     struct create_semaphore_reply reply;
31     int len = name ? strlen(name) + 1 : 0;
32     HANDLE32 handle;
33     SEMAPHORE *sem;
34
35     /* Check parameters */
36
37     if ((max <= 0) || (initial < 0) || (initial > max))
38     {
39         SetLastError( ERROR_INVALID_PARAMETER );
40         return 0;
41     }
42
43     req.initial = (unsigned int)initial;
44     req.max     = (unsigned int)max;
45     req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
46
47     CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len );
48     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
49     if (reply.handle == -1) return 0;
50
51     SYSTEM_LOCK();
52     sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem),
53                                       name, reply.handle, SEMAPHORE_ALL_ACCESS,
54                                       sa, &handle);
55     if (sem) K32OBJ_DecCount( &sem->header );
56     SYSTEM_UNLOCK();
57     if (handle == INVALID_HANDLE_VALUE32) handle = 0;
58     return handle;
59 }
60
61
62 /***********************************************************************
63  *           CreateSemaphore32W   (KERNEL32.175)
64  */
65 HANDLE32 WINAPI CreateSemaphore32W( SECURITY_ATTRIBUTES *sa, LONG initial,
66                                     LONG max, LPCWSTR name )
67 {
68     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
69     HANDLE32 ret = CreateSemaphore32A( sa, initial, max, nameA );
70     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
71     return ret;
72 }
73
74
75 /***********************************************************************
76  *           OpenSemaphore32A   (KERNEL32.545)
77  */
78 HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name )
79 {
80     HANDLE32 handle = 0;
81     K32OBJ *obj;
82     struct open_named_obj_request req;
83     struct open_named_obj_reply reply;
84     int len = name ? strlen(name) + 1 : 0;
85
86     req.type    = OPEN_SEMAPHORE;
87     req.access  = access;
88     req.inherit = inherit;
89     CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
90     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
91     if (reply.handle != -1)
92     {
93         SYSTEM_LOCK();
94         if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL)
95         {
96             handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
97             K32OBJ_DecCount( obj );
98             if (handle == INVALID_HANDLE_VALUE32)
99                 handle = 0; /* must return 0 on failure, not -1 */
100         }
101         else CLIENT_CloseHandle( reply.handle );
102         SYSTEM_UNLOCK();
103     }
104     return handle;
105 }
106
107
108 /***********************************************************************
109  *           OpenSemaphore32W   (KERNEL32.546)
110  */
111 HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name )
112 {
113     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
114     HANDLE32 ret = OpenSemaphore32A( access, inherit, nameA );
115     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
116     return ret;
117 }
118
119
120 /***********************************************************************
121  *           ReleaseSemaphore   (KERNEL32.583)
122  */
123 BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous )
124 {
125     struct release_semaphore_request req;
126     struct release_semaphore_reply reply;
127
128     if (count < 0)
129     {
130         SetLastError( ERROR_INVALID_PARAMETER );
131         return FALSE;
132     }
133     req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
134                                          K32OBJ_SEMAPHORE, SEMAPHORE_MODIFY_STATE );
135     if (req.handle == -1) return FALSE;
136     req.count = (unsigned int)count;
137     CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) );
138     if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
139     if (previous) *previous = reply.prev_count;
140     return TRUE;
141 }