OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #include "seccomon.h" | |
6 /* This ifdef should match the one in sslsnce.c */ | |
7 #if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_OS2) || defined(XP_BEOS) | |
8 | |
9 #include "sslmutex.h" | |
10 #include "prerr.h" | |
11 | |
12 static SECStatus | |
13 single_process_sslMutex_Init(sslMutex* pMutex) | |
14 { | |
15 PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0); | |
16 | |
17 pMutex->u.sslLock = PR_NewLock(); | |
18 if (!pMutex->u.sslLock) { | |
19 return SECFailure; | |
20 } | |
21 return SECSuccess; | |
22 } | |
23 | |
24 static SECStatus | |
25 single_process_sslMutex_Destroy(sslMutex* pMutex) | |
26 { | |
27 PR_ASSERT(pMutex != 0); | |
28 PR_ASSERT(pMutex->u.sslLock != 0); | |
29 if (!pMutex->u.sslLock) { | |
30 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
31 return SECFailure; | |
32 } | |
33 PR_DestroyLock(pMutex->u.sslLock); | |
34 return SECSuccess; | |
35 } | |
36 | |
37 static SECStatus | |
38 single_process_sslMutex_Unlock(sslMutex* pMutex) | |
39 { | |
40 PR_ASSERT(pMutex != 0); | |
41 PR_ASSERT(pMutex->u.sslLock != 0); | |
42 if (!pMutex->u.sslLock) { | |
43 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
44 return SECFailure; | |
45 } | |
46 PR_Unlock(pMutex->u.sslLock); | |
47 return SECSuccess; | |
48 } | |
49 | |
50 static SECStatus | |
51 single_process_sslMutex_Lock(sslMutex* pMutex) | |
52 { | |
53 PR_ASSERT(pMutex != 0); | |
54 PR_ASSERT(pMutex->u.sslLock != 0); | |
55 if (!pMutex->u.sslLock) { | |
56 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
57 return SECFailure; | |
58 } | |
59 PR_Lock(pMutex->u.sslLock); | |
60 return SECSuccess; | |
61 } | |
62 | |
63 #if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined
(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) | |
64 | |
65 #include <unistd.h> | |
66 #include <fcntl.h> | |
67 #include <string.h> | |
68 #include <errno.h> | |
69 #include "unix_err.h" | |
70 #include "pratom.h" | |
71 | |
72 #define SSL_MUTEX_MAGIC 0xfeedfd | |
73 #define NONBLOCKING_POSTS 1 /* maybe this is faster */ | |
74 | |
75 #if NONBLOCKING_POSTS | |
76 | |
77 #ifndef FNONBLOCK | |
78 #define FNONBLOCK O_NONBLOCK | |
79 #endif | |
80 | |
81 static int | |
82 setNonBlocking(int fd, int nonBlocking) | |
83 { | |
84 int flags; | |
85 int err; | |
86 | |
87 flags = fcntl(fd, F_GETFL, 0); | |
88 if (0 > flags) | |
89 return flags; | |
90 if (nonBlocking) | |
91 flags |= FNONBLOCK; | |
92 else | |
93 flags &= ~FNONBLOCK; | |
94 err = fcntl(fd, F_SETFL, flags); | |
95 return err; | |
96 } | |
97 #endif | |
98 | |
99 SECStatus | |
100 sslMutex_Init(sslMutex* pMutex, int shared) | |
101 { | |
102 int err; | |
103 PR_ASSERT(pMutex); | |
104 pMutex->isMultiProcess = (PRBool)(shared != 0); | |
105 if (!shared) { | |
106 return single_process_sslMutex_Init(pMutex); | |
107 } | |
108 pMutex->u.pipeStr.mPipes[0] = -1; | |
109 pMutex->u.pipeStr.mPipes[1] = -1; | |
110 pMutex->u.pipeStr.mPipes[2] = -1; | |
111 pMutex->u.pipeStr.nWaiters = 0; | |
112 | |
113 err = pipe(pMutex->u.pipeStr.mPipes); | |
114 if (err) { | |
115 nss_MD_unix_map_default_error(errno); | |
116 return err; | |
117 } | |
118 #if NONBLOCKING_POSTS | |
119 err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1); | |
120 if (err) | |
121 goto loser; | |
122 #endif | |
123 | |
124 pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC; | |
125 | |
126 #if defined(LINUX) && defined(i386) | |
127 /* Pipe starts out empty */ | |
128 return SECSuccess; | |
129 #else | |
130 /* Pipe starts with one byte. */ | |
131 return sslMutex_Unlock(pMutex); | |
132 #endif | |
133 | |
134 loser: | |
135 nss_MD_unix_map_default_error(errno); | |
136 close(pMutex->u.pipeStr.mPipes[0]); | |
137 close(pMutex->u.pipeStr.mPipes[1]); | |
138 return SECFailure; | |
139 } | |
140 | |
141 SECStatus | |
142 sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal) | |
143 { | |
144 if (PR_FALSE == pMutex->isMultiProcess) { | |
145 return single_process_sslMutex_Destroy(pMutex); | |
146 } | |
147 if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { | |
148 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
149 return SECFailure; | |
150 } | |
151 close(pMutex->u.pipeStr.mPipes[0]); | |
152 close(pMutex->u.pipeStr.mPipes[1]); | |
153 | |
154 if (processLocal) { | |
155 return SECSuccess; | |
156 } | |
157 | |
158 pMutex->u.pipeStr.mPipes[0] = -1; | |
159 pMutex->u.pipeStr.mPipes[1] = -1; | |
160 pMutex->u.pipeStr.mPipes[2] = -1; | |
161 pMutex->u.pipeStr.nWaiters = 0; | |
162 | |
163 return SECSuccess; | |
164 } | |
165 | |
166 #if defined(LINUX) && defined(i386) | |
167 /* No memory barrier needed for this platform */ | |
168 | |
169 /* nWaiters includes the holder of the lock (if any) and the number | |
170 ** threads waiting for it. After incrementing nWaiters, if the count | |
171 ** is exactly 1, then you have the lock and may proceed. If the | |
172 ** count is greater than 1, then you must wait on the pipe. | |
173 */ | |
174 | |
175 SECStatus | |
176 sslMutex_Unlock(sslMutex* pMutex) | |
177 { | |
178 PRInt32 newValue; | |
179 if (PR_FALSE == pMutex->isMultiProcess) { | |
180 return single_process_sslMutex_Unlock(pMutex); | |
181 } | |
182 | |
183 if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { | |
184 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
185 return SECFailure; | |
186 } | |
187 /* Do Memory Barrier here. */ | |
188 newValue = PR_ATOMIC_DECREMENT(&pMutex->u.pipeStr.nWaiters); | |
189 if (newValue > 0) { | |
190 int cc; | |
191 char c = 1; | |
192 do { | |
193 cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1); | |
194 } while (cc < 0 && (errno == EINTR || errno == EAGAIN)); | |
195 if (cc != 1) { | |
196 if (cc < 0) | |
197 nss_MD_unix_map_default_error(errno); | |
198 else | |
199 PORT_SetError(PR_UNKNOWN_ERROR); | |
200 return SECFailure; | |
201 } | |
202 } | |
203 return SECSuccess; | |
204 } | |
205 | |
206 SECStatus | |
207 sslMutex_Lock(sslMutex* pMutex) | |
208 { | |
209 PRInt32 newValue; | |
210 if (PR_FALSE == pMutex->isMultiProcess) { | |
211 return single_process_sslMutex_Lock(pMutex); | |
212 } | |
213 | |
214 if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { | |
215 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
216 return SECFailure; | |
217 } | |
218 newValue = PR_ATOMIC_INCREMENT(&pMutex->u.pipeStr.nWaiters); | |
219 /* Do Memory Barrier here. */ | |
220 if (newValue > 1) { | |
221 int cc; | |
222 char c; | |
223 do { | |
224 cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1); | |
225 } while (cc < 0 && errno == EINTR); | |
226 if (cc != 1) { | |
227 if (cc < 0) | |
228 nss_MD_unix_map_default_error(errno); | |
229 else | |
230 PORT_SetError(PR_UNKNOWN_ERROR); | |
231 return SECFailure; | |
232 } | |
233 } | |
234 return SECSuccess; | |
235 } | |
236 | |
237 #else | |
238 | |
239 /* Using Atomic operations requires the use of a memory barrier instruction | |
240 ** on PowerPC, Sparc, and Alpha. NSPR's PR_Atomic functions do not perform | |
241 ** them, and NSPR does not provide a function that does them (e.g. PR_Barrier). | |
242 ** So, we don't use them on those platforms. | |
243 */ | |
244 | |
245 SECStatus | |
246 sslMutex_Unlock(sslMutex* pMutex) | |
247 { | |
248 int cc; | |
249 char c = 1; | |
250 | |
251 if (PR_FALSE == pMutex->isMultiProcess) { | |
252 return single_process_sslMutex_Unlock(pMutex); | |
253 } | |
254 | |
255 if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { | |
256 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
257 return SECFailure; | |
258 } | |
259 do { | |
260 cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1); | |
261 } while (cc < 0 && (errno == EINTR || errno == EAGAIN)); | |
262 if (cc != 1) { | |
263 if (cc < 0) | |
264 nss_MD_unix_map_default_error(errno); | |
265 else | |
266 PORT_SetError(PR_UNKNOWN_ERROR); | |
267 return SECFailure; | |
268 } | |
269 | |
270 return SECSuccess; | |
271 } | |
272 | |
273 SECStatus | |
274 sslMutex_Lock(sslMutex* pMutex) | |
275 { | |
276 int cc; | |
277 char c; | |
278 | |
279 if (PR_FALSE == pMutex->isMultiProcess) { | |
280 return single_process_sslMutex_Lock(pMutex); | |
281 } | |
282 | |
283 if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { | |
284 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
285 return SECFailure; | |
286 } | |
287 | |
288 do { | |
289 cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1); | |
290 } while (cc < 0 && errno == EINTR); | |
291 if (cc != 1) { | |
292 if (cc < 0) | |
293 nss_MD_unix_map_default_error(errno); | |
294 else | |
295 PORT_SetError(PR_UNKNOWN_ERROR); | |
296 return SECFailure; | |
297 } | |
298 | |
299 return SECSuccess; | |
300 } | |
301 | |
302 #endif | |
303 | |
304 #elif defined(WIN32) | |
305 | |
306 #include "win32err.h" | |
307 | |
308 /* on Windows, we need to find the optimal type of locking mechanism to use | |
309 for the sslMutex. | |
310 | |
311 There are 3 cases : | |
312 1) single-process, use a PRLock, as for all other platforms | |
313 2) Win95 multi-process, use a Win32 mutex | |
314 3) on WINNT multi-process, use a PRLock + a Win32 mutex | |
315 | |
316 */ | |
317 | |
318 #ifdef WINNT | |
319 | |
320 SECStatus | |
321 sslMutex_2LevelInit(sslMutex *sem) | |
322 { | |
323 /* the following adds a PRLock to sslMutex . This is done in each | |
324 process of a multi-process server and is only needed on WINNT, if | |
325 using fibers. We can't tell if native threads or fibers are used, so | |
326 we always do it on WINNT | |
327 */ | |
328 PR_ASSERT(sem); | |
329 if (sem) { | |
330 /* we need to reset the sslLock in the children or the single_process in
it | |
331 function below will assert */ | |
332 sem->u.sslLock = NULL; | |
333 } | |
334 return single_process_sslMutex_Init(sem); | |
335 } | |
336 | |
337 static SECStatus | |
338 sslMutex_2LevelDestroy(sslMutex *sem) | |
339 { | |
340 return single_process_sslMutex_Destroy(sem); | |
341 } | |
342 | |
343 #endif | |
344 | |
345 SECStatus | |
346 sslMutex_Init(sslMutex *pMutex, int shared) | |
347 { | |
348 #ifdef WINNT | |
349 SECStatus retvalue; | |
350 #endif | |
351 HANDLE hMutex; | |
352 SECURITY_ATTRIBUTES attributes = | |
353 { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; | |
354 | |
355 PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 || | |
356 pMutex->u.sslMutx == | |
357 INVALID_HANDLE_VALUE)); | |
358 | |
359 pMutex->isMultiProcess = (PRBool)(shared != 0); | |
360 | |
361 if (PR_FALSE == pMutex->isMultiProcess) { | |
362 return single_process_sslMutex_Init(pMutex); | |
363 } | |
364 | |
365 #ifdef WINNT | |
366 /* we need a lock on WINNT for fibers in the parent process */ | |
367 retvalue = sslMutex_2LevelInit(pMutex); | |
368 if (SECSuccess != retvalue) | |
369 return SECFailure; | |
370 #endif | |
371 | |
372 if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 && | |
373 hMutex != | |
374 INVALID_HANDLE_VALUE)) { | |
375 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
376 return SECFailure; | |
377 } | |
378 attributes.bInheritHandle = (shared ? TRUE : FALSE); | |
379 hMutex = CreateMutex(&attributes, FALSE, NULL); | |
380 if (hMutex == NULL) { | |
381 hMutex = INVALID_HANDLE_VALUE; | |
382 nss_MD_win32_map_default_error(GetLastError()); | |
383 return SECFailure; | |
384 } | |
385 pMutex->u.sslMutx = hMutex; | |
386 return SECSuccess; | |
387 } | |
388 | |
389 SECStatus | |
390 sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) | |
391 { | |
392 HANDLE hMutex; | |
393 int rv; | |
394 int retvalue = SECSuccess; | |
395 | |
396 PR_ASSERT(pMutex != 0); | |
397 if (PR_FALSE == pMutex->isMultiProcess) { | |
398 return single_process_sslMutex_Destroy(pMutex); | |
399 } | |
400 | |
401 /* multi-process mode */ | |
402 #ifdef WINNT | |
403 /* on NT, get rid of the PRLock used for fibers within a process */ | |
404 retvalue = sslMutex_2LevelDestroy(pMutex); | |
405 #endif | |
406 | |
407 PR_ASSERT(pMutex->u.sslMutx != 0 && | |
408 pMutex->u.sslMutx != INVALID_HANDLE_VALUE); | |
409 if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || | |
410 hMutex == INVALID_HANDLE_VALUE) { | |
411 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
412 return SECFailure; | |
413 } | |
414 | |
415 rv = CloseHandle(hMutex); /* ignore error */ | |
416 if (!processLocal && rv) { | |
417 pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE; | |
418 } | |
419 if (!rv) { | |
420 nss_MD_win32_map_default_error(GetLastError()); | |
421 retvalue = SECFailure; | |
422 } | |
423 return retvalue; | |
424 } | |
425 | |
426 int | |
427 sslMutex_Unlock(sslMutex *pMutex) | |
428 { | |
429 BOOL success = FALSE; | |
430 HANDLE hMutex; | |
431 | |
432 PR_ASSERT(pMutex != 0); | |
433 if (PR_FALSE == pMutex->isMultiProcess) { | |
434 return single_process_sslMutex_Unlock(pMutex); | |
435 } | |
436 | |
437 PR_ASSERT(pMutex->u.sslMutx != 0 && | |
438 pMutex->u.sslMutx != INVALID_HANDLE_VALUE); | |
439 if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || | |
440 hMutex == INVALID_HANDLE_VALUE) { | |
441 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
442 return SECFailure; | |
443 } | |
444 success = ReleaseMutex(hMutex); | |
445 if (!success) { | |
446 nss_MD_win32_map_default_error(GetLastError()); | |
447 return SECFailure; | |
448 } | |
449 #ifdef WINNT | |
450 return single_process_sslMutex_Unlock(pMutex); | |
451 /* release PRLock for other fibers in the process */ | |
452 #else | |
453 return SECSuccess; | |
454 #endif | |
455 } | |
456 | |
457 int | |
458 sslMutex_Lock(sslMutex *pMutex) | |
459 { | |
460 HANDLE hMutex; | |
461 DWORD event; | |
462 DWORD lastError; | |
463 SECStatus rv; | |
464 SECStatus retvalue = SECSuccess; | |
465 PR_ASSERT(pMutex != 0); | |
466 | |
467 if (PR_FALSE == pMutex->isMultiProcess) { | |
468 return single_process_sslMutex_Lock(pMutex); | |
469 } | |
470 #ifdef WINNT | |
471 /* lock first to preserve from other threads/fibers | |
472 in the same process */ | |
473 retvalue = single_process_sslMutex_Lock(pMutex); | |
474 #endif | |
475 PR_ASSERT(pMutex->u.sslMutx != 0 && | |
476 pMutex->u.sslMutx != INVALID_HANDLE_VALUE); | |
477 if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || | |
478 hMutex == INVALID_HANDLE_VALUE) { | |
479 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | |
480 return SECFailure; /* what else ? */ | |
481 } | |
482 /* acquire the mutex to be the only owner accross all other processes */ | |
483 event = WaitForSingleObject(hMutex, INFINITE); | |
484 switch (event) { | |
485 case WAIT_OBJECT_0: | |
486 case WAIT_ABANDONED: | |
487 rv = SECSuccess; | |
488 break; | |
489 | |
490 case WAIT_TIMEOUT: | |
491 #if defined(WAIT_IO_COMPLETION) | |
492 case WAIT_IO_COMPLETION: | |
493 #endif | |
494 default: /* should never happen. nothing we can do. */ | |
495 PR_ASSERT(!("WaitForSingleObject returned invalid value.")); | |
496 PORT_SetError(PR_UNKNOWN_ERROR); | |
497 rv = SECFailure; | |
498 break; | |
499 | |
500 case WAIT_FAILED: /* failure returns this */ | |
501 rv = SECFailure; | |
502 lastError = GetLastError(); /* for debugging */ | |
503 nss_MD_win32_map_default_error(lastError); | |
504 break; | |
505 } | |
506 | |
507 if (!(SECSuccess == retvalue && SECSuccess == rv)) { | |
508 return SECFailure; | |
509 } | |
510 | |
511 return SECSuccess; | |
512 } | |
513 | |
514 #elif defined(XP_UNIX) && !defined(DARWIN) | |
515 | |
516 #include <errno.h> | |
517 #include "unix_err.h" | |
518 | |
519 SECStatus | |
520 sslMutex_Init(sslMutex* pMutex, int shared) | |
521 { | |
522 int rv; | |
523 PR_ASSERT(pMutex); | |
524 pMutex->isMultiProcess = (PRBool)(shared != 0); | |
525 if (!shared) { | |
526 return single_process_sslMutex_Init(pMutex); | |
527 } | |
528 do { | |
529 rv = sem_init(&pMutex->u.sem, shared, 1); | |
530 } while (rv < 0 && errno == EINTR); | |
531 if (rv < 0) { | |
532 nss_MD_unix_map_default_error(errno); | |
533 return SECFailure; | |
534 } | |
535 return SECSuccess; | |
536 } | |
537 | |
538 SECStatus | |
539 sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal) | |
540 { | |
541 int rv; | |
542 if (PR_FALSE == pMutex->isMultiProcess) { | |
543 return single_process_sslMutex_Destroy(pMutex); | |
544 } | |
545 | |
546 /* semaphores are global resources. See SEM_DESTROY(3) man page */ | |
547 if (processLocal) { | |
548 return SECSuccess; | |
549 } | |
550 do { | |
551 rv = sem_destroy(&pMutex->u.sem); | |
552 } while (rv < 0 && errno == EINTR); | |
553 if (rv < 0) { | |
554 nss_MD_unix_map_default_error(errno); | |
555 return SECFailure; | |
556 } | |
557 return SECSuccess; | |
558 } | |
559 | |
560 SECStatus | |
561 sslMutex_Unlock(sslMutex* pMutex) | |
562 { | |
563 int rv; | |
564 if (PR_FALSE == pMutex->isMultiProcess) { | |
565 return single_process_sslMutex_Unlock(pMutex); | |
566 } | |
567 do { | |
568 rv = sem_post(&pMutex->u.sem); | |
569 } while (rv < 0 && errno == EINTR); | |
570 if (rv < 0) { | |
571 nss_MD_unix_map_default_error(errno); | |
572 return SECFailure; | |
573 } | |
574 return SECSuccess; | |
575 } | |
576 | |
577 SECStatus | |
578 sslMutex_Lock(sslMutex* pMutex) | |
579 { | |
580 int rv; | |
581 if (PR_FALSE == pMutex->isMultiProcess) { | |
582 return single_process_sslMutex_Lock(pMutex); | |
583 } | |
584 do { | |
585 rv = sem_wait(&pMutex->u.sem); | |
586 } while (rv < 0 && errno == EINTR); | |
587 if (rv < 0) { | |
588 nss_MD_unix_map_default_error(errno); | |
589 return SECFailure; | |
590 } | |
591 return SECSuccess; | |
592 } | |
593 | |
594 #else | |
595 | |
596 SECStatus | |
597 sslMutex_Init(sslMutex* pMutex, int shared) | |
598 { | |
599 PR_ASSERT(pMutex); | |
600 pMutex->isMultiProcess = (PRBool)(shared != 0); | |
601 if (!shared) { | |
602 return single_process_sslMutex_Init(pMutex); | |
603 } | |
604 PORT_Assert(!("sslMutex_Init not implemented for multi-process applications
!")); | |
605 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
606 return SECFailure; | |
607 } | |
608 | |
609 SECStatus | |
610 sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal) | |
611 { | |
612 PR_ASSERT(pMutex); | |
613 if (PR_FALSE == pMutex->isMultiProcess) { | |
614 return single_process_sslMutex_Destroy(pMutex); | |
615 } | |
616 PORT_Assert(!("sslMutex_Destroy not implemented for multi-process applicatio
ns !")); | |
617 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
618 return SECFailure; | |
619 } | |
620 | |
621 SECStatus | |
622 sslMutex_Unlock(sslMutex* pMutex) | |
623 { | |
624 PR_ASSERT(pMutex); | |
625 if (PR_FALSE == pMutex->isMultiProcess) { | |
626 return single_process_sslMutex_Unlock(pMutex); | |
627 } | |
628 PORT_Assert(!("sslMutex_Unlock not implemented for multi-process application
s !")); | |
629 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
630 return SECFailure; | |
631 } | |
632 | |
633 SECStatus | |
634 sslMutex_Lock(sslMutex* pMutex) | |
635 { | |
636 PR_ASSERT(pMutex); | |
637 if (PR_FALSE == pMutex->isMultiProcess) { | |
638 return single_process_sslMutex_Lock(pMutex); | |
639 } | |
640 PORT_Assert(!("sslMutex_Lock not implemented for multi-process applications
!")); | |
641 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
642 return SECFailure; | |
643 } | |
644 | |
645 #endif | |
646 | |
647 #endif | |
OLD | NEW |