summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2hg <devnull@localhost>2001-08-30 05:30:45 +0000
committercvs2hg <devnull@localhost>2001-08-30 05:30:45 +0000
commitb173c8eecc91129873ca369542b77eb1d32173e2 (patch)
treed7ca6379e0ba8895106c05b51d17fbef776ce043
parentf7b843b8dec17be6d612b30c52e39cfb35e62848 (diff)
downloadnspr-hg-PSM_2_2_DEV_20010918_BRANCH.tar.gz
fixup commit for branch 'PSM_2_2_DEV_20010918_BRANCH'PSM_2_2_DEV_20010918_BRANCH
-rwxr-xr-xconfig/nspr-config.in2
-rw-r--r--config/prdepend.h1
-rw-r--r--pr/include/md/_pth.h46
-rw-r--r--pr/include/private/primpl.h2
-rw-r--r--pr/src/md/unix/unix_errors.c5
-rw-r--r--pr/src/misc/prnetdb.c2
-rw-r--r--pr/src/pthreads/ptsynch.c41
7 files changed, 77 insertions, 22 deletions
diff --git a/config/nspr-config.in b/config/nspr-config.in
index d6776558..daae782d 100755
--- a/config/nspr-config.in
+++ b/config/nspr-config.in
@@ -107,7 +107,7 @@ if test "$echo_libs" = "yes"; then
fi
os_ldflags="@LDFLAGS@"
for i in $os_ldflags ; do
- if echo $i | grep ^-L >/dev/null; then
+ if echo $i | grep \^-L >/dev/null; then
libdirs="$libdirs $i"
fi
done
diff --git a/config/prdepend.h b/config/prdepend.h
index 8bebd56b..28c1b139 100644
--- a/config/prdepend.h
+++ b/config/prdepend.h
@@ -39,3 +39,4 @@
*/
#error "Do not include this header file."
+
diff --git a/pr/include/md/_pth.h b/pr/include/md/_pth.h
index 997f32f7..be65ab74 100644
--- a/pr/include/md/_pth.h
+++ b/pr/include/md/_pth.h
@@ -96,6 +96,52 @@
#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), &(a))
#endif
+/* The pthreads standard does not specify an invalid value for the
+ * pthread_t handle. (0 is usually an invalid pthread identifier
+ * but there are exceptions, for example, DG/UX.) These macros
+ * define a way to set the handle to or compare the handle with an
+ * invalid identifier. These macros are not portable and may be
+ * more of a problem as we adapt to more pthreads implementations.
+ * They are only used in the PRMonitor functions. Do not use them
+ * in new code.
+ *
+ * Unfortunately some of our clients depend on certain properties
+ * of our PRMonitor implementation, preventing us from replacing
+ * it by a portable implementation.
+ * - High-performance servers like the fact that PR_EnterMonitor
+ * only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock.
+ * (A portable implementation would use a PRLock and a PRCondVar
+ * to implement the recursive lock in a monitor and call both
+ * PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.)
+ * Unfortunately this forces us to read the monitor owner field
+ * without holding a lock.
+ * - One way to make it safe to read the monitor owner field
+ * without holding a lock is to make that field a PRThread*
+ * (one should be able to read a pointer with a single machine
+ * instruction). However, PR_GetCurrentThread calls calloc if
+ * it is called by a thread that was not created by NSPR. The
+ * malloc tracing tools in the Mozilla client use PRMonitor for
+ * locking in their malloc, calloc, and free functions. If
+ * PR_EnterMonitor calls any of these functions, infinite
+ * recursion ensues.
+ */
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \
+ memset(&(t), 0, sizeof(pthread_t))
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \
+ (!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t)))
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st)
+#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \
+ || defined(HPUX) || defined(LINUX) || defined(FREEBSD) \
+ || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
+ || defined(VMS) || defined(NTO) || defined(RHAPSODY)
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) (t) = 0
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) (t) == 0
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st)
+#else
+#error "pthreads is not supported for this architecture"
+#endif
+
#if defined(_PR_DCETHREADS)
#define _PT_PTHREAD_ATTR_INIT pthread_attr_create
#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_delete
diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h
index eb1dd716..16f2d23c 100644
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -1450,7 +1450,7 @@ struct PRMonitor {
const char* name; /* monitor name for debugging */
#if defined(_PR_PTHREADS)
PRLock lock; /* the lock structure */
- PRThread *owner; /* the owner of the lock or NULL */
+ pthread_t owner; /* the owner of the lock or invalid */
PRCondVar *cvar; /* condition variable queue */
#else /* defined(_PR_PTHREADS) */
PRCondVar *cvar; /* associated lock and condition variable queue */
diff --git a/pr/src/md/unix/unix_errors.c b/pr/src/md/unix/unix_errors.c
index 7164675b..1ce52e68 100644
--- a/pr/src/md/unix/unix_errors.c
+++ b/pr/src/md/unix/unix_errors.c
@@ -383,9 +383,14 @@ void _MD_unix_map_rmdir_error(int err)
PRErrorCode prError;
switch (err) {
+ /*
+ * On AIX 4.3, ENOTEMPTY is defined as EEXIST.
+ */
+#if ENOTEMPTY != EEXIST
case ENOTEMPTY:
prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
break;
+#endif
case EEXIST:
prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
break;
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index 22a15dae..c8d33900 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -84,7 +84,7 @@ PRLock *_pr_dnsLock = NULL;
* an int.
*/
-#if defined(SOLARIS) \
+#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \
|| (defined(LINUX) && defined(_REENTRANT) \
&& !(defined(__GLIBC__) && __GLIBC__ >= 2))
#define _PR_HAVE_GETPROTO_R
diff --git a/pr/src/pthreads/ptsynch.c b/pr/src/pthreads/ptsynch.c
index ecf69a1a..4400e8df 100644
--- a/pr/src/pthreads/ptsynch.c
+++ b/pr/src/pthreads/ptsynch.c
@@ -444,6 +444,8 @@ PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void)
rv = _PT_PTHREAD_MUTEX_INIT(mon->lock.mutex, _pt_mattr);
PR_ASSERT(0 == rv);
+ _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
+
mon->cvar = cvar;
rv = _PT_PTHREAD_COND_INIT(mon->cvar->cv, _pt_cvar_attr);
PR_ASSERT(0 == rv);
@@ -484,42 +486,43 @@ PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon)
*/
PR_IMPLEMENT(PRInt32) PR_GetMonitorEntryCount(PRMonitor *mon)
{
- PRThread *self = PR_GetCurrentThread();
- if (mon->owner == self)
+ pthread_t self = pthread_self();
+ if (pthread_equal(mon->owner, self))
return mon->entryCount;
return 0;
}
PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
{
- PRThread *self = PR_GetCurrentThread();
+ pthread_t self = pthread_self();
PR_ASSERT(mon != NULL);
/*
- * This is safe only if mon->owner (a PRThread*) can be
- * read in one instruction.
+ * This is safe only if mon->owner (a pthread_t) can be
+ * read in one instruction. Perhaps mon->owner should be
+ * a "PRThread *"?
*/
- if (mon->owner != self)
+ if (!pthread_equal(mon->owner, self))
{
PR_Lock(&mon->lock);
/* and now I have the lock */
PR_ASSERT(0 == mon->entryCount);
- PR_ASSERT(NULL == mon->owner);
- mon->owner = self;
+ PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner));
+ _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner);
}
mon->entryCount += 1;
} /* PR_EnterMonitor */
PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
{
- PRThread *self = PR_GetCurrentThread();
+ pthread_t self = pthread_self();
PR_ASSERT(mon != NULL);
/* The lock better be that - locked */
PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
/* we'd better be the owner */
- PR_ASSERT(mon->owner == self);
- if (mon->owner != self)
+ PR_ASSERT(pthread_equal(mon->owner, self));
+ if (!pthread_equal(mon->owner, self))
return PR_FAILURE;
/* if it's locked and we have it, then the entries should be > 0 */
@@ -528,7 +531,7 @@ PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
if (mon->entryCount == 0)
{
/* and if it transitioned to zero - unlock */
- mon->owner = NULL; /* make the owner unknown */
+ _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); /* make the owner unknown */
PR_Unlock(&mon->lock);
}
return PR_SUCCESS;
@@ -538,7 +541,7 @@ PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
{
PRStatus rv;
PRInt16 saved_entries;
- PRThread *saved_owner;
+ pthread_t saved_owner;
PR_ASSERT(mon != NULL);
/* we'd better be locked */
@@ -546,19 +549,19 @@ PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
/* and the entries better be positive */
PR_ASSERT(mon->entryCount > 0);
/* and it better be by us */
- PR_ASSERT(mon->owner == PR_GetCurrentThread());
+ PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
/* tuck these away 'till later */
saved_entries = mon->entryCount;
mon->entryCount = 0;
- saved_owner = mon->owner;
- mon->owner = NULL;
+ _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);
+ _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
rv = PR_WaitCondVar(mon->cvar, timeout);
/* reinstate the intresting information */
mon->entryCount = saved_entries;
- mon->owner = saved_owner;
+ _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);
return rv;
} /* PR_Wait */
@@ -571,7 +574,7 @@ PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon)
/* and the entries better be positive */
PR_ASSERT(mon->entryCount > 0);
/* and it better be by us */
- PR_ASSERT(mon->owner == PR_GetCurrentThread());
+ PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
pt_PostNotifyToCvar(mon->cvar, PR_FALSE);
@@ -586,7 +589,7 @@ PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon)
/* and the entries better be positive */
PR_ASSERT(mon->entryCount > 0);
/* and it better be by us */
- PR_ASSERT(mon->owner == PR_GetCurrentThread());
+ PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
pt_PostNotifyToCvar(mon->cvar, PR_TRUE);