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