Mercurial > trustbridge > nss-cmake-static
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 } |