comparison nspr/pr/src/md/windows/w32ipcsem.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * File: w32ipcsem.c
8 * Description: implements named semaphores for NT and WIN95.
9 */
10
11 #include "primpl.h"
12
13 #ifdef WINCE
14 static HANDLE OpenSemaphore(DWORD inDesiredAccess,
15 BOOL inInheritHandle,
16 const char *inName)
17 {
18 HANDLE retval = NULL;
19 HANDLE semaphore = NULL;
20 PRUnichar wideName[MAX_PATH]; /* name size is limited to MAX_PATH */
21
22 MultiByteToWideChar(CP_ACP, 0, inName, -1, wideName, MAX_PATH);
23 /* 0x7fffffff is the max count for our semaphore */
24 semaphore = CreateSemaphoreW(NULL, 0, 0x7fffffff, wideName);
25 if (NULL != semaphore) {
26 DWORD lastErr = GetLastError();
27
28 if (ERROR_ALREADY_EXISTS != lastErr)
29 CloseHandle(semaphore);
30 else
31 retval = semaphore;
32 }
33 return retval;
34 }
35 #endif
36
37 /*
38 * NSPR-to-NT access right mapping table for semaphore objects.
39 *
40 * The SYNCHRONIZE access is required by WaitForSingleObject.
41 * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore.
42 * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS.
43 * This is because if a semaphore object with the specified name
44 * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to
45 * the existing object.
46 */
47 static DWORD semAccessTable[] = {
48 STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */
49 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */
50 0 /* execute */
51 };
52
53 #ifndef _PR_GLOBAL_THREADS_ONLY
54
55 /*
56 * A fiber cannot call WaitForSingleObject because that
57 * will block the other fibers running on the same thread.
58 * If a fiber needs to wait on a (semaphore) handle, we
59 * create a native thread to call WaitForSingleObject and
60 * have the fiber join the native thread.
61 */
62
63 /*
64 * Arguments, return value, and error code for WaitForSingleObject
65 */
66 struct WaitSingleArg {
67 HANDLE handle;
68 DWORD timeout;
69 DWORD rv;
70 DWORD error;
71 };
72
73 static void WaitSingleThread(void *arg)
74 {
75 struct WaitSingleArg *warg = (struct WaitSingleArg *) arg;
76
77 warg->rv = WaitForSingleObject(warg->handle, warg->timeout);
78 if (warg->rv == WAIT_FAILED) {
79 warg->error = GetLastError();
80 }
81 }
82
83 static DWORD FiberSafeWaitForSingleObject(
84 HANDLE hHandle,
85 DWORD dwMilliseconds
86 )
87 {
88 PRThread *me = _PR_MD_CURRENT_THREAD();
89
90 if (_PR_IS_NATIVE_THREAD(me)) {
91 return WaitForSingleObject(hHandle, dwMilliseconds);
92 } else {
93 PRThread *waitThread;
94 struct WaitSingleArg warg;
95 PRStatus rv;
96
97 warg.handle = hHandle;
98 warg.timeout = dwMilliseconds;
99 waitThread = PR_CreateThread(
100 PR_USER_THREAD, WaitSingleThread, &warg,
101 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
102 if (waitThread == NULL) {
103 return WAIT_FAILED;
104 }
105
106 rv = PR_JoinThread(waitThread);
107 PR_ASSERT(rv == PR_SUCCESS);
108 if (rv == PR_FAILURE) {
109 return WAIT_FAILED;
110 }
111 if (warg.rv == WAIT_FAILED) {
112 SetLastError(warg.error);
113 }
114 return warg.rv;
115 }
116 }
117
118 #endif /* !_PR_GLOBAL_THREADS_ONLY */
119
120 PRSem *_PR_MD_OPEN_SEMAPHORE(
121 const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
122 {
123 PRSem *sem;
124 SECURITY_ATTRIBUTES sa;
125 LPSECURITY_ATTRIBUTES lpSA = NULL;
126 PSECURITY_DESCRIPTOR pSD = NULL;
127 PACL pACL = NULL;
128
129 sem = PR_NEW(PRSem);
130 if (sem == NULL) {
131 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
132 return NULL;
133 }
134 if (flags & PR_SEM_CREATE) {
135 if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
136 &pSD, &pACL) == PR_SUCCESS) {
137 sa.nLength = sizeof(sa);
138 sa.lpSecurityDescriptor = pSD;
139 sa.bInheritHandle = FALSE;
140 lpSA = &sa;
141 }
142 #ifdef WINCE
143 {
144 /* The size of a sem's name is limited to MAX_PATH. */
145 PRUnichar wosname[MAX_PATH];
146 MultiByteToWideChar(CP_ACP, 0, osname, -1, wosname, MAX_PATH);
147 sem->sem = CreateSemaphoreW(lpSA, value, 0x7fffffff, wosname);
148 }
149 #else
150 sem->sem = CreateSemaphoreA(lpSA, value, 0x7fffffff, osname);
151 #endif
152 if (lpSA != NULL) {
153 _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
154 }
155 if (sem->sem == NULL) {
156 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
157 PR_DELETE(sem);
158 return NULL;
159 }
160 if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
161 PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
162 CloseHandle(sem->sem);
163 PR_DELETE(sem);
164 return NULL;
165 }
166 } else {
167 sem->sem = OpenSemaphore(
168 SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname);
169 if (sem->sem == NULL) {
170 DWORD err = GetLastError();
171
172 /*
173 * If we open a nonexistent named semaphore, NT
174 * returns ERROR_FILE_NOT_FOUND, while Win95
175 * returns ERROR_INVALID_NAME
176 */
177 if (err == ERROR_INVALID_NAME) {
178 PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
179 } else {
180 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
181 }
182 PR_DELETE(sem);
183 return NULL;
184 }
185 }
186 return sem;
187 }
188
189 PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem)
190 {
191 DWORD rv;
192
193 #ifdef _PR_GLOBAL_THREADS_ONLY
194 rv = WaitForSingleObject(sem->sem, INFINITE);
195 #else
196 rv = FiberSafeWaitForSingleObject(sem->sem, INFINITE);
197 #endif
198 PR_ASSERT(rv == WAIT_FAILED || rv == WAIT_OBJECT_0);
199 if (rv == WAIT_FAILED) {
200 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
201 return PR_FAILURE;
202 }
203 if (rv != WAIT_OBJECT_0) {
204 /* Should not happen */
205 PR_SetError(PR_UNKNOWN_ERROR, 0);
206 return PR_FAILURE;
207 }
208 return PR_SUCCESS;
209 }
210
211 PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem)
212 {
213 if (ReleaseSemaphore(sem->sem, 1, NULL) == FALSE) {
214 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
215 return PR_FAILURE;
216 }
217 return PR_SUCCESS;
218 }
219
220 PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem)
221 {
222 if (CloseHandle(sem->sem) == FALSE) {
223 _PR_MD_MAP_CLOSE_ERROR(GetLastError());
224 return PR_FAILURE;
225 }
226 PR_DELETE(sem);
227 return PR_SUCCESS;
228 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)