12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* This Source Code Form is subject to the terms of the Mozilla Public 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "seccomon.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This ifdef should match the one in sslsnce.c */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslmutex.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prerr.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus single_process_sslMutex_Init(sslMutex* pMutex) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0 ); 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslLock = PR_NewLock(); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex->u.sslLock) { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex->u.sslLock!= 0); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex->u.sslLock) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_DestroyLock(pMutex->u.sslLock); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0 ); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex->u.sslLock !=0); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex->u.sslLock) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_Unlock(pMutex->u.sslLock); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex->u.sslLock != 0 ); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex->u.sslLock) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_Lock(pMutex->u.sslLock); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unix_err.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pratom.h" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SSL_MUTEX_MAGIC 0xfeedfd 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NONBLOCKING_POSTS 1 /* maybe this is faster */ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NONBLOCKING_POSTS 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef FNONBLOCK 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FNONBLOCK O_NONBLOCK 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)setNonBlocking(int fd, int nonBlocking) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = fcntl(fd, F_GETFL, 0); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 > flags) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flags; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nonBlocking) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= FNONBLOCK; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags &= ~FNONBLOCK; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = fcntl(fd, F_SETFL, flags); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return err; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Init(sslMutex *pMutex, int shared) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->isMultiProcess = (PRBool)(shared != 0); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Init(pMutex); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[0] = -1; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[1] = -1; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[2] = -1; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.nWaiters = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = pipe(pMutex->u.pipeStr.mPipes); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return err; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NONBLOCKING_POSTS 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(LINUX) && defined(i386) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pipe starts out empty */ 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pipe starts with one byte. */ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sslMutex_Unlock(pMutex); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(pMutex->u.pipeStr.mPipes[0]); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(pMutex->u.pipeStr.mPipes[1]); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Destroy(pMutex); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(pMutex->u.pipeStr.mPipes[0]); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(pMutex->u.pipeStr.mPipes[1]); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processLocal) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[0] = -1; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[1] = -1; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.mPipes[2] = -1; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.pipeStr.nWaiters = 0; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(LINUX) && defined(i386) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* No memory barrier needed for this platform */ 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* nWaiters includes the holder of the lock (if any) and the number 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** threads waiting for it. After incrementing nWaiters, if the count 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is exactly 1, then you have the lock and may proceed. If the 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** count is greater than 1, then you must wait on the pipe. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Unlock(sslMutex *pMutex) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 newValue; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do Memory Barrier here. */ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newValue = PR_ATOMIC_DECREMENT(&pMutex->u.pipeStr.nWaiters); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newValue > 0) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cc; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c = 1; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (cc < 0 && (errno == EINTR || errno == EAGAIN)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc != 1) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc < 0) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_UNKNOWN_ERROR); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Lock(sslMutex *pMutex) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 newValue; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Lock(pMutex); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newValue = PR_ATOMIC_INCREMENT(&pMutex->u.pipeStr.nWaiters); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do Memory Barrier here. */ 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newValue > 1) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cc; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (cc < 0 && errno == EINTR); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc != 1) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc < 0) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_UNKNOWN_ERROR); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Using Atomic operations requires the use of a memory barrier instruction 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** on PowerPC, Sparc, and Alpha. NSPR's PR_Atomic functions do not perform 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** them, and NSPR does not provide a function that does them (e.g. PR_Barrier). 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** So, we don't use them on those platforms. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Unlock(sslMutex *pMutex) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cc; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c = 1; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (cc < 0 && (errno == EINTR || errno == EAGAIN)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc != 1) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc < 0) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_UNKNOWN_ERROR); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Lock(sslMutex *pMutex) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cc; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char c; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Lock(pMutex); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (cc < 0 && errno == EINTR); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc != 1) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cc < 0) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_UNKNOWN_ERROR); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(WIN32) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win32err.h" 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* on Windows, we need to find the optimal type of locking mechanism to use 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for the sslMutex. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) There are 3 cases : 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1) single-process, use a PRLock, as for all other platforms 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2) Win95 multi-process, use a Win32 mutex 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3) on WINNT multi-process, use a PRLock + a Win32 mutex 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus sslMutex_2LevelInit(sslMutex *sem) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* the following adds a PRLock to sslMutex . This is done in each 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process of a multi-process server and is only needed on WINNT, if 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using fibers. We can't tell if native threads or fibers are used, so 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) we always do it on WINNT 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(sem); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sem) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we need to reset the sslLock in the children or the single_process init 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function below will assert */ 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sem->u.sslLock = NULL; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Init(sem); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus sslMutex_2LevelDestroy(sslMutex *sem) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Destroy(sem); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Init(sslMutex *pMutex, int shared) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus retvalue; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hMutex; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_ATTRIBUTES attributes = 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 || 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx == INVALID_HANDLE_VALUE) ); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->isMultiProcess = (PRBool)(shared != 0); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Init(pMutex); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we need a lock on WINNT for fibers in the parent process */ 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retvalue = sslMutex_2LevelInit(pMutex); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SECSuccess != retvalue) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 && 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hMutex != INVALID_HANDLE_VALUE)) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attributes.bInheritHandle = (shared ? TRUE : FALSE); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hMutex = CreateMutex(&attributes, FALSE, NULL); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hMutex == NULL) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hMutex = INVALID_HANDLE_VALUE; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_win32_map_default_error(GetLastError()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx = hMutex; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hMutex; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int retvalue = SECSuccess; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Destroy(pMutex); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* multi-process mode */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* on NT, get rid of the PRLock used for fibers within a process */ 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retvalue = sslMutex_2LevelDestroy(pMutex); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT( pMutex->u.sslMutx != 0 && 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx != INVALID_HANDLE_VALUE); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || hMutex == INVALID_HANDLE_VALUE) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = CloseHandle(hMutex); /* ignore error */ 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!processLocal && rv) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rv) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_win32_map_default_error(GetLastError()); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retvalue = SECFailure; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return retvalue; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Unlock(sslMutex *pMutex) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL success = FALSE; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hMutex; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0 ); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex->u.sslMutx != 0 && 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx != INVALID_HANDLE_VALUE); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hMutex == INVALID_HANDLE_VALUE) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = ReleaseMutex(hMutex); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_win32_map_default_error(GetLastError()); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* release PRLock for other fibers in the process */ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Lock(sslMutex *pMutex) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hMutex; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD event; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD lastError; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus retvalue = SECSuccess; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex != 0); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Lock(pMutex); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WINNT 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* lock first to preserve from other threads/fibers 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in the same process */ 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retvalue = single_process_sslMutex_Lock(pMutex); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex->u.sslMutx != 0 && 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->u.sslMutx != INVALID_HANDLE_VALUE); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 || 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hMutex == INVALID_HANDLE_VALUE) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* what else ? */ 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* acquire the mutex to be the only owner accross all other processes */ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event = WaitForSingleObject(hMutex, INFINITE); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_OBJECT_0: 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_ABANDONED: 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECSuccess; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_TIMEOUT: 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(WAIT_IO_COMPLETION) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_IO_COMPLETION: 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: /* should never happen. nothing we can do. */ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(!("WaitForSingleObject returned invalid value.")); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_UNKNOWN_ERROR); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_FAILED: /* failure returns this */ 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lastError = GetLastError(); /* for debugging */ 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_win32_map_default_error(lastError); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (! (SECSuccess == retvalue && SECSuccess == rv)) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(XP_UNIX) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unix_err.h" 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Init(sslMutex *pMutex, int shared) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->isMultiProcess = (PRBool)(shared != 0); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Init(pMutex); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = sem_init(&pMutex->u.sem, shared, 1); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv < 0 && errno == EINTR); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Destroy(pMutex); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* semaphores are global resources. See SEM_DESTROY(3) man page */ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processLocal) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = sem_destroy(&pMutex->u.sem); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv < 0 && errno == EINTR); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Unlock(sslMutex *pMutex) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = sem_post(&pMutex->u.sem); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv < 0 && errno == EINTR); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Lock(sslMutex *pMutex) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Lock(pMutex); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = sem_wait(&pMutex->u.sem); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv < 0 && errno == EINTR); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv < 0) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nss_MD_unix_map_default_error(errno); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Init(sslMutex *pMutex, int shared) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMutex->isMultiProcess = (PRBool)(shared != 0); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Init(pMutex); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!("sslMutex_Init not implemented for multi-process applications !")); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Destroy(pMutex); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!("sslMutex_Destroy not implemented for multi-process applications !")); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Unlock(sslMutex *pMutex) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Unlock(pMutex); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!("sslMutex_Unlock not implemented for multi-process applications !")); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslMutex_Lock(sslMutex *pMutex) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PR_ASSERT(pMutex); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_FALSE == pMutex->isMultiProcess) { 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return single_process_sslMutex_Lock(pMutex); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!("sslMutex_Lock not implemented for multi-process applications !")); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 641