summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2001-06-12 01:10:01 +0000
committernelsonb%netscape.com <devnull@localhost>2001-06-12 01:10:01 +0000
commit2dd099ed5bd73a653f3c346dcfe0738e08386e02 (patch)
treea6ce2e03196b7b9b18898c2d6bf20e2147b17aed
parent64ce270ec75bdaf28ceb2da81bb6de856a74e895 (diff)
downloadnss-hg-2dd099ed5bd73a653f3c346dcfe0738e08386e02.tar.gz
Use NSPR's Atomic increment and decrement functions in the simulated
Posix semaphore code to make the non-contention case really fast. Modified Files: sslmutex.c sslmutex.h
-rw-r--r--security/nss/lib/ssl/sslmutex.c111
-rw-r--r--security/nss/lib/ssl/sslmutex.h6
2 files changed, 66 insertions, 51 deletions
diff --git a/security/nss/lib/ssl/sslmutex.c b/security/nss/lib/ssl/sslmutex.c
index 7c021ffd7..1000a3f3b 100644
--- a/security/nss/lib/ssl/sslmutex.c
+++ b/security/nss/lib/ssl/sslmutex.c
@@ -43,6 +43,7 @@
#include <string.h>
#include <errno.h>
#include "unix_err.h"
+#include "pratom.h"
#define SSL_MUTEX_MAGIC 0xfeedfd
#define NONBLOCKING_POSTS 1 /* maybe this is faster */
@@ -75,108 +76,118 @@ SECStatus
sslMutex_Init(sslMutex *pMutex, int shared)
{
int err;
- int mPipes[3];
- char c = 1;
- memset(pMutex, -1, sizeof *pMutex);
- err = pipe(mPipes);
+ pMutex->mPipes[0] = -1;
+ pMutex->mPipes[1] = -1;
+ pMutex->mPipes[2] = -1;
+ pMutex->nWaiters = 0;
+
+ err = pipe(pMutex->mPipes);
if (err) {
return err;
}
/* close-on-exec is false by default */
if (!shared) {
- err = fcntl(mPipes[0], F_SETFD, FD_CLOEXEC);
+ err = fcntl(pMutex->mPipes[0], F_SETFD, FD_CLOEXEC);
if (err)
goto loser;
- err = fcntl(mPipes[1], F_SETFD, FD_CLOEXEC);
+ err = fcntl(pMutex->mPipes[1], F_SETFD, FD_CLOEXEC);
if (err)
goto loser;
}
#if NONBLOCKING_POSTS
- err = setNonBlocking(mPipes[1], 1);
+ err = setNonBlocking(pMutex->mPipes[1], 1);
if (err)
goto loser;
#endif
+ /* Pipe starts out empty */
- do {
- err = write(mPipes[1], &c, 1);
- } while (err < 0 && (errno == EINTR || errno == EAGAIN));
- if (0 > err)
- goto loser;
-
- mPipes[2] = SSL_MUTEX_MAGIC;
+ pMutex->mPipes[2] = SSL_MUTEX_MAGIC;
- memcpy(pMutex, mPipes, sizeof mPipes);
return SECSuccess;
loser:
nss_MD_unix_map_default_error(errno);
- close(mPipes[0]);
- close(mPipes[1]);
+ close(pMutex->mPipes[0]);
+ close(pMutex->mPipes[1]);
return SECFailure;
}
SECStatus
sslMutex_Destroy(sslMutex *pMutex)
{
- int * mPipes = (int *)pMutex;
- if (mPipes[2] != SSL_MUTEX_MAGIC) {
+ if (pMutex->mPipes[2] != SSL_MUTEX_MAGIC) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
- close(mPipes[0]);
- close(mPipes[1]);
- memset(pMutex, -1, sizeof *pMutex);
+ close(pMutex->mPipes[0]);
+ close(pMutex->mPipes[1]);
+
+ pMutex->mPipes[0] = -1;
+ pMutex->mPipes[1] = -1;
+ pMutex->mPipes[2] = -1;
+ pMutex->nWaiters = 0;
+
return SECSuccess;
}
SECStatus
sslMutex_Unlock(sslMutex *pMutex)
{
- int * mPipes = (int *)pMutex;
- int cc;
- char c = 1;
+ PRInt32 oldValue;
- if (mPipes[2] != SSL_MUTEX_MAGIC) {
+ if (pMutex->mPipes[2] != SSL_MUTEX_MAGIC) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
- do {
- cc = write(mPipes[1], &c, 1);
- } while (cc < 0 && (errno == EINTR || errno == EAGAIN));
- if (cc == 1)
- return SECSuccess;
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
+ /* Do Memory Barrier here. */
+ oldValue = PR_AtomicDecrement(&pMutex->nWaiters);
+ if (oldValue > 1) {
+ int cc;
+ char c = 1;
+ do {
+ cc = write(pMutex->mPipes[1], &c, 1);
+ } while (cc < 0 && (errno == EINTR || errno == EAGAIN));
+ if (cc != 1) {
+ if (cc < 0)
+ nss_MD_unix_map_default_error(errno);
+ else
+ PORT_SetError(PR_UNKNOWN_ERROR);
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
}
SECStatus
sslMutex_Lock(sslMutex *pMutex)
{
- int * mPipes = (int *)pMutex;
- int cc;
- char c;
+ PRInt32 oldValue;
- if (mPipes[2] != SSL_MUTEX_MAGIC) {
+ if (pMutex->mPipes[2] != SSL_MUTEX_MAGIC) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
- do {
- cc = read(mPipes[0], &c, 1);
- } while (cc < 0 && errno == EINTR);
- if (cc == 1)
- return SECSuccess;
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
+ oldValue = PR_AtomicDecrement(&pMutex->nWaiters);
+ /* Do Memory Barrier here. */
+ if (oldValue > 0) {
+ int cc;
+ char c;
+ do {
+ cc = read(pMutex->mPipes[0], &c, 1);
+ } while (cc < 0 && errno == EINTR);
+ if (cc != 1) {
+ if (cc < 0)
+ nss_MD_unix_map_default_error(errno);
+ else
+ PORT_SetError(PR_UNKNOWN_ERROR);
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
}
#elif defined(WIN32)
diff --git a/security/nss/lib/ssl/sslmutex.h b/security/nss/lib/ssl/sslmutex.h
index a02c48cf5..38b7916e9 100644
--- a/security/nss/lib/ssl/sslmutex.h
+++ b/security/nss/lib/ssl/sslmutex.h
@@ -63,8 +63,12 @@ typedef int sslPID;
#elif defined(LINUX) || defined(AIX)
#include <sys/types.h>
+#include "prtypes.h"
-typedef struct { int ps[3]; } sslMutex;
+typedef struct {
+ int mPipes[3];
+ PRInt32 nWaiters;
+} sslMutex;
typedef pid_t sslPID;
#elif defined(XP_UNIX) /* other types of Unix */