- New implementation of SendMessage, ReceiveMessage, ReplyMessage functions
[wine] / scheduler / mutex.c
1 /*
2  * Win32 mutexes
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 _MUTEX
18 {
19     K32OBJ         header;
20 } MUTEX;
21
22
23 /***********************************************************************
24  *           CreateMutex32A   (KERNEL32.166)
25  */
26 HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
27                                 LPCSTR name )
28 {
29     struct create_mutex_request req;
30     struct create_mutex_reply reply;
31     int len = name ? strlen(name) + 1 : 0;
32     HANDLE32 handle;
33     MUTEX *mutex;
34
35     req.owned   = owner;
36     req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
37
38     CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, len );
39     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
40     if (reply.handle == -1) return 0;
41
42     SYSTEM_LOCK();
43     mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex),
44                                     name, reply.handle, MUTEX_ALL_ACCESS,
45                                     sa, &handle );
46     if (mutex) K32OBJ_DecCount( &mutex->header );
47     if (handle == INVALID_HANDLE_VALUE32) handle = 0;
48     SYSTEM_UNLOCK();
49     return handle;
50 }
51
52
53 /***********************************************************************
54  *           CreateMutex32W   (KERNEL32.167)
55  */
56 HANDLE32 WINAPI CreateMutex32W( SECURITY_ATTRIBUTES *sa, BOOL32 owner,
57                                 LPCWSTR name )
58 {
59     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
60     HANDLE32 ret = CreateMutex32A( sa, owner, nameA );
61     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
62     return ret;
63 }
64
65
66 /***********************************************************************
67  *           OpenMutex32A   (KERNEL32.541)
68  */
69 HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name )
70 {
71     HANDLE32 handle = 0;
72     K32OBJ *obj;
73     struct open_named_obj_request req;
74     struct open_named_obj_reply reply;
75     int len = name ? strlen(name) + 1 : 0;
76
77     req.type    = OPEN_MUTEX;
78     req.access  = access;
79     req.inherit = inherit;
80     CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len );
81     CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
82     if (reply.handle != -1)
83     {
84         SYSTEM_LOCK();
85         if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL)
86         {
87             handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit, reply.handle );
88             K32OBJ_DecCount( obj );
89             if (handle == INVALID_HANDLE_VALUE32)
90                 handle = 0; /* must return 0 on failure, not -1 */
91         }
92         else CLIENT_CloseHandle( reply.handle );
93         SYSTEM_UNLOCK();
94     }
95     return handle;
96 }
97
98
99 /***********************************************************************
100  *           OpenMutex32W   (KERNEL32.542)
101  */
102 HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name )
103 {
104     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
105     HANDLE32 ret = OpenMutex32A( access, inherit, nameA );
106     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
107     return ret;
108 }
109
110
111 /***********************************************************************
112  *           ReleaseMutex   (KERNEL32.582)
113  */
114 BOOL32 WINAPI ReleaseMutex( HANDLE32 handle )
115 {
116     struct release_mutex_request req;
117
118     req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
119                                          K32OBJ_MUTEX, MUTEX_MODIFY_STATE );
120     if (req.handle == -1) return FALSE;
121     CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) );
122     return !CLIENT_WaitReply( NULL, NULL, 0 );
123 }