summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc <devnull@localhost>1998-04-28 22:43:48 +0000
committerwtc <devnull@localhost>1998-04-28 22:43:48 +0000
commitc6d8300952bf5b808ef70c986a7351d0a33804c1 (patch)
tree8e24d8847da182936c808c241e64c617024abf8a
parentece7a202bbd2c155f2049cbf79648fd68035a710 (diff)
downloadnspr-hg-c6d8300952bf5b808ef70c986a7351d0a33804c1.tar.gz
Merged NSPRPUB_19980421_BRANCH to the main trunk.
-rw-r--r--lib/ds/plevent.c3
-rw-r--r--lib/ds/plevent.h7
-rw-r--r--lib/msgc/src/prmsgc.c7
-rw-r--r--lib/prstreams/prstrms.cpp2
-rw-r--r--pr/include/md/_aix.h29
-rw-r--r--pr/include/md/_freebsd.h36
-rw-r--r--pr/include/md/_irix.cfg3
-rw-r--r--pr/include/md/_irix.h7
-rw-r--r--pr/include/md/_linux.h46
-rw-r--r--pr/include/md/_macos.h8
-rw-r--r--pr/include/md/_ncr.cfg1
-rw-r--r--pr/include/md/_os2.cfg3
-rw-r--r--pr/include/md/_os2.h51
-rw-r--r--pr/include/md/_os2_errors.h4
-rw-r--r--pr/include/md/_osf1.cfg1
-rw-r--r--pr/include/md/_pcos.h6
-rw-r--r--pr/include/md/_pth.h7
-rw-r--r--pr/include/md/_reliantunix.cfg1
-rw-r--r--pr/include/md/_scoos.cfg1
-rw-r--r--pr/include/md/_unix_errors.h3
-rw-r--r--pr/include/md/_unixos.h54
-rw-r--r--pr/include/md/_unixware.cfg1
-rw-r--r--pr/include/md/_win32_errors.h70
-rw-r--r--pr/include/md/_win95.h22
-rw-r--r--pr/include/md/_winnt.h8
-rw-r--r--pr/include/obsolete/protypes.h4
-rw-r--r--pr/include/prbit.h40
-rw-r--r--pr/include/prdtoa.h10
-rw-r--r--pr/include/prinet.h8
-rw-r--r--pr/include/prio.h89
-rw-r--r--pr/include/private/pprio.h27
-rw-r--r--pr/include/private/primpl.h131
-rw-r--r--pr/include/prmwait.h4
-rw-r--r--pr/include/prtypes.h19
-rw-r--r--pr/include/prwin16.h2
-rw-r--r--pr/src/io/pprmwait.h4
-rw-r--r--pr/src/io/prfile.c11
-rw-r--r--pr/src/io/prio.c33
-rw-r--r--pr/src/io/prlayer.c26
-rw-r--r--pr/src/io/prmapopt.c215
-rw-r--r--pr/src/io/prprf.c4
-rw-r--r--pr/src/io/prscanf.c2
-rw-r--r--pr/src/io/prsocket.c169
-rw-r--r--pr/src/md/mac/macsockotpt.c2
-rw-r--r--pr/src/md/os2/os2cv.c8
-rw-r--r--pr/src/md/os2/os2gc.c2
-rw-r--r--pr/src/md/os2/os2io.c10
-rw-r--r--pr/src/md/os2/os2misc.c6
-rw-r--r--pr/src/md/os2/os2thred.c4
-rw-r--r--pr/src/md/unix/aix.c49
-rw-r--r--pr/src/md/unix/freebsd.c132
-rw-r--r--pr/src/md/unix/irix.c71
-rw-r--r--pr/src/md/unix/linux.c132
-rw-r--r--pr/src/md/unix/os_AIX.s1
-rw-r--r--pr/src/md/unix/os_BSD_386_2.s1
-rw-r--r--pr/src/md/unix/os_ReliantUNIX.s1
-rw-r--r--pr/src/md/unix/os_SunOS_ultrasparc.s2
-rw-r--r--pr/src/md/unix/unix.c535
-rw-r--r--pr/src/md/unix/unix_errors.c20
-rw-r--r--pr/src/md/windows/ntio.c2
-rw-r--r--pr/src/md/windows/ntmisc.c50
-rw-r--r--pr/src/md/windows/ntthread.c50
-rw-r--r--pr/src/md/windows/w16null.c2
-rw-r--r--pr/src/md/windows/w95thred.c18
-rw-r--r--pr/src/md/windows/win32_errors.c1
-rw-r--r--pr/src/misc/pratom.c18
-rw-r--r--pr/src/misc/prdtoa.c684
-rw-r--r--pr/src/misc/prinit.c5
-rw-r--r--pr/src/misc/prnetdb.c29
-rw-r--r--pr/src/misc/prtime.c25
-rw-r--r--pr/src/pthreads/ptio.c912
-rw-r--r--pr/src/pthreads/ptsynch.c52
-rw-r--r--pr/src/pthreads/ptthread.c49
-rw-r--r--pr/src/threads/combined/prucv.c10
-rw-r--r--pr/src/threads/combined/prulock.c30
-rw-r--r--pr/src/threads/combined/pruthr.c46
-rw-r--r--pr/src/threads/prcthr.c31
-rw-r--r--pr/src/threads/prdump.c2
-rw-r--r--pr/tests/accept.c33
-rw-r--r--pr/tests/alarm.c8
-rw-r--r--pr/tests/atomic.c9
-rw-r--r--pr/tests/attach.c11
-rw-r--r--pr/tests/cltsrv.c58
-rw-r--r--pr/tests/intrupt.c4
-rw-r--r--pr/tests/io_timeout.c4
-rw-r--r--pr/tests/ipv6.c1
-rw-r--r--pr/tests/layer.c93
-rw-r--r--pr/tests/many_cv.c26
-rw-r--r--pr/tests/nonblock.c8
-rw-r--r--pr/tests/poll_nm.c12
-rw-r--r--pr/tests/poll_to.c8
-rw-r--r--pr/tests/priotest.c146
-rw-r--r--pr/tests/ranfile.c2
-rw-r--r--pr/tests/sel_spd.c8
-rw-r--r--pr/tests/selct_nm.c13
-rw-r--r--pr/tests/selct_to.c8
-rw-r--r--pr/tests/servr_kk.c8
-rw-r--r--pr/tests/servr_ku.c8
-rw-r--r--pr/tests/servr_uk.c8
-rw-r--r--pr/tests/servr_uu.c8
-rw-r--r--pr/tests/socket.c24
-rw-r--r--pr/tests/suspend.c108
-rw-r--r--pr/tests/testfile.c3
-rw-r--r--pr/tests/thruput.c8
-rw-r--r--pr/tests/tmocon.c2
-rw-r--r--pr/tests/udpsrv.c12
-rw-r--r--pr/tests/w16gui/poppad.rc16
-rw-r--r--pr/tests/yield.c3
-rw-r--r--tools/httpget.c4
109 files changed, 2506 insertions, 2329 deletions
diff --git a/lib/ds/plevent.c b/lib/ds/plevent.c
index 46c1c609..d164955e 100644
--- a/lib/ds/plevent.c
+++ b/lib/ds/plevent.c
@@ -15,9 +15,6 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
-#if defined(WIN16)
-#include <windows.h>
-#endif
#include "plevent.h"
#include "prmem.h"
#include "prcmon.h"
diff --git a/lib/ds/plevent.h b/lib/ds/plevent.h
index d8361144..81c7340e 100644
--- a/lib/ds/plevent.h
+++ b/lib/ds/plevent.h
@@ -170,6 +170,13 @@ and to ensure that no more events will be delivered for that owner.
#include "prthread.h"
#include "prmon.h"
+/* For HWND */
+#ifdef _WIN32
+#include <windef.h>
+#elif defined(WIN16)
+#include <windows.h>
+#endif
+
PR_BEGIN_EXTERN_C
/* Typedefs */
diff --git a/lib/msgc/src/prmsgc.c b/lib/msgc/src/prmsgc.c
index f01d2cd1..650ebd6d 100644
--- a/lib/msgc/src/prmsgc.c
+++ b/lib/msgc/src/prmsgc.c
@@ -21,6 +21,11 @@
#include <stdarg.h>
#include <time.h>
+#ifdef WIN32
+#include <windef.h>
+#include <winbase.h>
+#endif
+
#include "prclist.h"
#include "prbit.h"
@@ -2365,7 +2370,7 @@ PR_TraceRoot()
/******************************************************************************/
-#if defined(DEBUG) && defined(_WIN32)
+#if defined(DEBUG) && defined(WIN32)
static void DumpApplicationHeap(FILE *out, HANDLE heap)
{
PROCESS_HEAP_ENTRY entry;
diff --git a/lib/prstreams/prstrms.cpp b/lib/prstreams/prstrms.cpp
index 8dd71fc6..473b70bf 100644
--- a/lib/prstreams/prstrms.cpp
+++ b/lib/prstreams/prstrms.cpp
@@ -21,9 +21,7 @@
*/
#include "prstrms.h"
-#ifdef SVR4
#include <string.h> // memmove
-#endif
//
// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.
diff --git a/pr/include/md/_aix.h b/pr/include/md/_aix.h
index e1a1643a..7ea19b7f 100644
--- a/pr/include/md/_aix.h
+++ b/pr/include/md/_aix.h
@@ -38,14 +38,14 @@
*/
#define PR_LINKER_ARCH "aix"
-#define _PR_SI_SYSNAME "AIX"
-#define _PR_SI_ARCHITECTURE "rs6000"
-#define PR_DLL_SUFFIX ".so"
+#define _PR_SI_SYSNAME "AIX"
+#define _PR_SI_ARCHITECTURE "rs6000"
+#define PR_DLL_SUFFIX ".so"
-#define _PR_VMBASE 0x30000000
-#define _PR_STACK_VMBASE 0x50000000
+#define _PR_VMBASE 0x30000000
+#define _PR_STACK_VMBASE 0x50000000
#define _MD_DEFAULT_STACK_SIZE 65536L
-#define _MD_MMAP_FLAGS MAP_PRIVATE
+#define _MD_MMAP_FLAGS MAP_PRIVATE
#define NEED_TIME_R
#undef HAVE_STACK_GROWING_UP
@@ -53,11 +53,18 @@
#undef HAVE_WEAK_MALLOC_SYMBOLS
#define HAVE_DLL
#define USE_DLFCN
-
-#undef _PR_HAVE_ATOMIC_OPS
-
-#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
-#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
+#define _PR_HAVE_SOCKADDR_LEN
+
+#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
+
+/* The atomic operations */
+#include <sys/atomic_op.h>
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1)
+#define _MD_ATOMIC_DECREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1)
+#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval)
#define USE_SETJMP
diff --git a/pr/include/md/_freebsd.h b/pr/include/md/_freebsd.h
index 1d8a5240..916c11c2 100644
--- a/pr/include/md/_freebsd.h
+++ b/pr/include/md/_freebsd.h
@@ -36,6 +36,7 @@
#undef HAVE_STACK_GROWING_UP
#define HAVE_DLL
#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
#define USE_SETJMP
@@ -156,41 +157,6 @@ extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
*/
#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
-#if defined(_PR_NEED_FAKE_POLL)
-
-/*
- * XXX: FreeBSD2 doesn't have poll(), but our pthreads code calls poll().
- * As a temporary measure, I implemented a fake poll() using select().
- * Here are the struct and macro definitions copied from sys/poll.h
- * on Solaris 2.5.
- */
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-/* poll events */
-
-#define POLLIN 0x0001 /* fd is readable */
-#define POLLPRI 0x0002 /* high priority info at fd */
-#define POLLOUT 0x0004 /* fd is writeable (won't block) */
-#define POLLRDNORM 0x0040 /* normal data is readable */
-#define POLLWRNORM POLLOUT
-#define POLLRDBAND 0x0080 /* out-of-band data is readable */
-#define POLLWRBAND 0x0100 /* out-of-band data is writeable */
-
-#define POLLNORM POLLRDNORM
-
-#define POLLERR 0x0008 /* fd has error condition */
-#define POLLHUP 0x0010 /* fd has been hung up on */
-#define POLLNVAL 0x0020 /* invalid pollfd entry */
-
-extern int poll(struct pollfd *, unsigned long, int);
-
-#endif /* _PR_NEED_FAKE_POLL */
-
/* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't
want to be including that.. */
#ifndef INADDR_LOOPBACK
diff --git a/pr/include/md/_irix.cfg b/pr/include/md/_irix.cfg
index b9873fcb..2070760b 100644
--- a/pr/include/md/_irix.cfg
+++ b/pr/include/md/_irix.cfg
@@ -78,6 +78,9 @@
#define HAVE_ALIGNED_DOUBLES
#define HAVE_ALIGNED_LONGLONGS
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+
#ifndef NO_NSPR_10_SUPPORT
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
diff --git a/pr/include/md/_irix.h b/pr/include/md/_irix.h
index 405dd03c..694b809b 100644
--- a/pr/include/md/_irix.h
+++ b/pr/include/md/_irix.h
@@ -131,8 +131,8 @@ PR_EXTERN(struct PRThread*) _MD_get_attached_thread(void);
#define _MD_ATTACH_THREAD(threadp)
-#define _MD_SAVE_ERRNO(_thread)
-#define _MD_RESTORE_ERRNO(_thread)
+#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode;
extern struct _PRCPU *_pr_primordialCPU;
extern usema_t *_pr_irix_exit_sem;
@@ -216,6 +216,9 @@ struct _MDThread {
PRInt32 id;
PRInt32 suspending_id;
int errcode;
+ PRStatus *creation_status; /* points to the variable in which
+ * a newly created child thread is
+ * to store its creation status */
};
struct _MDThreadStack {
diff --git a/pr/include/md/_linux.h b/pr/include/md/_linux.h
index 03b526e3..a7ac6326 100644
--- a/pr/include/md/_linux.h
+++ b/pr/include/md/_linux.h
@@ -56,14 +56,10 @@
#undef USE_DLFCN
#endif
-#if !defined(MACLINUX) && !defined(NEED_TIME_R)
+#if !defined(MKLINUX) && !defined(NEED_TIME_R)
#define NEED_TIME_R
#endif
-#if defined(_PR_PTHREADS) && !(defined(__GLIBC__) && __GLIBC__ >= 2)
-#define _PR_NEED_FAKE_POLL
-#endif
-
#define USE_SETJMP
#ifdef _PR_PTHREADS
@@ -250,40 +246,12 @@ extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
*/
#define _MD_SELECT __select
-#if defined(_PR_NEED_FAKE_POLL)
-
-/*
- * XXX: Linux doesn't have poll(), but our pthreads code calls poll().
- * As a temporary measure, I implemented a fake poll() using select().
- * Here are the struct and macro definitions copied from sys/poll.h
- * on Solaris 2.5.
- */
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-/* poll events */
-
-#define POLLIN 0x0001 /* fd is readable */
-#define POLLPRI 0x0002 /* high priority info at fd */
-#define POLLOUT 0x0004 /* fd is writeable (won't block) */
-#define POLLRDNORM 0x0040 /* normal data is readable */
-#define POLLWRNORM POLLOUT
-#define POLLRDBAND 0x0080 /* out-of-band data is readable */
-#define POLLWRBAND 0x0100 /* out-of-band data is writeable */
-
-#define POLLNORM POLLRDNORM
-
-#define POLLERR 0x0008 /* fd has error condition */
-#define POLLHUP 0x0010 /* fd has been hung up on */
-#define POLLNVAL 0x0020 /* invalid pollfd entry */
-
-extern int poll(struct pollfd *, unsigned long, int);
-
-#endif /* _PR_NEED_FAKE_POLL */
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
+ int timeout);
+#define _MD_POLL __syscall_poll
+#endif
/* For writev() */
#include <sys/uio.h>
diff --git a/pr/include/md/_macos.h b/pr/include/md/_macos.h
index b38b5374..dae22d0a 100644
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -330,11 +330,11 @@ typedef enum IOOperation {
#define _MD_DELETE _MD_Delete
-PR_EXTERN(PRStatus) _MD_LockFile(PRInt32 osfd);
+extern PRStatus _MD_LockFile(PRInt32 osfd);
#define _MD_LOCKFILE _MD_LockFile
-PR_EXTERN(PRStatus) _MD_TLockFile(PRInt32 osfd);
+extern PRStatus _MD_TLockFile(PRInt32 osfd);
#define _MD_TLOCKFILE _MD_TLockFile
-PR_EXTERN(PRStatus) _MD_UnlockFile(PRInt32 osfd);
+extern PRStatus _MD_UnlockFile(PRInt32 osfd);
#define _MD_UNLOCKFILE _MD_UnlockFile
/*
@@ -384,7 +384,7 @@ extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, c
/*
** Netdb Related definitions
*/
-PR_EXTERN(PRStatus) _MD_gethostname(char *name, int namelen);
+extern PRStatus _MD_gethostname(char *name, int namelen);
#define _MD_GETHOSTNAME _MD_gethostname
/*
diff --git a/pr/include/md/_ncr.cfg b/pr/include/md/_ncr.cfg
index 23757a60..337b933d 100644
--- a/pr/include/md/_ncr.cfg
+++ b/pr/include/md/_ncr.cfg
@@ -71,6 +71,7 @@
#define PR_ALIGN_OF_DOUBLE 4
#define PR_ALIGN_OF_POINTER 4
+#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_os2.cfg b/pr/include/md/_os2.cfg
index 989d8d88..1271e0f1 100644
--- a/pr/include/md/_os2.cfg
+++ b/pr/include/md/_os2.cfg
@@ -76,6 +76,9 @@
#define PR_ALIGN_OF_DWORD 8
#define PR_ALIGN_OF_POINTER 4
+#define PR_BYTES_PER_WORD_LOG2 2
+#define PR_BYTES_PER_DWORD_LOG2 2
+
#ifndef NO_NSPR_10_SUPPORT
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
diff --git a/pr/include/md/_os2.h b/pr/include/md/_os2.h
index aa440567..acdf4c64 100644
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -23,7 +23,9 @@
#define INCL_DOSERRORS
#define INCL_WIN
#define INCL_WPS
+#define TID OS2TID /* global rename in OS2 H's! */
#include <os2.h>
+#undef TID /* and restore */
#include <sys/select.h>
#include "prio.h"
@@ -42,7 +44,11 @@
#undef HAVE_THREAD_AFFINITY
#define HAVE_SOCKET_REUSEADDR
#define HAVE_SOCKET_KEEPALIVE
-#define _PR_HAVE_ATOMIC_OPS
+
+/*********************************************
+/* We don't have atomic ops on OS/2 natively */
+/* #define _PR_HAVE_ATOMIC_OPS */
+/*********************************************/
#define HANDLE unsigned long
#define HINSTANCE HMODULE
@@ -59,6 +65,7 @@ typedef void (*FiberFunc)(void *);
typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS];
#define GC_VMBASE 0x40000000
#define GC_VMLIMIT 0x00FFFFFF
+typedef int (*FARPROC)();
#define _MD_MAGIC_THREAD 0x22222222
#define _MD_MAGIC_THREADSTACK 0x33333333
@@ -66,6 +73,8 @@ typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS];
#define _MD_MAGIC_DIR 0x55555555
#define _MD_MAGIC_CV 0x66666666
+#define CALLBACK
+
typedef struct _MDSemaphore
{
HEV sem;
@@ -82,7 +91,7 @@ struct _MDThread {
PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the
* wait queue of some cond var.
* PR_FALSE otherwise. */
- TID handle; /* OS/2 thread handle */
+ OS2TID handle; /* OS/2 thread handle */
void *sp; /* only valid when suspended */
PRUint32 magic; /* for debugging */
PR_CONTEXT_TYPE gcContext; /* Thread context for GC */
@@ -133,7 +142,7 @@ struct _MDNotified {
};
struct _MDLock {
- CRITICAL_SECTION mutex; /* this is recursive on NT */
+ HMTX mutex; /* this is recursive on NT */
/*
* When notifying cvars, there is no point in actually
@@ -189,6 +198,10 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE
/* --- Socket IO stuff --- */
+
+/* The ones that don't map directly may need to be re-visited... */
+#define EPIPE EBADF
+#define EIO ECONNREFUSED
#define _MD_EACCES EACCES
#define _MD_EADDRINUSE EADDRINUSE
#define _MD_EADDRNOTAVAIL EADDRNOTAVAIL
@@ -230,14 +243,10 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
#define _MD_SELECT select
#define _MD_FSYNC _PR_MD_FSYNC
-long _System InterlockedIncrement(PLONG);
-long _System InterlockedDecrement(PLONG);
-long _System InterlockedExchange(PLONG, LONG);
-
-#define _MD_INIT_ATOMIC()
-#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x)
-#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x)
-#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
+#define _MD_INIT_ATOMIC _PR_MD_INIT_ATOMIC
+#define _MD_ATOMIC_INCREMENT(x) _PR_MD_ATOMIC_INCREMENT(x)
+#define _MD_ATOMIC_DECREMENT(x) _PR_MD_ATOMIC_DECREMENT(x)
+#define _MD_ATOMIC_SET(x,y) _PR_MD_ATOMIC_SET(x, y)
#define _MD_INIT_IO _PR_MD_INIT_IO
#define _MD_TRANSMITFILE _PR_MD_TRANSMITFILE
@@ -304,10 +313,10 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
#define _PR_LOCK _MD_LOCK
#define _PR_UNLOCK _MD_UNLOCK
-#define _MD_NEW_LOCK(lock) (InitializeCriticalSection(&((lock)->mutex)),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
-#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex))
-#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex))
-#define _MD_TEST_AND_LOCK(lock) (EnterCriticalSection(&((lock)->mutex)),PR_SUCCESS)
+#define _MD_NEW_LOCK(lock) (DosCreateMutexSem(0, &((lock)->mutex), 0, 0),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
+#define _MD_FREE_LOCK(lock) DosCloseMutexSem(((lock)->mutex))
+#define _MD_LOCK(lock) DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT)
+#define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT),PR_SUCCESS)
#define _MD_UNLOCK _PR_MD_UNLOCK
/* --- lock and cv waiting --- */
@@ -376,8 +385,8 @@ extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
typedef struct __NSPR_TLS
{
- PRThread *_pr_thread_last_run;
- PRThread *_pr_currentThread;
+ struct PRThread *_pr_thread_last_run;
+ struct PRThread *_pr_currentThread;
struct _PRCPU *_pr_currentCPU;
} _NSPR_TLS;
@@ -431,7 +440,10 @@ extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
/* Some stuff for setting up thread contexts */
-typedef ULONG DWORD, *PDWORD;
+#undef DWORD
+#undef PDWORD
+typedef unsigned long DWORD;
+typedef unsigned long *PDWORD;
/* The following definitions and two structures are new in OS/2 Warp 4.0.
*/
@@ -472,7 +484,7 @@ typedef struct _CONTEXTRECORD {
#pragma pack()
#endif
-extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+extern APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
/*
#define _pr_tid (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
@@ -484,5 +496,6 @@ extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
* not emulating anything. Just mapping.
*/
#define FreeLibrary(x) DosFreeModule(x)
+#define OutputDebugString(str) ;
#endif /* nspr_os2_defs_h___ */
diff --git a/pr/include/md/_os2_errors.h b/pr/include/md/_os2_errors.h
index 34fa4c59..17b33129 100644
--- a/pr/include/md/_os2_errors.h
+++ b/pr/include/md/_os2_errors.h
@@ -20,7 +20,9 @@
#define nspr_os2_errors_h___
#include "md/_os2.h"
-#include <assert.h>
+#ifndef assert
+ #include <assert.h>
+#endif
#include <nerrno.h>
PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err);
diff --git a/pr/include/md/_osf1.cfg b/pr/include/md/_osf1.cfg
index 83208941..16bc9ac9 100644
--- a/pr/include/md/_osf1.cfg
+++ b/pr/include/md/_osf1.cfg
@@ -75,6 +75,7 @@
#define PR_ALIGN_OF_DOUBLE 8
#define PR_ALIGN_OF_POINTER 8
+#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_pcos.h b/pr/include/md/_pcos.h
index c430972c..6e325b36 100644
--- a/pr/include/md/_pcos.h
+++ b/pr/include/md/_pcos.h
@@ -69,15 +69,17 @@ typedef int PROSFD;
/*
** Undo the macro define in the Microsoft header files...
*/
+#ifndef XP_OS2 /* Uh... this seems a bit insane in itself to we OS/2 folk */
#ifdef _stat
#undef _stat
#endif
+#endif
#ifdef OS2
-PR_EXTERN(PRStatus) _MD_OS2GetHostName(char *name, PRUint32 namelen);
+extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_OS2GetHostName
#else
-PR_EXTERN(PRStatus) _MD_WindowsGetHostName(char *name, PRUint32 namelen);
+extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_WindowsGetHostName
#endif
diff --git a/pr/include/md/_pth.h b/pr/include/md/_pth.h
index fba4726c..bf0be7f7 100644
--- a/pr/include/md/_pth.h
+++ b/pr/include/md/_pth.h
@@ -194,10 +194,13 @@ PR_EXTERN(PRIntn) pt_hpux_privcheck(void);
/* Needed for garbage collection -- Look at PR_Suspend/PR_Resume implementation */
#if defined(OSF1)
#define PTHREAD_YIELD() pthread_yield_np()
-#elif defined(HPUX10_30) || defined(HPUX11) || defined(AIX4_3)
+#elif defined(HPUX10_30) || defined(HPUX11)
#define PTHREAD_YIELD() sched_yield()
-#elif (defined(AIX) && !defined(AIX4_3)) || defined(HPUX)
+#elif defined(HPUX)
#define PTHREAD_YIELD() pthread_yield()
+#elif defined(AIX)
+extern int (*_PT_aix_yield_fcn)();
+#define PTHREAD_YIELD() (*_PT_aix_yield_fcn)()
#elif defined(IRIX)
#include <time.h>
#define PTHREAD_YIELD() \
diff --git a/pr/include/md/_reliantunix.cfg b/pr/include/md/_reliantunix.cfg
index d5a71fe1..634acfe3 100644
--- a/pr/include/md/_reliantunix.cfg
+++ b/pr/include/md/_reliantunix.cfg
@@ -76,6 +76,7 @@
#define PR_ALIGN_OF_DOUBLE 8
#define PR_ALIGN_OF_POINTER 4
+#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_scoos.cfg b/pr/include/md/_scoos.cfg
index 4db48681..3f414650 100644
--- a/pr/include/md/_scoos.cfg
+++ b/pr/include/md/_scoos.cfg
@@ -71,6 +71,7 @@
#define PR_ALIGN_OF_DOUBLE 4
#define PR_ALIGN_OF_POINTER 4
+#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_unix_errors.h b/pr/include/md/_unix_errors.h
index ce1ef004..b022462c 100644
--- a/pr/include/md/_unix_errors.h
+++ b/pr/include/md/_unix_errors.h
@@ -135,6 +135,9 @@ PR_EXTERN(void) _MD_unix_map_gethostname_error(int err);
PR_EXTERN(void) _MD_unix_map_select_error(int err);
#define _PR_MD_MAP_SELECT_ERROR _MD_unix_map_select_error
+PR_EXTERN(void) _MD_unix_map_poll_error(int err);
+#define _PR_MD_MAP_POLL_ERROR _MD_unix_map_poll_error
+
PR_EXTERN(void) _MD_unix_map_flock_error(int err);
#define _PR_MD_MAP_FLOCK_ERROR _MD_unix_map_flock_error
diff --git a/pr/include/md/_unixos.h b/pr/include/md/_unixos.h
index e6d1a4f2..b82f9265 100644
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -118,11 +118,17 @@ struct _MDDir {
struct _MDCPU_Unix {
PRCList ioQ;
+ PRUint32 ioq_timeout;
+ PRInt32 ioq_max_osfd;
+ PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
fd_set fd_read_set, fd_write_set, fd_exception_set;
PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
fd_exception_cnt[_PR_MD_MAX_OSFD];
- PRUint32 ioq_timeout;
- PRInt32 ioq_max_osfd;
+#else
+ struct pollfd *ioq_pollfds;
+ int ioq_pollfds_size;
+#endif /* _PR_USE_POLL */
};
struct _PRCPU;
extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu);
@@ -137,6 +143,11 @@ extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu);
#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt)
#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout)
#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32
/*
@@ -453,4 +464,43 @@ extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+#if defined(LINUX) && defined(_PR_PTHREADS) && !(__GLIBC__ >= 2)
+#define _PR_NEED_FAKE_POLL
+#endif
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll(), but our pthreads code calls poll().
+ * As a temporary measure, I implemented a fake poll() using select().
+ * Here are the struct and macro definitions copied from sys/poll.h
+ * on Solaris 2.5.
+ */
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+/* poll events */
+
+#define POLLIN 0x0001 /* fd is readable */
+#define POLLPRI 0x0002 /* high priority info at fd */
+#define POLLOUT 0x0004 /* fd is writeable (won't block) */
+#define POLLRDNORM 0x0040 /* normal data is readable */
+#define POLLWRNORM POLLOUT
+#define POLLRDBAND 0x0080 /* out-of-band data is readable */
+#define POLLWRBAND 0x0100 /* out-of-band data is writeable */
+
+#define POLLNORM POLLRDNORM
+
+#define POLLERR 0x0008 /* fd has error condition */
+#define POLLHUP 0x0010 /* fd has been hung up on */
+#define POLLNVAL 0x0020 /* invalid pollfd entry */
+
+extern int poll(struct pollfd *, unsigned long, int);
+
+#endif /* _PR_NEED_FAKE_POLL */
+
#endif /* prunixos_h___ */
diff --git a/pr/include/md/_unixware.cfg b/pr/include/md/_unixware.cfg
index a4472415..d8261908 100644
--- a/pr/include/md/_unixware.cfg
+++ b/pr/include/md/_unixware.cfg
@@ -72,6 +72,7 @@
#define PR_ALIGN_OF_POINTER 4
#define _PR_USE_POLL
+#define _PR_POLL_AVAILABLE
#ifndef NO_NSPR_10_SUPPORT
diff --git a/pr/include/md/_win32_errors.h b/pr/include/md/_win32_errors.h
index 4a3170bb..005caee6 100644
--- a/pr/include/md/_win32_errors.h
+++ b/pr/include/md/_win32_errors.h
@@ -24,109 +24,109 @@
#include <errno.h>
-PR_EXTERN(void) _MD_win32_map_opendir_error(PRInt32 err);
+extern void _MD_win32_map_opendir_error(PRInt32 err);
#define _PR_MD_MAP_OPENDIR_ERROR _MD_win32_map_opendir_error
-PR_EXTERN(void) _MD_win32_map_closedir_error(PRInt32 err);
+extern void _MD_win32_map_closedir_error(PRInt32 err);
#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_win32_map_closedir_error
-PR_EXTERN(void) _MD_unix_readdir_error(PRInt32 err);
+extern void _MD_unix_readdir_error(PRInt32 err);
#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error
-PR_EXTERN(void) _MD_win32_map_delete_error(PRInt32 err);
+extern void _MD_win32_map_delete_error(PRInt32 err);
#define _PR_MD_MAP_DELETE_ERROR _MD_win32_map_delete_error
-PR_EXTERN(void) _MD_win32_map_stat_error(PRInt32 err);
+extern void _MD_win32_map_stat_error(PRInt32 err);
#define _PR_MD_MAP_STAT_ERROR _MD_win32_map_stat_error
-PR_EXTERN(void) _MD_win32_map_fstat_error(PRInt32 err);
+extern void _MD_win32_map_fstat_error(PRInt32 err);
#define _PR_MD_MAP_FSTAT_ERROR _MD_win32_map_fstat_error
-PR_EXTERN(void) _MD_win32_map_rename_error(PRInt32 err);
+extern void _MD_win32_map_rename_error(PRInt32 err);
#define _PR_MD_MAP_RENAME_ERROR _MD_win32_map_rename_error
-PR_EXTERN(void) _MD_win32_map_access_error(PRInt32 err);
+extern void _MD_win32_map_access_error(PRInt32 err);
#define _PR_MD_MAP_ACCESS_ERROR _MD_win32_map_access_error
-PR_EXTERN(void) _MD_win32_map_mkdir_error(PRInt32 err);
+extern void _MD_win32_map_mkdir_error(PRInt32 err);
#define _PR_MD_MAP_MKDIR_ERROR _MD_win32_map_mkdir_error
-PR_EXTERN(void) _MD_win32_map_rmdir_error(PRInt32 err);
+extern void _MD_win32_map_rmdir_error(PRInt32 err);
#define _PR_MD_MAP_RMDIR_ERROR _MD_win32_map_rmdir_error
-PR_EXTERN(void) _MD_win32_map_read_error(PRInt32 err);
+extern void _MD_win32_map_read_error(PRInt32 err);
#define _PR_MD_MAP_READ_ERROR _MD_win32_map_read_error
-PR_EXTERN(void) _MD_win32_map_transmitfile_error(PRInt32 err);
+extern void _MD_win32_map_transmitfile_error(PRInt32 err);
#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_win32_map_transmitfile_error
-PR_EXTERN(void) _MD_win32_map_write_error(PRInt32 err);
+extern void _MD_win32_map_write_error(PRInt32 err);
#define _PR_MD_MAP_WRITE_ERROR _MD_win32_map_write_error
-PR_EXTERN(void) _MD_win32_map_lseek_error(PRInt32 err);
+extern void _MD_win32_map_lseek_error(PRInt32 err);
#define _PR_MD_MAP_LSEEK_ERROR _MD_win32_map_lseek_error
-PR_EXTERN(void) _MD_win32_map_fsync_error(PRInt32 err);
+extern void _MD_win32_map_fsync_error(PRInt32 err);
#define _PR_MD_MAP_FSYNC_ERROR _MD_win32_map_fsync_error
-PR_EXTERN(void) _MD_win32_map_close_error(PRInt32 err);
+extern void _MD_win32_map_close_error(PRInt32 err);
#define _PR_MD_MAP_CLOSE_ERROR _MD_win32_map_close_error
-PR_EXTERN(void) _MD_win32_map_socket_error(PRInt32 err);
+extern void _MD_win32_map_socket_error(PRInt32 err);
#define _PR_MD_MAP_SOCKET_ERROR _MD_win32_map_socket_error
-PR_EXTERN(void) _MD_win32_map_recv_error(PRInt32 err);
+extern void _MD_win32_map_recv_error(PRInt32 err);
#define _PR_MD_MAP_RECV_ERROR _MD_win32_map_recv_error
-PR_EXTERN(void) _MD_win32_map_recvfrom_error(PRInt32 err);
+extern void _MD_win32_map_recvfrom_error(PRInt32 err);
#define _PR_MD_MAP_RECVFROM_ERROR _MD_win32_map_recvfrom_error
-PR_EXTERN(void) _MD_win32_map_send_error(PRInt32 err);
+extern void _MD_win32_map_send_error(PRInt32 err);
#define _PR_MD_MAP_SEND_ERROR _MD_win32_map_send_error
-PR_EXTERN(void) _MD_win32_map_sendto_error(PRInt32 err);
+extern void _MD_win32_map_sendto_error(PRInt32 err);
#define _PR_MD_MAP_SENDTO_ERROR _MD_win32_map_sendto_error
-PR_EXTERN(void) _MD_win32_map_accept_error(PRInt32 err);
+extern void _MD_win32_map_accept_error(PRInt32 err);
#define _PR_MD_MAP_ACCEPT_ERROR _MD_win32_map_accept_error
-PR_EXTERN(void) _MD_win32_map_acceptex_error(PRInt32 err);
+extern void _MD_win32_map_acceptex_error(PRInt32 err);
#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_win32_map_acceptex_error
-PR_EXTERN(PRInt32) _MD_win32_map_connect_error(PRInt32 err);
+extern PRInt32 _MD_win32_map_connect_error(PRInt32 err);
#define _PR_MD_MAP_CONNECT_ERROR _MD_win32_map_connect_error
-PR_EXTERN(void) _MD_win32_map_bind_error(PRInt32 err);
+extern void _MD_win32_map_bind_error(PRInt32 err);
#define _PR_MD_MAP_BIND_ERROR _MD_win32_map_bind_error
-PR_EXTERN(void) _MD_win32_map_listen_error(PRInt32 err);
+extern void _MD_win32_map_listen_error(PRInt32 err);
#define _PR_MD_MAP_LISTEN_ERROR _MD_win32_map_listen_error
-PR_EXTERN(void) _MD_win32_map_shutdown_error(PRInt32 err);
+extern void _MD_win32_map_shutdown_error(PRInt32 err);
#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_win32_map_shutdown_error
-PR_EXTERN(void) _MD_win32_map_getsockname_error(PRInt32 err);
+extern void _MD_win32_map_getsockname_error(PRInt32 err);
#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_win32_map_getsockname_error
-PR_EXTERN(void) _MD_win32_map_getpeername_error(PRInt32 err);
+extern void _MD_win32_map_getpeername_error(PRInt32 err);
#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_win32_map_getpeername_error
-PR_EXTERN(void) _MD_win32_map_getsockopt_error(PRInt32 err);
+extern void _MD_win32_map_getsockopt_error(PRInt32 err);
#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_win32_map_getsockopt_error
-PR_EXTERN(void) _MD_win32_map_setsockopt_error(PRInt32 err);
+extern void _MD_win32_map_setsockopt_error(PRInt32 err);
#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_win32_map_setsockopt_error
-PR_EXTERN(void) _MD_win32_map_open_error(PRInt32 err);
+extern void _MD_win32_map_open_error(PRInt32 err);
#define _PR_MD_MAP_OPEN_ERROR _MD_win32_map_open_error
-PR_EXTERN(void) _MD_win32_map_gethostname_error(PRInt32 err);
+extern void _MD_win32_map_gethostname_error(PRInt32 err);
#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_win32_map_gethostname_error
-PR_EXTERN(void) _MD_win32_map_select_error(PRInt32 err);
+extern void _MD_win32_map_select_error(PRInt32 err);
#define _PR_MD_MAP_SELECT_ERROR _MD_win32_map_select_error
-PR_EXTERN(void) _MD_win32_map_lockf_error(int err);
+extern void _MD_win32_map_lockf_error(int err);
#define _PR_MD_MAP_LOCKF_ERROR _MD_win32_map_lockf_error
#endif /* nspr_win32_errors_h___ */
diff --git a/pr/include/md/_win95.h b/pr/include/md/_win95.h
index 3609046c..7b412923 100644
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -169,10 +169,13 @@ struct _MDProcess {
#define _MD_WRITE _PR_MD_WRITE
#define _MD_WRITEV _PR_MD_WRITEV
#define _MD_LSEEK _PR_MD_LSEEK
+#define _MD_LSEEK64 _PR_MD_LSEEK64
extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#define _MD_CLOSE_FILE _MD_CloseFile
#define _MD_GETFILEINFO _PR_MD_GETFILEINFO
+#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64
#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO
+#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64
#define _MD_STAT _PR_MD_STAT
#define _MD_RENAME _PR_MD_RENAME
#define _MD_ACCESS _PR_MD_ACCESS
@@ -224,8 +227,13 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
#define _MD_FSYNC _PR_MD_FSYNC
#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x)
#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x)
+#endif /* x86 */
#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
#define _MD_INIT_IO _PR_MD_INIT_IO
@@ -363,6 +371,7 @@ extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
/* --- Native-Thread Specific Definitions ------------------------------- */
+#ifdef _PR_USE_STATIC_TLS
extern __declspec(thread) struct PRThread *_pr_currentThread;
#define _MD_CURRENT_THREAD() _pr_currentThread
#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
@@ -374,6 +383,19 @@ extern __declspec(thread) struct PRThread *_pr_thread_last_run;
extern __declspec(thread) struct _PRCPU *_pr_currentCPU;
#define _MD_CURRENT_CPU() _pr_currentCPU
#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (0))
+#else /* _PR_USE_STATIC_TLS */
+extern DWORD _pr_currentThreadIndex;
+#define _MD_CURRENT_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex))
+#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, _thread)
+
+extern DWORD _pr_lastThreadIndex;
+#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex))
+#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0)
+
+extern DWORD _pr_currentCPUIndex;
+#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0)
+#endif /* _PR_USE_STATIC_TLS */
// wtc. extern __declspec(thread) PRUintn _pr_ints_off;
// lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val))
diff --git a/pr/include/md/_winnt.h b/pr/include/md/_winnt.h
index a754c087..ba2a6a10 100644
--- a/pr/include/md/_winnt.h
+++ b/pr/include/md/_winnt.h
@@ -179,9 +179,12 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_WRITE _PR_MD_WRITE
#define _MD_WRITEV _PR_MD_WRITEV
#define _MD_LSEEK _PR_MD_LSEEK
+#define _MD_LSEEK64 _PR_MD_LSEEK64
#define _MD_CLOSE_FILE(f) _PR_MD_CLOSE(f, PR_FALSE)
#define _MD_GETFILEINFO _PR_MD_GETFILEINFO
+#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64
#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO
+#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64
#define _MD_STAT _PR_MD_STAT
#define _MD_RENAME _PR_MD_RENAME
#define _MD_ACCESS _PR_MD_ACCESS
@@ -212,8 +215,13 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_SOCKETAVAILABLE _PR_MD_SOCKETAVAILABLE
#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x)
#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x)
+#endif /* x86 */
#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
#define _MD_INIT_IO _PR_MD_INIT_IO
diff --git a/pr/include/obsolete/protypes.h b/pr/include/obsolete/protypes.h
index 3c45ed4f..676d848b 100644
--- a/pr/include/obsolete/protypes.h
+++ b/pr/include/obsolete/protypes.h
@@ -33,7 +33,7 @@ typedef PRUintn uint;
typedef PRUintn uintn;
typedef PRUint64 uint64;
-#if !defined(XP_MAC) && !defined(_WIN32)
+#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
typedef PRUint32 uint32;
#else
typedef unsigned long uint32;
@@ -59,7 +59,7 @@ typedef PRInt64 int64;
/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
#if !defined(HPUX) || !defined(_MODEL_INCLUDED)
#if !defined(WIN32) || !defined(_WINSOCK2API_) /* defines its own "int32" */
-#if !defined(XP_MAC) && !defined(_WIN32)
+#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
typedef PRInt32 int32;
#else
typedef long int32;
diff --git a/pr/include/prbit.h b/pr/include/prbit.h
index 17965aed..57853384 100644
--- a/pr/include/prbit.h
+++ b/pr/include/prbit.h
@@ -49,18 +49,19 @@ PR_EXTERN(PRIntn) PR_FloorLog2(PRUint32 i);
*/
#define PR_CEILING_LOG2(_log2,_n) \
PR_BEGIN_MACRO \
+ PRUint32 j_ = (PRUint32)(_n); \
(_log2) = 0; \
- if ((_n) & ((_n)-1)) \
+ if ((j_) & ((j_)-1)) \
(_log2) += 1; \
- if ((_n) >> 16) \
- (_log2) += 16, (_n) >>= 16; \
- if ((_n) >> 8) \
- (_log2) += 8, (_n) >>= 8; \
- if ((_n) >> 4) \
- (_log2) += 4, (_n) >>= 4; \
- if ((_n) >> 2) \
- (_log2) += 2, (_n) >>= 2; \
- if ((_n) >> 1) \
+ if ((j_) >> 16) \
+ (_log2) += 16, (j_) >>= 16; \
+ if ((j_) >> 8) \
+ (_log2) += 8, (j_) >>= 8; \
+ if ((j_) >> 4) \
+ (_log2) += 4, (j_) >>= 4; \
+ if ((j_) >> 2) \
+ (_log2) += 2, (j_) >>= 2; \
+ if ((j_) >> 1) \
(_log2) += 1; \
PR_END_MACRO
@@ -72,16 +73,17 @@ PR_EXTERN(PRIntn) PR_FloorLog2(PRUint32 i);
*/
#define PR_FLOOR_LOG2(_log2,_n) \
PR_BEGIN_MACRO \
+ PRUint32 j_ = (PRUint32)(_n); \
(_log2) = 0; \
- if ((_n) >> 16) \
- (_log2) += 16, (_n) >>= 16; \
- if ((_n) >> 8) \
- (_log2) += 8, (_n) >>= 8; \
- if ((_n) >> 4) \
- (_log2) += 4, (_n) >>= 4; \
- if ((_n) >> 2) \
- (_log2) += 2, (_n) >>= 2; \
- if ((_n) >> 1) \
+ if ((j_) >> 16) \
+ (_log2) += 16, (j_) >>= 16; \
+ if ((j_) >> 8) \
+ (_log2) += 8, (j_) >>= 8; \
+ if ((j_) >> 4) \
+ (_log2) += 4, (j_) >>= 4; \
+ if ((j_) >> 2) \
+ (_log2) += 2, (j_) >>= 2; \
+ if ((j_) >> 1) \
(_log2) += 1; \
PR_END_MACRO
diff --git a/pr/include/prdtoa.h b/pr/include/prdtoa.h
index d362a1e4..fec81a59 100644
--- a/pr/include/prdtoa.h
+++ b/pr/include/prdtoa.h
@@ -69,15 +69,7 @@ PR_EXTERN(void) PR_cnvtf(char *buf, PRIntn bufsz, PRIntn prcsn, PRFloat64 fval);
** 0 ==> shortest string that yields d when read in
** and rounded to nearest.
*/
-PR_EXTERN(char *) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
- PRIntn *decpt, PRIntn *sign, char **rve);
-
-/*
-** PR_dtoa_r() is the reentrant version of PR_dtoa().
-*/
-
-PR_EXTERN(PRStatus)
-PR_dtoa_r(PRFloat64 d, PRIntn mode, PRIntn ndigits,
+PR_EXTERN(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize);
PR_END_EXTERN_C
diff --git a/pr/include/prinet.h b/pr/include/prinet.h
index 3e40616e..149b943e 100644
--- a/pr/include/prinet.h
+++ b/pr/include/prinet.h
@@ -74,13 +74,7 @@
#elif defined(WIN32)
-/*
- * On Win NT, windows.h includes either winsock.h or winsock2.h,
- * depending on the value of the _WIN32_WINNT macro. One can't
- * include winsock2.h if winsock.h is already included. So we
- * include windows.h to stay neutral.
- */
-#include <windows.h>
+/* Do not include any system header files. */
#elif defined(WIN16)
diff --git a/pr/include/prio.h b/pr/include/prio.h
index 411d8e1a..1cc6719e 100644
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -84,6 +84,36 @@ typedef enum PRTransmitFileFlags {
/*
**************************************************************************
+** Macros for PRNetAddr
+**
+** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL
+** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST
+**************************************************************************
+*/
+
+#ifdef WIN32
+
+#define PR_AF_INET 2
+#define PR_AF_LOCAL 1
+#define PR_INADDR_ANY (unsigned long)0x00000000
+#define PR_INADDR_LOOPBACK 0x7f000001
+#define PR_INADDR_BROADCAST (unsigned long)0xffffffff
+
+#else /* WIN32 */
+
+#define PR_AF_INET AF_INET
+#define PR_AF_LOCAL AF_UNIX
+#ifdef AF_INET6
+#define PR_AF_INET6 AF_INET6
+#endif
+#define PR_INADDR_ANY INADDR_ANY
+#define PR_INADDR_LOOPBACK INADDR_LOOPBACK
+#define PR_INADDR_BROADCAST INADDR_BROADCAST
+
+#endif /* WIN32 */
+
+/*
+**************************************************************************
** A network address
**
** Only Internet Protocol (IPv4 and IPv6) addresses are supported.
@@ -99,12 +129,6 @@ typedef enum PRTransmitFileFlags {
typedef struct in6_addr PRIPv6Addr;
-#define PR_NETADDR_SIZE(_addr) PR_NetAddrSize(_addr)
-
-#else
-
-#define PR_NETADDR_SIZE(_addr) sizeof(PRNetAddr)
-
#endif /* defined(_PR_INET6) */
union PRNetAddr {
@@ -120,15 +144,44 @@ union PRNetAddr {
} inet;
#if defined(_PR_INET6)
struct {
- PRUint16 family; /* address family (AF_INET | AF_INET6) */
+ PRUint16 family; /* address family (AF_INET6) */
PRUint16 port; /* port number */
PRUint32 flowinfo; /* routing information */
PRIPv6Addr ip; /* the actual 128 bits of address */
} ipv6;
#endif /* defined(_PR_INET6) */
+#if defined(XP_UNIX)
+ struct { /* Unix domain socket address */
+ PRUint16 family; /* address family (AF_UNIX) */
+ char path[104]; /* null-terminated pathname */
+ } local;
+#endif
};
/*
+** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
+** whose 'family' field is set. It returns the size of the union
+** member corresponding to the specified address family.
+*/
+
+#if defined(_PR_INET6)
+
+#define PR_NETADDR_SIZE(_addr) PR_NetAddrSize(_addr)
+
+#else
+
+#if defined(XP_UNIX)
+#define PR_NETADDR_SIZE(_addr) \
+ ((_addr)->raw.family == AF_UNIX \
+ ? sizeof((_addr)->local) \
+ : sizeof((_addr)->inet))
+#else
+#define PR_NETADDR_SIZE(_addr) sizeof((_addr)->inet)
+#endif /* defined(XP_UNIX) */
+
+#endif /* defined(_PR_INET6) */
+
+/*
***************************************************************************
** PRSockOption
**
@@ -275,7 +328,7 @@ typedef PRInt32 (PR_CALLBACK *PRSendtoFN)(
PRFileDesc *fd, const void *buf, PRInt32 amount,
PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout);
typedef PRInt16 (PR_CALLBACK *PRPollFN)(
- PRFileDesc *fd, PRInt16 how_flags);
+ PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
void *buf, PRInt32 amount, PRIntervalTime t);
@@ -371,11 +424,13 @@ PR_EXTERN(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id);
* that one recongizes and therefore predict that it will implement
* a desired protocol.
*
- * There are two well-known identities:
+ * There are three well-known identities:
+ * PR_INVALID_IO_LAYER => an invalid layer identity, for error return
* PR_TOP_IO_LAYER => the identity of the top of the stack
* PR_NSPR_IO_LAYER => the identity used by NSPR proper
- * The latter may be used as a shorthand for identifying the topmost layer
- * of an existing stack. Ie., the following two constructs are equivalent.
+ * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
+ * layer of an existing stack. Ie., the following two constructs are
+ * equivalent.
*
* rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer);
* rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer)
@@ -404,7 +459,7 @@ PR_EXTERN(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* stack, PRDescIdentity i
* layer's methods table. You may NOT modify the table directly.
**************************************************************************
*/
-PR_EXTERN(PRIOMethods const*) PR_GetDefaultIOMethods(void);
+PR_EXTERN(const PRIOMethods *) PR_GetDefaultIOMethods(void);
/*
**************************************************************************
@@ -416,7 +471,7 @@ PR_EXTERN(PRIOMethods const*) PR_GetDefaultIOMethods(void);
**************************************************************************
*/
PR_EXTERN(PRFileDesc*) PR_CreateIOLayerStub(
- PRDescIdentity ident, PRIOMethods const *methods);
+ PRDescIdentity ident, const PRIOMethods *methods);
/*
**************************************************************************
@@ -1516,11 +1571,11 @@ struct PRPollDesc {
** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
** these together to produce the desired poll request.
**
-** On Unix platforms where we use poll() to block the idle threads,
+** On Unix platforms where the poll() system call is available,
** the various PR_POLL_XXX flags are mapped to the native poll flags.
*/
-#if defined(XP_UNIX) && defined(_PR_USE_POLL)
+#if defined(XP_UNIX) && defined(_PR_POLL_AVAILABLE)
#include <poll.h>
#define PR_POLL_READ POLLIN
@@ -1529,7 +1584,7 @@ struct PRPollDesc {
#define PR_POLL_ERR POLLERR /* only in out_flags */
#define PR_POLL_NVAL POLLNVAL /* only in out_flags when fd is bad */
-#else /* XP_UNIX, _PR_USE_POLL */
+#else /* XP_UNIX, _PR_POLL_AVAILABLE */
#define PR_POLL_READ 0x1
#define PR_POLL_WRITE 0x2
@@ -1537,7 +1592,7 @@ struct PRPollDesc {
#define PR_POLL_ERR 0x8 /* only in out_flags */
#define PR_POLL_NVAL 0x10 /* only in out_flags when fd is bad */
-#endif /* XP_UNIX, _PR_USE_POLL */
+#endif /* XP_UNIX, _PR_POLL_AVAILABLE */
/*
*************************************************************************
diff --git a/pr/include/private/pprio.h b/pr/include/private/pprio.h
index 8cd92a29..c9d6eec1 100644
--- a/pr/include/private/pprio.h
+++ b/pr/include/private/pprio.h
@@ -39,9 +39,9 @@ NSPR_BEGIN_EXTERN_C
/************************************************************************/
/* Return the method tables for files, tcp sockets and udp sockets */
-PR_EXTERN(PRIOMethods*) PR_GetFileMethods(void);
-PR_EXTERN(PRIOMethods*) PR_GetTCPMethods(void);
-PR_EXTERN(PRIOMethods*) PR_GetUDPMethods(void);
+PR_EXTERN(const PRIOMethods*) PR_GetFileMethods(void);
+PR_EXTERN(const PRIOMethods*) PR_GetTCPMethods(void);
+PR_EXTERN(const PRIOMethods*) PR_GetUDPMethods(void);
/*
** Convert a NSPR Socket Handle to a Native Socket handle.
@@ -49,7 +49,8 @@ PR_EXTERN(PRIOMethods*) PR_GetUDPMethods(void);
*/
PR_EXTERN(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *);
PR_EXTERN(void) PR_ChangeFileDescNativeHandle(PRFileDesc *, PRInt32);
-PR_EXTERN(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd, PRIOMethods *methods);
+PR_EXTERN(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd,
+ const PRIOMethods *methods);
PR_EXTERN(void) PR_FreeFileDesc(PRFileDesc *fd);
/*
** Import an existing OS file to NSPR.
@@ -59,6 +60,24 @@ PR_EXTERN(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd);
PR_EXTERN(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd);
/*
+** Macros for PR_Socket
+**
+** Socket types: PR_SOCK_STREAM, PR_SOCK_DGRAM
+*/
+
+#ifdef WIN32
+
+#define PR_SOCK_STREAM 1
+#define PR_SOCK_DGRAM 2
+
+#else /* WIN32 */
+
+#define PR_SOCK_STREAM SOCK_STREAM
+#define PR_SOCK_DGRAM SOCK_DGRAM
+
+#endif /* WIN32 */
+
+/*
** Create a new Socket; this function is obsolete.
*/
PR_EXTERN(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto);
diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h
index 5cfbf3a2..f93ed80f 100644
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -28,14 +28,6 @@
*/
#if defined(_PR_PTHREADS)
-/*
- * XXX: On Linux 2.0.27 (installed on tioman.mcom.com), sched.h uses
- * this _P macro that seems to be undefined. I suspect that it is
- * a typo (should be __P).
- */
-#if defined(LINUX)
-#define _P(x) __P(x)
-#endif
#include <pthread.h>
#endif
@@ -191,9 +183,14 @@ typedef struct PTDebug
PRUintn continuationsServed;
PRUintn recyclesNeeded;
PRUintn quiescentIO;
+ PRUintn locks_created, locks_destroyed;
+ PRUintn locks_acquired, locks_released;
+ PRUintn cvars_created, cvars_destroyed;
+ PRUintn cvars_notified, delayed_cv_deletes;
} PTDebug;
PR_EXTERN(PTDebug) PT_GetStats(void);
+PR_EXTERN(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
#endif /* defined(DEBUG) */
@@ -524,7 +521,7 @@ extern _PRInterruptTable _pr_interruptTable[];
#define _PR_MISSED_IO 0x2
#define _PR_MISSED_CHILD 0x4
-PR_EXTERN(void) _PR_IntsOn(_PRCPU *cpu);
+extern void _PR_IntsOn(_PRCPU *cpu);
PR_EXTERN(void) _PR_WakeupCPU(void);
PR_EXTERN(void) _PR_PauseCPU(void);
@@ -536,7 +533,7 @@ PR_EXTERN(void) _PR_PauseCPU(void);
#define _PR_LOCK_UNLOCK(_lock) \
_PR_MD_UNLOCK(&(_lock)->ilock);
-PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock);
+extern PRThread * _PR_AssignLock(PRLock *lock);
#define _PR_LOCK_PTR(_qp) \
((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
@@ -548,9 +545,9 @@ PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock);
#define _PR_CVAR_UNLOCK(_cvar) \
_PR_MD_UNLOCK(&(_cvar)->ilock);
-PR_EXTERN(PRStatus) _PR_WaitCondVar(
+extern PRStatus _PR_WaitCondVar(
PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
-PR_EXTERN(PRUint32) _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
+extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
PR_EXTERN(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
@@ -689,20 +686,20 @@ extern PRLock *_pr_terminationCVLock;
* code. *
*************************************************************************/
-PR_EXTERN(void) _PR_ClockInterrupt(void);
+extern void _PR_ClockInterrupt(void);
-PR_EXTERN(void) _PR_Schedule(void);
-PR_EXTERN(void) _PR_SetThreadPriority(
+extern void _PR_Schedule(void);
+extern void _PR_SetThreadPriority(
PRThread* thread, PRThreadPriority priority);
PR_EXTERN(void) _PR_Unlock(PRLock *lock);
PR_EXTERN(void) _PR_SuspendThread(PRThread *t);
PR_EXTERN(void) _PR_ResumeThread(PRThread *t);
-PR_EXTERN(PRThreadStack *)_PR_NewStack(PRUint32 stackSize);
-PR_EXTERN(void) _PR_FreeStack(PRThreadStack *stack);
-PR_EXTERN(PRBool) NotifyThread (PRThread *thread, PRThread *me);
-PR_EXTERN(void) _PR_NotifyLockedThread (PRThread *thread);
+extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
+extern void _PR_FreeStack(PRThreadStack *stack);
+extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
+extern void _PR_NotifyLockedThread (PRThread *thread);
PR_EXTERN(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
PR_EXTERN(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
@@ -718,8 +715,8 @@ PR_EXTERN(PRThread*) _PR_CreateThread(PRThreadType type,
PRUint32 stackSize,
PRUint32 flags);
-PR_EXTERN(void) _PR_NativeDestroyThread(PRThread *thread);
-PR_EXTERN(void) _PR_UserDestroyThread(PRThread *thread);
+extern void _PR_NativeDestroyThread(PRThread *thread);
+extern void _PR_UserDestroyThread(PRThread *thread);
PR_EXTERN(PRThread*) _PRI_AttachThread(
PRThreadType type, PRThreadPriority priority,
@@ -750,10 +747,10 @@ PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
* awaken a thread which is waiting on a lock or cvar.
*/
-PR_EXTERN(PRStatus) _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
#define _PR_MD_WAIT _MD_WAIT
-PR_EXTERN(PRStatus) _PR_MD_WAKEUP_WAITER(PRThread *);
+extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
#define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
@@ -787,13 +784,13 @@ PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
/*
* Returns the number of threads awoken or 0 if a timeout occurred;
*/
-PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
+extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
#define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
-PR_EXTERN(void) _PR_MD_EXIT(PRIntn status);
+extern void _PR_MD_EXIT(PRIntn status);
#define _PR_MD_EXIT _MD_EXIT
/* Locks related */
@@ -877,10 +874,10 @@ PR_EXTERN(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
PR_EXTERN(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
-PR_EXTERN(PRStatus) _PR_MD_INIT_THREAD(PRThread *thread);
+extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
#define _PR_MD_INIT_THREAD _MD_INIT_THREAD
-PR_EXTERN(void) _PR_MD_EXIT_THREAD(PRThread *thread);
+extern void _PR_MD_EXIT_THREAD(PRThread *thread);
#define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
@@ -888,16 +885,16 @@ PR_EXTERN(void) _PR_MD_EXIT_THREAD(PRThread *thread);
PR_EXTERN(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
-PR_EXTERN(void) _PR_MD_SUSPEND_THREAD(PRThread *thread);
+extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
#define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
-PR_EXTERN(void) _PR_MD_RESUME_THREAD(PRThread *thread);
+extern void _PR_MD_RESUME_THREAD(PRThread *thread);
#define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
-PR_EXTERN(void) _PR_MD_SUSPEND_CPU(_PRCPU *cpu);
+extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu);
#define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
-PR_EXTERN(void) _PR_MD_RESUME_CPU(_PRCPU *cpu);
+extern void _PR_MD_RESUME_CPU(_PRCPU *cpu);
#define _PR_MD_RESUME_CPU _MD_RESUME_CPU
extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
@@ -918,24 +915,24 @@ PR_EXTERN(void) _PR_IRIX_CHILD_PROCESS(void);
#endif /* !_PR_LOCAL_THREADS_ONLY */
-PR_EXTERN(void) _PR_MD_CLEAN_THREAD(PRThread *thread);
+extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
#define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
#ifdef HAVE_CUSTOM_USER_THREADS
-PR_EXTERN(void) _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
+extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
#define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
-PR_EXTERN(PRThread*) _PR_MD_CREATE_USER_THREAD(
+extern PRThread* _PR_MD_CREATE_USER_THREAD(
PRUint32 stacksize,
void (*start)(void *),
void *arg);
#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
#endif
-PR_EXTERN(void) _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread);
+extern void _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread);
#define _PR_MD_INIT_PRIMORDIAL_THREAD _MD_INIT_PRIMORDIAL_THREAD
-PR_EXTERN(PRStatus) _PR_MD_CREATE_THREAD(
+extern PRStatus _PR_MD_CREATE_THREAD(
PRThread *thread,
void (*start) (void *),
PRThreadPriority priority,
@@ -944,10 +941,10 @@ PR_EXTERN(PRStatus) _PR_MD_CREATE_THREAD(
PRUint32 stackSize);
#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
-PR_EXTERN(void) _PR_MD_YIELD(void);
+extern void _PR_MD_YIELD(void);
#define _PR_MD_YIELD _MD_YIELD
-PR_EXTERN(void) _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
+extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
#define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
PR_EXTERN(void) _PR_MD_SUSPENDALL(void);
@@ -956,14 +953,14 @@ PR_EXTERN(void) _PR_MD_SUSPENDALL(void);
PR_EXTERN(void) _PR_MD_RESUMEALL(void);
#define _PR_MD_RESUMEALL _MD_RESUMEALL
-PR_EXTERN(void) _PR_MD_INIT_CONTEXT(
+extern void _PR_MD_INIT_CONTEXT(
PRThread *thread, char *top, void (*start) (void), PRBool *status);
#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
-PR_EXTERN(void) _PR_MD_SWITCH_CONTEXT(PRThread *thread);
+extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
#define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
-PR_EXTERN(void) _PR_MD_RESTORE_CONTEXT(PRThread *thread);
+extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
#define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
/* Directory enumeration related */
@@ -1200,8 +1197,8 @@ PR_EXTERN(void) _PR_MD_INIT_LOCKS(void);
struct PRLock {
#if defined(_PR_PTHREADS)
- pthread_mutex_t mutex; /* the underlying lock */
- _PT_Notified notified; /* array of conditions notified */
+ pthread_mutex_t mutex; /* the underlying lock */
+ _PT_Notified notified; /* array of conditions notified */
pthread_t owner; /* current lock owner */
#else /* defined(_PR_PTHREADS) */
PRCList links; /* linkage for PRThread.lockList */
@@ -1213,12 +1210,13 @@ struct PRLock {
#endif /* defined(_PR_PTHREADS) */
};
-PR_EXTERN(void) _PR_InitLocks(void);
+extern void _PR_InitLocks(void);
struct PRCondVar {
PRLock *lock; /* associated lock that protects the condition */
#if defined(_PR_PTHREADS)
- pthread_cond_t cv;
+ pthread_cond_t cv; /* underlying pthreads condition */
+ PRInt32 notify_pending; /* CV has destroy pending notification */
#else /* defined(_PR_PTHREADS) */
PRCList condQ; /* Condition variable wait Q */
_MDLock ilock; /* Internal Lock to protect condQ */
@@ -1297,12 +1295,13 @@ struct PRThread {
void *dumpArg; /* argument for the dump function */
#if defined(_PR_PTHREADS)
- pthread_t id; /* pthread identifier for the thread */
+ pthread_t id; /* pthread identifier for the thread */
PRBool okToDelete; /* ok to delete the PRThread struct? */
- PRCondVar *waiting; /* where the thread is waiting | NULL */
- void *sp; /* recorded sp for garbage collection */
- PRThread *next, *prev; /* simple linked list of all threads */
- PRUint32 suspend; /* used to store suspend and resume flags */
+ PRCondVar *io_cv; /* a condition used to run i/o */
+ PRCondVar *waiting; /* where the thread is waiting | NULL */
+ void *sp; /* recorded sp for garbage collection */
+ PRThread *next, *prev; /* simple linked list of all threads */
+ PRUint32 suspend; /* used to store suspend and resume flags */
#ifdef PT_NO_SIGTIMEDWAIT
pthread_mutex_t suspendResumeMutex;
pthread_cond_t suspendResumeCV;
@@ -1481,10 +1480,10 @@ extern PRBool _pr_ipv6_enabled; /* defined in prnetdb.c */
*************************************************************************/
/* Initialization related */
-PR_EXTERN(void) _PR_MD_EARLY_INIT(void);
+extern void _PR_MD_EARLY_INIT(void);
#define _PR_MD_EARLY_INIT _MD_EARLY_INIT
-PR_EXTERN(void) _PR_MD_INTERVAL_INIT(void);
+extern void _PR_MD_INTERVAL_INIT(void);
#define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
PR_EXTERN(void) _PR_MD_INIT_SEGS(void);
@@ -1516,24 +1515,24 @@ PR_EXTERN(PRTime) _PR_MD_NOW(void);
#define _PR_MD_NOW _MD_NOW
/* Environment related */
-PR_EXTERN(char*) _PR_MD_GET_ENV(const char *name);
+extern char* _PR_MD_GET_ENV(const char *name);
#define _PR_MD_GET_ENV _MD_GET_ENV
-PR_EXTERN(PRIntn) _PR_MD_PUT_ENV(const char *name);
+extern PRIntn _PR_MD_PUT_ENV(const char *name);
#define _PR_MD_PUT_ENV _MD_PUT_ENV
/* Atomic operations */
-void _PR_MD_INIT_ATOMIC(void);
+extern void _PR_MD_INIT_ATOMIC(void);
#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
-PR_EXTERN(PRInt32) _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
+extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
#define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
-PR_EXTERN(PRInt32) _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
+extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
#define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
-PR_EXTERN(PRInt32) _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
+extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
#define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
/* Segment related */
@@ -1560,29 +1559,29 @@ extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
/* Time intervals */
-PR_EXTERN(PRIntervalTime) _PR_MD_GET_INTERVAL(void);
+extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
-PR_EXTERN(PRIntervalTime) _PR_MD_INTERVAL_PER_SEC(void);
+extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
/* Affinity masks */
-PR_EXTERN(PRInt32) _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
+extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
-PR_EXTERN(PRInt32) _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
+extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
/* File locking */
-PR_EXTERN(PRStatus) _PR_MD_LOCKFILE(PRInt32 osfd);
+extern PRStatus _PR_MD_LOCKFILE(PRInt32 osfd);
#define _PR_MD_LOCKFILE _MD_LOCKFILE
-PR_EXTERN(PRStatus) _PR_MD_TLOCKFILE(PRInt32 osfd);
+extern PRStatus _PR_MD_TLOCKFILE(PRInt32 osfd);
#define _PR_MD_TLOCKFILE _MD_TLOCKFILE
-PR_EXTERN(PRStatus) _PR_MD_UNLOCKFILE(PRInt32 osfd);
+extern PRStatus _PR_MD_UNLOCKFILE(PRInt32 osfd);
#define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
/* Memory-mapped files */
@@ -1608,7 +1607,7 @@ PR_EXTERN(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
#define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
/* Get name of current host */
-PR_EXTERN(PRStatus) _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
+extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
#define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
PR_END_EXTERN_C
diff --git a/pr/include/prmwait.h b/pr/include/prmwait.h
index 008e6a80..c63398bd 100644
--- a/pr/include/prmwait.h
+++ b/pr/include/prmwait.h
@@ -24,6 +24,8 @@
#include "prtypes.h"
#include "prclist.h"
+PR_BEGIN_EXTERN_C
+
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
@@ -299,6 +301,8 @@ PR_EXTERN(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);
*/
PR_EXTERN(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
+PR_END_EXTERN_C
+
#endif /* defined(_PRMWAIT_H) */
/* prmwait.h */
diff --git a/pr/include/prtypes.h b/pr/include/prtypes.h
index dda8663b..a4a3b695 100644
--- a/pr/include/prtypes.h
+++ b/pr/include/prtypes.h
@@ -100,12 +100,20 @@
#define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x
-#else /* Unix or OS/2 */
+#elif defined(XP_OS2)
#define PR_EXTERN(__type) extern __type
#define PR_IMPLEMENT(__type) __type
#define PR_EXTERN_DATA(__type) extern __type
#define PR_IMPLEMENT_DATA(__type) __type
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) __x _Optlink
+#else /* Unix */
+#define PR_EXTERN(__type) extern __type
+#define PR_IMPLEMENT(__type) __type
+#define PR_EXTERN_DATA(__type) extern __type
+#define PR_IMPLEMENT_DATA(__type) __type
#define PR_CALLBACK
#define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x
@@ -227,9 +235,8 @@ typedef unsigned long PRUint64;
typedef __int64 PRInt64;
typedef unsigned __int64 PRUint64;
#elif defined(WIN32)
-#include <windows.h> /* For LONGLONG and DWORDLONG */
-typedef LONGLONG PRInt64;
-typedef DWORDLONG PRUint64;
+typedef __int64 PRInt64;
+typedef unsigned __int64 PRUint64;
#else
typedef long long PRInt64;
typedef unsigned long long PRUint64;
@@ -299,7 +306,9 @@ typedef unsigned long PRUptrdiff;
** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
** juast as you would C int-valued conditions.
************************************************************************/
-typedef enum { PR_FALSE = 0, PR_TRUE = 1 } PRBool;
+typedef PRIntn PRBool;
+#define PR_TRUE (PRIntn)1
+#define PR_FALSE (PRIntn)0
/************************************************************************
** TYPES: PRPackedBool
diff --git a/pr/include/prwin16.h b/pr/include/prwin16.h
index f87de046..2420b235 100644
--- a/pr/include/prwin16.h
+++ b/pr/include/prwin16.h
@@ -22,7 +22,7 @@
/*
** Condition use of this header on platform.
*/
-#if (defined(XP_PC) && !defined(_WIN32) && defined(MOZILLA_CLIENT)) || defined(WIN16)
+#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16)
#include <stdio.h>
PR_BEGIN_EXTERN_C
diff --git a/pr/src/io/pprmwait.h b/pr/src/io/pprmwait.h
index 55b258e0..adfce668 100644
--- a/pr/src/io/pprmwait.h
+++ b/pr/src/io/pprmwait.h
@@ -31,8 +31,8 @@
#define MAX_POLLING_INTERVAL 100
#define _PR_DEFAULT_HASH_LENGTH 59
-#define _MW_REHASH(a, i, m) _MW_HASH((PRUint32)(a) + (i) + _PR_HASH_OFFSET, m)
-#define _MW_HASH(a, m) ((((PRUint32)(a) >> 4) ^ ((PRUint32)(a) >> 10)) % (m))
+#define _MW_REHASH(a, i, m) _MW_HASH((PRUword)(a) + (i) + _PR_HASH_OFFSET, m)
+#define _MW_HASH(a, m) ((((PRUword)(a) >> 4) ^ ((PRUword)(a) >> 10)) % (m))
#define _MW_ABORTED(_rv) \
((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c
index ab20b2a3..95210eae 100644
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -200,6 +200,13 @@ static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
}
}
+static PRInt16 PR_CALLBACK FilePoll(
+ PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+ *out_flags = 0;
+ return in_flags;
+} /* FilePoll */
+
PRIOMethods _pr_fileMethods = {
PR_DESC_FILE,
FileClose,
@@ -222,7 +229,7 @@ PRIOMethods _pr_fileMethods = {
(PRSendFN)_PR_InvalidInt,
(PRRecvfromFN)_PR_InvalidInt,
(PRSendtoFN)_PR_InvalidInt,
- (PRPollFN)0,
+ FilePoll,
(PRAcceptreadFN)_PR_InvalidInt,
(PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus,
@@ -233,7 +240,7 @@ PRIOMethods _pr_fileMethods = {
(PRSetsocketoptionFN)_PR_InvalidStatus,
};
-PR_IMPLEMENT(PRIOMethods*) PR_GetFileMethods(void)
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
{
return &_pr_fileMethods;
}
diff --git a/pr/src/io/prio.c b/pr/src/io/prio.c
index d0be59fc..fc8f005f 100644
--- a/pr/src/io/prio.c
+++ b/pr/src/io/prio.c
@@ -30,7 +30,7 @@ PRLock *_pr_filedesc_freelist_lock;
void _PR_InitIO(void)
{
- PRIOMethods *methods = PR_GetFileMethods();
+ const PRIOMethods *methods = PR_GetFileMethods();
_pr_filedesc_freelist = NULL;
_pr_filedesc_freelist_lock = PR_NewLock();
@@ -75,7 +75,8 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
return result;
}
-PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd, PRIOMethods *methods)
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+ PRInt32 osfd, const PRIOMethods *methods)
{
PRFileDesc *fd;
@@ -147,7 +148,7 @@ PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds,
PRIntervalTime timeout)
{
PRPollDesc *pd, *epd;
- PRInt32 n;
+ PRInt32 ready;
PRThread *me = _PR_MD_CURRENT_THREAD();
if (_PR_PENDING_INTERRUPT(me)) {
@@ -161,24 +162,24 @@ PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds,
** proc to check for data before blocking.
*/
pd = pds;
- n = 0;
+ ready = 0;
for (pd = pds, epd = pd + npds; pd < epd; pd++) {
PRFileDesc *fd = pd->fd;
- PRInt16 in_flags;
- if (NULL == fd) {
- continue;
- }
- in_flags = pd->in_flags;
- if (in_flags && fd->methods->poll) {
- PRInt16 out_flags = (*fd->methods->poll)(fd, in_flags);
- if (out_flags) {
- pd->out_flags = out_flags;
- n++;
+ PRInt16 in_flags = pd->in_flags;
+ if (NULL != fd)
+ {
+ if (in_flags && fd->methods->poll) {
+ PRInt16 out_flags;
+ in_flags = (*fd->methods->poll)(fd, in_flags, &out_flags);
+ if (0 != (in_flags & out_flags)) {
+ pd->out_flags = out_flags; /* ready already */
+ ready++;
+ }
}
}
}
- if (n != 0) {
- return n;
+ if (ready != 0) {
+ return ready; /* don't need to block */
}
return(_PR_MD_PR_POLL(pds, npds, timeout));
}
diff --git a/pr/src/io/prlayer.c b/pr/src/io/prlayer.c
index d70a935e..1ca15962 100644
--- a/pr/src/io/prlayer.c
+++ b/pr/src/io/prlayer.c
@@ -148,9 +148,10 @@ static PRStatus PR_CALLBACK pl_DefConnect (
return (fd->lower->methods->connect)(fd->lower, addr, timeout);
}
-static PRFileDesc * PR_CALLBACK pl_TopAccept (
+static PRFileDesc* PR_CALLBACK pl_TopAccept (
PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
{
+ PRStatus rv;
PRFileDesc *newfd;
PR_ASSERT(fd != NULL);
@@ -159,13 +160,16 @@ static PRFileDesc * PR_CALLBACK pl_TopAccept (
newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
if (newfd != NULL)
{
- if (PR_FAILURE == PR_PushIOLayer(fd, fd->identity, newfd))
+ PRFileDesc *newstack = PR_NEW(PRFileDesc);
+ if (NULL != newstack)
{
- PR_Close(newfd);
- newfd = NULL;
+ *newstack = *fd; /* make a copy of the accepting layer */
+ rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+ if (PR_SUCCESS == rv) return newfd; /* that's it */
}
+ PR_Close(newfd); /* we failed for local reasons */
}
- return newfd;
+ return NULL;
}
static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
@@ -235,12 +239,13 @@ static PRInt32 PR_CALLBACK pl_DefSendto (
fd->lower, buf, amount, flags, addr, timeout);
}
-static PRInt16 PR_CALLBACK pl_DefPoll (PRFileDesc *fd, PRInt16 how_flags)
+static PRInt16 PR_CALLBACK pl_DefPoll (
+ PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
{
PR_ASSERT(fd != NULL);
PR_ASSERT(fd->lower != NULL);
- return (fd->lower->methods->poll)(fd->lower, how_flags);
+ return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
}
static PRInt32 PR_CALLBACK pl_DefAcceptread (
@@ -317,7 +322,7 @@ static PRStatus PR_CALLBACK pl_DefSetsocketoption (
}
/* Methods for the top of the stack. Just call down to the next fd. */
-static struct PRIOMethods pl_methods = {
+static PRIOMethods pl_methods = {
PR_DESC_LAYERED,
pl_TopClose,
pl_DefRead,
@@ -350,13 +355,13 @@ static struct PRIOMethods pl_methods = {
pl_DefSetsocketoption
};
-PR_IMPLEMENT(PRIOMethods const*) PR_GetDefaultIOMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods()
{
return &pl_methods;
} /* PR_GetDefaultIOMethods */
PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
- PRDescIdentity ident, PRIOMethods const *methods)
+ PRDescIdentity ident, const PRIOMethods *methods)
{
PRFileDesc *fd = NULL;
PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
@@ -399,6 +404,7 @@ PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
*fd = copy;
fd->higher = stack;
stack->lower = fd;
+ stack->higher = NULL;
}
else
{
diff --git a/pr/src/io/prmapopt.c b/pr/src/io/prmapopt.c
index c9ed829a..6bd4dddc 100644
--- a/pr/src/io/prmapopt.c
+++ b/pr/src/io/prmapopt.c
@@ -40,106 +40,6 @@
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
#endif
-/*
- * Not every platform has all the socket options we want to
- * support. Some older operating systems such as SunOS 4.1.3
- * don't have the IP multicast socket options. Win32 doesn't
- * have TCP_MAXSEG.
- *
- * To deal with this problem, we define the missing socket
- * options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with
- * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
- * available on the platform is requested.
- */
-
-/*
- * Sanity check. SO_LINGER and TCP_NODELAY should be available
- * on all platforms. Just to make sure we have included the
- * appropriate header files. Then any undefined socket options
- * are really missing.
- */
-
-#if !defined(SO_LINGER)
-#error "SO_LINGER is not defined"
-#endif
-
-#if !defined(TCP_NODELAY)
-#error "TCP_NODELAY is not defined"
-#endif
-
-/*
- * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
- * a valid socket option.
- */
-#define _PR_NO_SUCH_SOCKOPT -1
-
-#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */
-#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */
-#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */
-#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */
-#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */
-#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_TTL /* set/get IP Time To Live */
-#define IP_TTL _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef IP_TOS /* set/get IP Type Of Service */
-#define IP_TOS _PR_NO_SUCH_SOCKOPT
-#endif
-
-#ifndef TCP_MAXSEG /* maxumum segment size for tcp */
-#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
-#endif
-
-PRStatus _PR_MapOptionName(
- PRSockOption optname, PRInt32 *level, PRInt32 *name)
-{
- static PRInt32 socketOptions[PR_SockOpt_Last] =
- {
- 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
- IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
- IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
- TCP_NODELAY, TCP_MAXSEG
- };
- static PRInt32 socketLevels[PR_SockOpt_Last] =
- {
- 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
- IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
- IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
- IPPROTO_TCP, IPPROTO_TCP
- };
-
- if ((optname < PR_SockOpt_Linger)
- && (optname > PR_SockOpt_MaxSegment))
- {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-
- if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
- {
- PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
- return PR_FAILURE;
- }
- *name = socketOptions[optname];
- *level = socketLevels[optname];
- return PR_SUCCESS;
-} /* _PR_MapOptionName */
-
#ifndef _PR_PTHREADS
PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
@@ -244,6 +144,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
data->value.mcast_ttl = ttl;
break;
}
+#ifdef IP_ADD_MEMBERSHIP
case PR_SockOpt_AddMember:
case PR_SockOpt_DropMember:
{
@@ -260,6 +161,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
}
break;
}
+#endif /* IP_ADD_MEMBERSHIP */
case PR_SockOpt_McastInterface:
{
/* This option is a struct in_addr. */
@@ -377,6 +279,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
fd, level, name, (char*)&ttl, sizeof(ttl));
break;
}
+#ifdef IP_ADD_MEMBERSHIP
case PR_SockOpt_AddMember:
case PR_SockOpt_DropMember:
{
@@ -389,6 +292,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
fd, level, name, (char*)&mreq, sizeof(mreq));
break;
}
+#endif /* IP_ADD_MEMBERSHIP */
case PR_SockOpt_McastInterface:
{
/* This option is a struct in_addr. */
@@ -406,3 +310,114 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
} /* _PR_SocketSetSocketOption */
#endif /* ! _PR_PTHREADS */
+
+/*
+ *********************************************************************
+ *********************************************************************
+ **
+ ** Make sure that the following is at the end of this file,
+ ** because we will be playing with macro redefines.
+ **
+ *********************************************************************
+ *********************************************************************
+ */
+
+/*
+ * Not every platform has all the socket options we want to
+ * support. Some older operating systems such as SunOS 4.1.3
+ * don't have the IP multicast socket options. Win32 doesn't
+ * have TCP_MAXSEG.
+ *
+ * To deal with this problem, we define the missing socket
+ * options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with
+ * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
+ * available on the platform is requested.
+ */
+
+/*
+ * Sanity check. SO_LINGER and TCP_NODELAY should be available
+ * on all platforms. Just to make sure we have included the
+ * appropriate header files. Then any undefined socket options
+ * are really missing.
+ */
+
+#if !defined(SO_LINGER)
+#error "SO_LINGER is not defined"
+#endif
+
+#if !defined(TCP_NODELAY)
+#error "TCP_NODELAY is not defined"
+#endif
+
+/*
+ * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
+ * a valid socket option.
+ */
+#define _PR_NO_SUCH_SOCKOPT -1
+
+#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */
+#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */
+#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */
+#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */
+#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */
+#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TTL /* set/get IP Time To Live */
+#define IP_TTL _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TOS /* set/get IP Type Of Service */
+#define IP_TOS _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef TCP_MAXSEG /* maxumum segment size for tcp */
+#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
+#endif
+
+PRStatus _PR_MapOptionName(
+ PRSockOption optname, PRInt32 *level, PRInt32 *name)
+{
+ static PRInt32 socketOptions[PR_SockOpt_Last] =
+ {
+ 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
+ IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
+ IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
+ TCP_NODELAY, TCP_MAXSEG
+ };
+ static PRInt32 socketLevels[PR_SockOpt_Last] =
+ {
+ 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
+ IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+ IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+ IPPROTO_TCP, IPPROTO_TCP
+ };
+
+ if ((optname < PR_SockOpt_Linger)
+ && (optname > PR_SockOpt_MaxSegment))
+ {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
+ }
+
+ if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
+ {
+ PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+ *name = socketOptions[optname];
+ *level = socketLevels[optname];
+ return PR_SUCCESS;
+} /* _PR_MapOptionName */
diff --git a/pr/src/io/prprf.c b/pr/src/io/prprf.c
index d8dd9ec0..2ce93d18 100644
--- a/pr/src/io/prprf.c
+++ b/pr/src/io/prprf.c
@@ -35,11 +35,11 @@
** Note: on some platforms va_list is defined as an array,
** and requires array notation.
*/
-#if defined(MACLINUX) || defined(WIN16)
+#if defined(MKLINUX) || defined(WIN16)
#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
#else
#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
-#endif /*MACLINUX*/
+#endif /*MKLINUX*/
/*
** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it)
diff --git a/pr/src/io/prscanf.c b/pr/src/io/prscanf.c
index 4a23543f..96530bf6 100644
--- a/pr/src/io/prscanf.c
+++ b/pr/src/io/prscanf.c
@@ -379,7 +379,7 @@ GetFloat(ScanfState *state)
*va_arg(state->ap, long double *) = dval;
#endif
} else {
- *va_arg(state->ap, float *) = dval;
+ *va_arg(state->ap, float *) = (float) dval;
}
}
return PR_SUCCESS;
diff --git a/pr/src/io/prsocket.c b/pr/src/io/prsocket.c
index f34cf267..9c4be75c 100644
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -30,29 +30,53 @@
/************************************************************************/
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+static PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+ if ((addr != NULL)
+#ifdef XP_UNIX
+ && (addr->raw.family != AF_UNIX)
+#endif
+#ifdef _PR_INET6
+ && (addr->raw.family != AF_INET6)
+#endif
+ && (addr->raw.family != AF_INET)) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
+{
+ /*
+ * The definition of the length of a Unix domain socket address
+ * is not uniform, so we don't check it.
+ */
+ if ((addr != NULL)
+#ifdef XP_UNIX
+ && (addr->raw.family != AF_UNIX)
+#endif
+ && (PR_NETADDR_SIZE(addr) != addr_len)) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, PRIOVec *iov, PRInt32 iov_size,
PRIntervalTime timeout)
{
PRThread *me = _PR_MD_CURRENT_THREAD();
int w = 0;
PRIOVec *tmp_iov = NULL;
+#define LOCAL_MAXIOV 8
+ PRIOVec local_iov[LOCAL_MAXIOV];
int tmp_out;
int index, iov_cnt;
int count=0, sz = 0; /* 'count' is the return value. */
-#if defined(XP_UNIX)
- struct timeval tv, *tvp;
- fd_set wd;
-
- FD_ZERO(&wd);
- if (timeout == PR_INTERVAL_NO_TIMEOUT)
- tvp = NULL;
- else if (timeout != PR_INTERVAL_NO_WAIT) {
- tv.tv_sec = PR_IntervalToSeconds(timeout);
- tv.tv_usec = PR_IntervalToMicroseconds(
- timeout - PR_SecondsToInterval(tv.tv_sec));
- tvp = &tv;
- }
-#endif
if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT;
@@ -64,25 +88,22 @@ PRIntervalTime timeout)
return -1;
}
- tmp_iov = (PRIOVec *)PR_CALLOC(iov_size * sizeof(PRIOVec));
- if (!tmp_iov) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- return -1;
- }
+ /*
+ * Assume the first writev will succeed. Copy iov's only on
+ * failure.
+ */
+ tmp_iov = iov;
+ for (index = 0; index < iov_size; index++)
+ sz += iov[index].iov_len;
- for (index=0; index<iov_size; index++) {
- sz += iov[index].iov_len;
- tmp_iov[index].iov_base = iov[index].iov_base;
- tmp_iov[index].iov_len = iov[index].iov_len;
- }
iov_cnt = iov_size;
while (sz > 0) {
w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout);
if (w < 0) {
- count = -1;
- break;
+ count = -1;
+ break;
}
count += w;
if (fd->secret->nonblocking) {
@@ -93,9 +114,24 @@ PRIntervalTime timeout)
if (sz > 0) {
/* find the next unwritten vector */
for ( index = 0, tmp_out = count;
- tmp_out >= iov[index].iov_len;
- tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
-
+ tmp_out >= iov[index].iov_len;
+ tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
+
+ if (tmp_iov == iov) {
+ /*
+ * The first writev failed so we
+ * must copy iov's around.
+ * Avoid calloc/free if there
+ * are few enough iov's.
+ */
+ if (iov_size - index <= LOCAL_MAXIOV)
+ tmp_iov = local_iov;
+ else if ((tmp_iov = (PRIOVec *) PR_CALLOC((iov_size - index) *
+ sizeof *tmp_iov)) == NULL) {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return -1;
+ }
+ }
/* fill in the first partial read */
tmp_iov[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]);
@@ -110,7 +146,7 @@ PRIntervalTime timeout)
}
}
- if (tmp_iov)
+ if (tmp_iov != iov && tmp_iov != local_iov)
PR_DELETE(tmp_iov);
return count;
}
@@ -307,13 +343,8 @@ PRIntervalTime timeout)
_PR_MD_MAKE_NONBLOCK(fd2);
#endif
- PR_ASSERT((NULL == addr) || (PR_NETADDR_SIZE(addr) == al));
-#if defined(_PR_INET6)
- PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET)
- || (addr->raw.family == AF_INET6));
-#else
- PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET));
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
return fd2;
}
@@ -367,10 +398,16 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
PRInt32 result;
int one = 1;
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+
+#ifdef XP_UNIX
+ if (addr->raw.family == AF_UNIX) {
+ /* Disallow relative pathnames */
+ if (addr->local.path[0] != '/') {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
+ }
+ } else {
#endif
#ifdef HAVE_SOCKET_REUSEADDR
@@ -380,6 +417,10 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
}
#endif
+#ifdef XP_UNIX
+ }
+#endif
+
result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
if (result < 0) {
return PR_FAILURE;
@@ -541,11 +582,7 @@ static PRInt32 PR_CALLBACK SocketSendTo(
return -1;
}
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
count = 0;
while (amount > 0) {
@@ -797,12 +834,8 @@ static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
if (result < 0) {
return PR_FAILURE;
}
- PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr));
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
return PR_SUCCESS;
}
@@ -816,12 +849,8 @@ static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
if (result < 0) {
return PR_FAILURE;
}
- PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr));
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
return PR_SUCCESS;
}
@@ -925,6 +954,13 @@ static PRStatus PR_CALLBACK SocketSetSockOpt(
return rv;
}
+static PRInt16 PR_CALLBACK SocketPoll(
+ PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+ *out_flags = 0;
+ return in_flags;
+} /* SocketPoll */
+
static PRIOMethods tcpMethods = {
PR_DESC_SOCKET_TCP,
SocketClose,
@@ -947,7 +983,7 @@ static PRIOMethods tcpMethods = {
SocketSend,
(PRRecvfromFN)_PR_InvalidInt,
(PRSendtoFN)_PR_InvalidInt,
- (PRPollFN)0,
+ SocketPoll,
SocketAcceptRead,
SocketTransmitFile,
SocketGetName,
@@ -980,7 +1016,7 @@ static PRIOMethods udpMethods = {
SocketSend,
SocketRecvFrom,
SocketSendTo,
- (PRPollFN)0,
+ SocketPoll,
(PRAcceptreadFN)_PR_InvalidInt,
(PRTransmitfileFN)_PR_InvalidInt,
SocketGetName,
@@ -991,12 +1027,12 @@ static PRIOMethods udpMethods = {
_PR_SocketSetSocketOption
};
-PR_IMPLEMENT(PRIOMethods*) PR_GetTCPMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
{
return &tcpMethods;
}
-PR_IMPLEMENT(PRIOMethods*) PR_GetUDPMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
{
return &udpMethods;
}
@@ -1012,6 +1048,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
#if defined(_PR_INET6)
&& AF_INET6 != domain
#endif
+#if defined(XP_UNIX)
+ && AF_UNIX != domain
+#endif
) {
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
return NULL;
@@ -1243,13 +1282,13 @@ PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
{
PRInt32 rv;
PRFileDesc *newsockfd;
- PRNetAddr remote;
PRIntervalTime start, elapsed;
if (PR_INTERVAL_NO_TIMEOUT != timeout) {
start = PR_IntervalNow();
}
- if ((newsockfd = PR_Accept(sd, &remote, timeout)) == NULL) {
+ *raddr = (PRNetAddr *) ((char *) buf + amount);
+ if ((newsockfd = PR_Accept(sd, *raddr, timeout)) == NULL) {
return -1;
}
@@ -1266,8 +1305,6 @@ PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
rv = PR_Recv(newsockfd, buf, amount, 0, timeout);
if (rv >= 0) {
*nd = newsockfd;
- *raddr = (PRNetAddr *)((char *) buf + amount);
- memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));
return rv;
}
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 4c74bb8d..a227c063 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1449,7 +1449,7 @@ PR_IMPLEMENT(char *) inet_ntoa(struct in_addr addr)
}
-PR_IMPLEMENT(PRStatus) _MD_gethostname(char *name, int namelen)
+PRStatus _MD_gethostname(char *name, int namelen)
{
OSStatus err;
InetInterfaceInfo info;
diff --git a/pr/src/md/os2/os2cv.c b/pr/src/md/os2/os2cv.c
index 34264dd5..95cedff4 100644
--- a/pr/src/md/os2/os2cv.c
+++ b/pr/src/md/os2/os2cv.c
@@ -147,7 +147,7 @@ md_UnlockAndPostNotifies(
}
/* Release the lock before notifying */
- LeaveCriticalSection(&lock->mutex);
+ DosReleaseMutexSem(lock->mutex);
notified = &post; /* this is where we start */
do {
@@ -254,14 +254,14 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
md_UnlockAndPostNotifies(lock, thred, cv);
} else {
AddThreadToCVWaitQueueInternal(thred, cv);
- LeaveCriticalSection(&lock->mutex);
+ DosReleaseMutexSem(lock->mutex);
}
/* Wait for notification or timeout; don't really care which */
rv = DosWaitEventSem(thred->md.blocked_sema.sem, msecs);
DosResetEventSem(thred->md.blocked_sema.sem, &count);
- EnterCriticalSection(&(lock->mutex));
+ _MD_LOCK(lock);
PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
@@ -326,7 +326,7 @@ _PR_MD_UNLOCK(_MDLock *lock)
if (0 != lock->notified.length) {
md_UnlockAndPostNotifies(lock, NULL, NULL);
} else {
- LeaveCriticalSection(&lock->mutex);
+ DosReleaseMutexSem(lock->mutex);
}
return;
}
diff --git a/pr/src/md/os2/os2gc.c b/pr/src/md/os2/os2gc.c
index 00db7e15..625df4c9 100644
--- a/pr/src/md/os2/os2gc.c
+++ b/pr/src/md/os2/os2gc.c
@@ -22,7 +22,7 @@
*/
#include "primpl.h"
-extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+extern APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
diff --git a/pr/src/md/os2/os2io.c b/pr/src/md/os2/os2io.c
index b2e89d27..b08f2155 100644
--- a/pr/src/md/os2/os2io.c
+++ b/pr/src/md/os2/os2io.c
@@ -27,7 +27,7 @@
struct _MDLock _pr_ioq_lock;
-PR_IMPLEMENT(PRStatus)
+PRStatus
_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
{
PRInt32 rv;
@@ -68,7 +68,7 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
}
return PR_FAILURE;
}
-PR_IMPLEMENT(PRStatus)
+PRStatus
_PR_MD_WAKEUP_WAITER(PRThread *thread)
{
if ( _PR_IS_NATIVE_THREAD(thread) )
@@ -556,7 +556,7 @@ _PR_MD_RMDIR(const char *name)
}
}
-PR_IMPLEMENT(PRStatus)
+PRStatus
_PR_MD_LOCKFILE(PRInt32 f)
{
PRInt32 rv;
@@ -586,14 +586,14 @@ _PR_MD_LOCKFILE(PRInt32 f)
return PR_SUCCESS;
} /* end _PR_MD_LOCKFILE() */
-PR_IMPLEMENT(PRStatus)
+PRStatus
_PR_MD_TLOCKFILE(PRInt32 f)
{
return _PR_MD_LOCKFILE(f);
} /* end _PR_MD_TLOCKFILE() */
-PR_IMPLEMENT(PRStatus)
+PRStatus
_PR_MD_UNLOCKFILE(PRInt32 f)
{
PRInt32 rv;
diff --git a/pr/src/md/os2/os2misc.c b/pr/src/md/os2/os2misc.c
index 00913013..153d595c 100644
--- a/pr/src/md/os2/os2misc.c
+++ b/pr/src/md/os2/os2misc.c
@@ -22,13 +22,13 @@
*/
#include "primpl.h"
-PR_IMPLEMENT(char *)
+char *
_PR_MD_GET_ENV(const char *name)
{
return getenv(name);
}
-PR_IMPLEMENT(PRIntn)
+PRIntn
_PR_MD_PUT_ENV(const char *name)
{
return putenv(name);
@@ -452,7 +452,7 @@ PRStatus _PR_KillOS2Process(PRProcess *process)
return PR_FAILURE;
}
-PR_IMPLEMENT(PRStatus) _MD_OS2GetHostName(char *name, PRUint32 namelen)
+PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
{
PRIntn rv;
PRInt32 syserror;
diff --git a/pr/src/md/os2/os2thred.c b/pr/src/md/os2/os2thred.c
index e51b3eb3..3be132f5 100644
--- a/pr/src/md/os2/os2thred.c
+++ b/pr/src/md/os2/os2thred.c
@@ -19,7 +19,7 @@
#include "primpl.h"
#include <process.h> /* for _beginthread() */
-APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
/* --- globals ------------------------------------------------ */
_NSPR_TLS* pThreadLocalStorage = 0;
@@ -83,7 +83,7 @@ _PR_MD_CREATE_THREAD(PRThread *thread,
PRThreadState state,
PRUint32 stackSize)
{
- thread->md.handle = thread->id = (TID) _beginthread(
+ thread->md.handle = thread->id = (OS2TID) _beginthread(
(void(* _Optlink)(void*))start,
NULL,
thread->stack->stackSize,
diff --git a/pr/src/md/unix/aix.c b/pr/src/md/unix/aix.c
index 8ae7e303..544b2584 100644
--- a/pr/src/md/unix/aix.c
+++ b/pr/src/md/unix/aix.c
@@ -20,12 +20,13 @@
/*
* NSPR 2.0 overrides the system select() and poll() functions.
- * On AIX 4.2, we use dlopen("/unix", 0) and dlsym() to get to the
- * original system select() and poll() functions.
+ * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get
+ * at the original system select() and poll() functions.
*/
#ifndef AIX4_1
+#include <sys/atomic_op.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <dlfcn.h>
@@ -34,13 +35,25 @@ static void *aix_handle = NULL;
static int (*aix_select_fcn)() = NULL;
static int (*aix_poll_fcn)() = NULL;
+PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+ PRIntn oldval;
+ boolean_t stored;
+ oldval = fetch_and_add((atomic_p)val, 0);
+ do
+ {
+ stored = compare_and_swap((atomic_p)val, &oldval, newval);
+ } while (!stored);
+ return oldval;
+} /* _AIX_AtomicSet */
+
int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
{
int rv;
if (!aix_select_fcn) {
if (!aix_handle) {
- aix_handle = dlopen("/unix",0);
+ aix_handle = dlopen("/unix", RTLD_NOW);
if (!aix_handle) {
PR_SetError(PR_UNKNOWN_ERROR, 0);
return -1;
@@ -62,7 +75,7 @@ int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
if (!aix_poll_fcn) {
if (!aix_handle) {
- aix_handle = dlopen("/unix",0);
+ aix_handle = dlopen("/unix", RTLD_NOW);
if (!aix_handle) {
PR_SetError(PR_UNKNOWN_ERROR, 0);
return -1;
@@ -95,10 +108,38 @@ void _pr_aix_dummy()
#if !defined(PTHREADS_USER)
+#ifdef _PR_PTHREADS
+
+/*
+ * AIX 4.3 has sched_yield(). AIX 4.2 has pthread_yield().
+ * So we look up the appropriate function pointer at run time.
+ */
+
+int (*_PT_aix_yield_fcn)() = NULL;
+
+void _MD_EarlyInit(void)
+{
+ void *main_app_handle = NULL;
+
+ main_app_handle = dlopen(NULL, RTLD_NOW);
+ PR_ASSERT(NULL != main_app_handle);
+
+ _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield");
+ if (!_PT_aix_yield_fcn) {
+ _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield");
+ PR_ASSERT(NULL != _PT_aix_yield_fcn);
+ }
+ dlclose(main_app_handle);
+}
+
+#else /* _PR_PTHREADS */
+
void _MD_EarlyInit(void)
{
}
+#endif /* _PR_PTHREADS */
+
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
#ifndef _PR_PTHREADS
diff --git a/pr/src/md/unix/freebsd.c b/pr/src/md/unix/freebsd.c
index 2cedf308..05652483 100644
--- a/pr/src/md/unix/freebsd.c
+++ b/pr/src/md/unix/freebsd.c
@@ -98,135 +98,3 @@ _MD_CREATE_THREAD(
return PR_FAILURE;
}
#endif /* ! _PR_PTHREADS */
-
-#if defined(_PR_NEED_FAKE_POLL)
-
-#include <fcntl.h>
-
-int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
-{
- int i;
- int rv;
- int maxfd;
- fd_set rd, wr, ex;
- struct timeval tv, *tvp;
-
- if (timeout < 0 && timeout != -1) {
- errno = EINVAL;
- return -1;
- }
-
- if (timeout == -1) {
- tvp = NULL;
- } else {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- tvp = &tv;
- }
-
- maxfd = -1;
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- FD_ZERO(&ex);
-
- for (i = 0; i < nfds; i++) {
- int osfd = filedes[i].fd;
- int events = filedes[i].events;
- PRBool fdHasEvent = PR_FALSE;
-
- if (osfd < 0) {
- continue; /* Skip this osfd. */
- }
-
- /*
- * Map the native poll flags to nspr poll flags.
- * POLLIN, POLLRDNORM ===> PR_POLL_READ
- * POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
- * POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
- * POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
- * are ignored.
- *
- * The output events POLLERR and POLLHUP are never turned on.
- * POLLNVAL may be turned on.
- */
-
- if (events & (POLLIN | POLLRDNORM)) {
- FD_SET(osfd, &rd);
- fdHasEvent = PR_TRUE;
- }
- if (events & (POLLOUT | POLLWRNORM)) {
- FD_SET(osfd, &wr);
- fdHasEvent = PR_TRUE;
- }
- if (events & (POLLPRI | POLLRDBAND)) {
- FD_SET(osfd, &ex);
- fdHasEvent = PR_TRUE;
- }
- if (fdHasEvent && osfd > maxfd) {
- maxfd = osfd;
- }
- }
-
- rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
-
- /* Compute poll results */
- if (rv > 0) {
- rv = 0;
- for (i = 0; i < nfds; i++) {
- PRBool fdHasEvent = PR_FALSE;
-
- filedes[i].revents = 0;
- if (filedes[i].fd < 0) {
- continue;
- }
- if (FD_ISSET(filedes[i].fd, &rd)) {
- if (filedes[i].events & POLLIN) {
- filedes[i].revents |= POLLIN;
- }
- if (filedes[i].events & POLLRDNORM) {
- filedes[i].revents |= POLLRDNORM;
- }
- fdHasEvent = PR_TRUE;
- }
- if (FD_ISSET(filedes[i].fd, &wr)) {
- if (filedes[i].events & POLLOUT) {
- filedes[i].revents |= POLLOUT;
- }
- if (filedes[i].events & POLLWRNORM) {
- filedes[i].revents |= POLLWRNORM;
- }
- fdHasEvent = PR_TRUE;
- }
- if (FD_ISSET(filedes[i].fd, &ex)) {
- if (filedes[i].events & POLLPRI) {
- filedes[i].revents |= POLLPRI;
- }
- if (filedes[i].events & POLLRDBAND) {
- filedes[i].revents |= POLLRDBAND;
- }
- fdHasEvent = PR_TRUE;
- }
- if (fdHasEvent) {
- rv++;
- }
- }
- PR_ASSERT(rv > 0);
- } else if (rv == -1 && errno == EBADF) {
- rv = 0;
- for (i = 0; i < nfds; i++) {
- filedes[i].revents = 0;
- if (filedes[i].fd < 0) {
- continue;
- }
- if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
- filedes[i].revents = POLLNVAL;
- rv++;
- }
- }
- PR_ASSERT(rv > 0);
- }
- PR_ASSERT(-1 != timeout || rv != 0);
-
- return rv;
-}
-#endif /* _PR_NEED_FAKE_POLL */
diff --git a/pr/src/md/unix/irix.c b/pr/src/md/unix/irix.c
index 58ebe922..ca49378d 100644
--- a/pr/src/md/unix/irix.c
+++ b/pr/src/md/unix/irix.c
@@ -308,10 +308,11 @@ sigchld_handler(int sig)
if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) ||
(WTERMSIG(status) == SIGBUS) ||
(WTERMSIG(status) == SIGABRT) ||
- (WTERMSIG(status) == SIGILL)))
+ (WTERMSIG(status) == SIGILL))) {
- prctl(PR_SETEXITSIG, SIGKILL);
- exit(status);
+ prctl(PR_SETEXITSIG, SIGKILL);
+ exit(status);
+ }
}
}
@@ -437,19 +438,32 @@ void _PR_IRIX_CHILD_PROCESS()
static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
{
+ int rv;
+
+#ifdef _PR_USE_POLL
+ struct pollfd pfd;
+ int msecs;
+
+ if (timeout == PR_INTERVAL_NO_TIMEOUT)
+ msecs = -1;
+ else
+ msecs = PR_IntervalToMilliseconds(timeout);
+#else
struct timeval tv, *tvp;
fd_set rd;
- int rv;
- if(timeout == PR_INTERVAL_NO_TIMEOUT) tvp = NULL;
- else {
- tv.tv_sec = PR_IntervalToSeconds(timeout);
- tv.tv_usec = PR_IntervalToMicroseconds(
- timeout - PR_SecondsToInterval(tv.tv_sec));
- tvp = &tv;
- }
- FD_ZERO(&rd);
- FD_SET(thread->md.cvar_pollsemfd, &rd);
+ if(timeout == PR_INTERVAL_NO_TIMEOUT)
+ tvp = NULL;
+ else {
+ tv.tv_sec = PR_IntervalToSeconds(timeout);
+ tv.tv_usec = PR_IntervalToMicroseconds(
+ timeout - PR_SecondsToInterval(tv.tv_sec));
+ tvp = &tv;
+ }
+ FD_ZERO(&rd);
+ FD_SET(thread->md.cvar_pollsemfd, &rd);
+#endif
+
/*
* call uspsema only if a previous select call on this semaphore
* did not timeout
@@ -461,8 +475,13 @@ static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
rv = 0;
again:
if(!rv) {
- rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd,
- NULL,NULL,tvp);
+#ifdef _PR_USE_POLL
+ pfd.events = POLLIN;
+ pfd.fd = thread->md.cvar_pollsemfd;
+ rv = _MD_POLL(&pfd, 1, msecs);
+#else
+ rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp);
+#endif
if ((rv == -1) && (errno == EINTR)) {
rv = 0;
goto again;
@@ -559,10 +578,12 @@ PRUint32 stackSize)
PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 pid;
PRStatus rv;
+ PRStatus creation_status;
if (!_PR_IS_NATIVE_THREAD(me))
_PR_INTSOFF(is);
thread->md.cvar_pollsem_select = 0;
+ thread->md.creation_status = &creation_status;
thread->flags |= _PR_GLOBAL_SCOPE;
pid = sprocsp(
spentry, /* startup func */
@@ -579,7 +600,7 @@ PRUint32 stackSize)
blockproc(me->cpu->md.id);
else
blockproc(me->md.id);
- if (thread->md.cvar_pollsemfd < 0) {
+ if (creation_status == PR_FAILURE) {
/*
* the sproc failed to create a polled semaphore and exited
*/
@@ -681,17 +702,21 @@ _MD_InitThread(PRThread *thread, PRBool wakeup_parent)
thread->md.id = getpid();
thread->md.cvar_pollsemfd = -1;
if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
- if (wakeup_parent == PR_TRUE)
+ if (wakeup_parent == PR_TRUE) {
+ *thread->md.creation_status = PR_FAILURE;
unblockproc(getppid());
- rv = PR_FAILURE;
+ }
+ return PR_FAILURE;
}
thread->md.cvar_pollsemfd =
_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
if ((thread->md.cvar_pollsemfd < 0)) {
free_poll_sem(&thread->md);
- if (wakeup_parent == PR_TRUE)
+ if (wakeup_parent == PR_TRUE) {
+ *thread->md.creation_status = PR_FAILURE;
unblockproc(getppid());
- rv = PR_FAILURE;
+ }
+ return PR_FAILURE;
}
setblockproccnt(thread->md.id, 0);
_MD_SET_SPROC_PID(getpid());
@@ -744,8 +769,10 @@ _MD_InitThread(PRThread *thread, PRBool wakeup_parent)
/*
* unblock the parent sproc
*/
- if (wakeup_parent == PR_TRUE)
+ if (wakeup_parent == PR_TRUE) {
+ *thread->md.creation_status = PR_SUCCESS;
unblockproc(getppid());
+ }
}
return rv;
}
@@ -769,7 +796,9 @@ _MD_InitRunningCPU(_PRCPU *cpu)
_MD_SET_SPROC_PID(getpid());
if (_pr_md_pipefd[0] >= 0) {
_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
+#endif
}
}
diff --git a/pr/src/md/unix/linux.c b/pr/src/md/unix/linux.c
index a653f47b..7cea2542 100644
--- a/pr/src/md/unix/linux.c
+++ b/pr/src/md/unix/linux.c
@@ -96,135 +96,3 @@ _MD_CREATE_THREAD(
return PR_FAILURE;
}
#endif /* ! _PR_PTHREADS */
-
-#if defined(_PR_NEED_FAKE_POLL)
-
-#include <fcntl.h>
-
-int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
-{
- int i;
- int rv;
- int maxfd;
- fd_set rd, wr, ex;
- struct timeval tv, *tvp;
-
- if (timeout < 0 && timeout != -1) {
- errno = EINVAL;
- return -1;
- }
-
- if (timeout == -1) {
- tvp = NULL;
- } else {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- tvp = &tv;
- }
-
- maxfd = -1;
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- FD_ZERO(&ex);
-
- for (i = 0; i < nfds; i++) {
- int osfd = filedes[i].fd;
- int events = filedes[i].events;
- PRBool fdHasEvent = PR_FALSE;
-
- if (osfd < 0) {
- continue; /* Skip this osfd. */
- }
-
- /*
- * Map the native poll flags to nspr poll flags.
- * POLLIN, POLLRDNORM ===> PR_POLL_READ
- * POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
- * POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
- * POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
- * are ignored.
- *
- * The output events POLLERR and POLLHUP are never turned on.
- * POLLNVAL may be turned on.
- */
-
- if (events & (POLLIN | POLLRDNORM)) {
- FD_SET(osfd, &rd);
- fdHasEvent = PR_TRUE;
- }
- if (events & (POLLOUT | POLLWRNORM)) {
- FD_SET(osfd, &wr);
- fdHasEvent = PR_TRUE;
- }
- if (events & (POLLPRI | POLLRDBAND)) {
- FD_SET(osfd, &ex);
- fdHasEvent = PR_TRUE;
- }
- if (fdHasEvent && osfd > maxfd) {
- maxfd = osfd;
- }
- }
-
- rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
-
- /* Compute poll results */
- if (rv > 0) {
- rv = 0;
- for (i = 0; i < nfds; i++) {
- PRBool fdHasEvent = PR_FALSE;
-
- filedes[i].revents = 0;
- if (filedes[i].fd < 0) {
- continue;
- }
- if (FD_ISSET(filedes[i].fd, &rd)) {
- if (filedes[i].events & POLLIN) {
- filedes[i].revents |= POLLIN;
- }
- if (filedes[i].events & POLLRDNORM) {
- filedes[i].revents |= POLLRDNORM;
- }
- fdHasEvent = PR_TRUE;
- }
- if (FD_ISSET(filedes[i].fd, &wr)) {
- if (filedes[i].events & POLLOUT) {
- filedes[i].revents |= POLLOUT;
- }
- if (filedes[i].events & POLLWRNORM) {
- filedes[i].revents |= POLLWRNORM;
- }
- fdHasEvent = PR_TRUE;
- }
- if (FD_ISSET(filedes[i].fd, &ex)) {
- if (filedes[i].events & POLLPRI) {
- filedes[i].revents |= POLLPRI;
- }
- if (filedes[i].events & POLLRDBAND) {
- filedes[i].revents |= POLLRDBAND;
- }
- fdHasEvent = PR_TRUE;
- }
- if (fdHasEvent) {
- rv++;
- }
- }
- PR_ASSERT(rv > 0);
- } else if (rv == -1 && errno == EBADF) {
- rv = 0;
- for (i = 0; i < nfds; i++) {
- filedes[i].revents = 0;
- if (filedes[i].fd < 0) {
- continue;
- }
- if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
- filedes[i].revents = POLLNVAL;
- rv++;
- }
- }
- PR_ASSERT(rv > 0);
- }
- PR_ASSERT(-1 != timeout || rv != 0);
-
- return rv;
-}
-#endif /* _PR_NEED_FAKE_POLL */
diff --git a/pr/src/md/unix/os_AIX.s b/pr/src/md/unix/os_AIX.s
index 63ca4e78..48a1f5b1 100644
--- a/pr/src/md/unix/os_AIX.s
+++ b/pr/src/md/unix/os_AIX.s
@@ -15,6 +15,7 @@
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
+
.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4
.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
diff --git a/pr/src/md/unix/os_BSD_386_2.s b/pr/src/md/unix/os_BSD_386_2.s
index 971ac1b2..a47c4a4e 100644
--- a/pr/src/md/unix/os_BSD_386_2.s
+++ b/pr/src/md/unix/os_BSD_386_2.s
@@ -15,6 +15,7 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
+
/*
* os_BSD_386_2.s
* We need to define our own setjmp/longjmp on BSDI 2.x because libc's
diff --git a/pr/src/md/unix/os_ReliantUNIX.s b/pr/src/md/unix/os_ReliantUNIX.s
index 4ac8b0c1..86cb2f06 100644
--- a/pr/src/md/unix/os_ReliantUNIX.s
+++ b/pr/src/md/unix/os_ReliantUNIX.s
@@ -15,6 +15,7 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
+
/* We want position independent code */
#define PIC
diff --git a/pr/src/md/unix/os_SunOS_ultrasparc.s b/pr/src/md/unix/os_SunOS_ultrasparc.s
index b98b820f..1391a9bc 100644
--- a/pr/src/md/unix/os_SunOS_ultrasparc.s
+++ b/pr/src/md/unix/os_SunOS_ultrasparc.s
@@ -1,4 +1,4 @@
-! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
!
! The contents of this file are subject to the Netscape Public License
! Version 1.0 (the "NPL"); you may not use this file except in
diff --git a/pr/src/md/unix/unix.c b/pr/src/md/unix/unix.c
index 9c62e80d..880e8bba 100644
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -28,6 +28,10 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+#endif
+
/* To get FIONREAD */
#if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
|| defined(SONY)
@@ -41,7 +45,7 @@
#if defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
|| defined(AIX4_1) || defined(LINUX) || defined(SONY) \
|| defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
- || defined(SUNOS4)
+ || defined(SUNOS4) || defined(NCR)
#define _PRSockLen_t int
#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
|| defined(UNIXWARE)
@@ -89,7 +93,7 @@ static sigset_t empty_set;
/*
* _nspr_noclock - if set clock interrupts are disabled
*/
-int _nspr_noclock = 0;
+int _nspr_noclock = 1;
#ifdef IRIX
extern PRInt32 _nspr_terminate_on_error;
@@ -380,11 +384,20 @@ PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount)
{
PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 rv, err;
+#ifndef _PR_USE_POLL
fd_set rd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
PRInt32 osfd = fd->secret->md.osfd;
+#ifndef _PR_USE_POLL
FD_ZERO(&rd);
FD_SET(osfd, &rd);
+#else
+ pfd.fd = osfd;
+ pfd.events = POLLIN;
+#endif /* _PR_USE_POLL */
while ((rv = read(osfd,buf,amount)) == -1) {
err = _MD_ERRNO();
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
@@ -394,10 +407,17 @@ PRInt32 osfd = fd->secret->md.osfd;
if (!_PR_IS_NATIVE_THREAD(me)) {
_PR_WaitForFD(osfd, PR_POLL_READ, PR_INTERVAL_NO_TIMEOUT);
} else {
+#ifndef _PR_USE_POLL
while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
== -1 && (err = _MD_ERRNO()) == EINTR) {
/* retry _MD_SELECT() if it is interrupted */
}
+#else /* _PR_USE_POLL */
+ while ((rv = _MD_POLL(&pfd, 1, -1))
+ == -1 && (err = _MD_ERRNO()) == EINTR) {
+ /* retry _MD_POLL() if it is interrupted */
+ }
+#endif /* _PR_USE_POLL */
if (rv == -1) {
break;
}
@@ -425,11 +445,20 @@ PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
{
PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 rv, err;
+#ifndef _PR_USE_POLL
fd_set wd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
PRInt32 osfd = fd->secret->md.osfd;
+#ifndef _PR_USE_POLL
FD_ZERO(&wd);
FD_SET(osfd, &wd);
+#else
+ pfd.fd = osfd;
+ pfd.events = POLLOUT;
+#endif /* _PR_USE_POLL */
while ((rv = write(osfd,buf,amount)) == -1) {
err = _MD_ERRNO();
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
@@ -439,10 +468,17 @@ PRInt32 osfd = fd->secret->md.osfd;
if (!_PR_IS_NATIVE_THREAD(me)) {
_PR_WaitForFD(osfd, PR_POLL_WRITE, PR_INTERVAL_NO_TIMEOUT);
} else {
+#ifndef _PR_USE_POLL
while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
== -1 && (err = _MD_ERRNO()) == EINTR) {
/* retry _MD_SELECT() if it is interrupted */
}
+#else /* _PR_USE_POLL */
+ while ((rv = _MD_POLL(&pfd, 1, -1))
+ == -1 && (err = _MD_ERRNO()) == EINTR) {
+ /* retry _MD_POLL() if it is interrupted */
+ }
+#endif /* _PR_USE_POLL */
if (rv == -1) {
break;
}
@@ -570,11 +606,18 @@ PRInt64 _MD_socketavailable64(PRFileDesc *fd)
#define WRITE_FD 2
/*
+ * socket_io_wait --
+ *
* wait for socket i/o, periodically checking for interrupt
+ *
+ * The first implementation uses select(), for platforms without
+ * poll(). The second (preferred) implementation uses poll().
*/
+#ifndef _PR_USE_POLL
+
static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
- PRIntervalTime timeout)
+ PRIntervalTime timeout)
{
PRInt32 rv = -1;
struct timeval tv, *tvp;
@@ -692,6 +735,114 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
return(rv);
}
+#else /* _PR_USE_POLL */
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+ PRIntervalTime timeout)
+{
+ PRInt32 rv = -1;
+ int msecs;
+ PRThread *me = _PR_MD_CURRENT_THREAD();
+ PRIntervalTime epoch, now, elapsed, remaining;
+ PRInt32 syserror;
+ struct pollfd pfd;
+
+ switch (timeout) {
+ case PR_INTERVAL_NO_WAIT:
+ PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+ break;
+ case PR_INTERVAL_NO_TIMEOUT:
+ /*
+ * This is a special case of the 'default' case below.
+ * Please see the comments there.
+ */
+ msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+ pfd.fd = osfd;
+ if (fd_type == READ_FD) {
+ pfd.events = POLLIN;
+ } else {
+ pfd.events = POLLOUT;
+ }
+ do {
+ rv = _MD_POLL(&pfd, 1, msecs);
+ if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+ _PR_MD_MAP_POLL_ERROR(syserror);
+ break;
+ }
+ if (_PR_PENDING_INTERRUPT(me)) {
+ me->flags &= ~_PR_INTERRUPT;
+ PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+ rv = -1;
+ break;
+ }
+ } while (rv == 0 || (rv == -1 && syserror == EINTR));
+ break;
+ default:
+ now = epoch = PR_IntervalNow();
+ remaining = timeout;
+ pfd.fd = osfd;
+ if (fd_type == READ_FD) {
+ pfd.events = POLLIN;
+ } else {
+ pfd.events = POLLOUT;
+ }
+ do {
+ /*
+ * We block in _MD_POLL for at most
+ * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+ * so that there is an upper limit on the delay
+ * before the interrupt bit is checked.
+ */
+ msecs = PR_IntervalToMilliseconds(remaining);
+ if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
+ msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+ }
+ rv = _MD_POLL(&pfd, 1, msecs);
+ /*
+ * we don't consider EINTR a real error
+ */
+ if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+ _PR_MD_MAP_POLL_ERROR(syserror);
+ break;
+ }
+ if (_PR_PENDING_INTERRUPT(me)) {
+ me->flags &= ~_PR_INTERRUPT;
+ PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+ rv = -1;
+ break;
+ }
+ /*
+ * We loop again if _MD_POLL timed out or got interrupted
+ * by a signal, and the timeout deadline has not passed yet.
+ */
+ if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+ /*
+ * If _MD_POLL timed out, we know how much time
+ * we spent in blocking, so we can avoid a
+ * PR_IntervalNow() call.
+ */
+ if (rv == 0) {
+ now += PR_MillisecondsToInterval(msecs);
+ } else {
+ now = PR_IntervalNow();
+ }
+ elapsed = (PRIntervalTime) (now - epoch);
+ if (elapsed >= timeout) {
+ PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+ rv = -1;
+ break;
+ } else {
+ remaining = timeout - elapsed;
+ }
+ }
+ } while (rv == 0 || (rv == -1 && syserror == EINTR));
+ break;
+ }
+ return(rv);
+}
+
+#endif /* _PR_USE_POLL */
+
PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
PRInt32 flags, PRIntervalTime timeout)
{
@@ -794,14 +945,17 @@ PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
_PR_MD_MAP_RECVFROM_ERROR(err);
}
done:
-#ifdef AIX
+#ifdef _PR_HAVE_SOCKADDR_LEN
if (rv != -1) {
/* mask off the first byte of struct sockaddr (the length field) */
if (addr) {
- addr->inet.family &= 0x00ff;
+ *((unsigned char *) addr) = 0;
+#ifdef IS_LITTLE_ENDIAN
+ addr->raw.family = ntohs(addr->raw.family);
+#endif
}
}
-#endif
+#endif /* _PR_HAVE_SOCKADDR_LEN */
return(rv);
}
@@ -1043,14 +1197,17 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
_PR_MD_MAP_ACCEPT_ERROR(err);
}
done:
-#ifdef AIX
+#ifdef _PR_HAVE_SOCKADDR_LEN
if (rv != -1) {
/* mask off the first byte of struct sockaddr (the length field) */
if (addr) {
- addr->inet.family &= 0x00ff;
+ *((unsigned char *) addr) = 0;
+#ifdef IS_LITTLE_ENDIAN
+ addr->raw.family = ntohs(addr->raw.family);
+#endif
}
}
-#endif
+#endif /* _PR_HAVE_SOCKADDR_LEN */
return(rv);
}
@@ -1198,14 +1355,17 @@ PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
rv = getsockname(fd->secret->md.osfd,
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
-#ifdef AIX
+#ifdef _PR_HAVE_SOCKADDR_LEN
if (rv == 0) {
/* mask off the first byte of struct sockaddr (the length field) */
if (addr) {
- addr->inet.family &= 0x00ff;
+ *((unsigned char *) addr) = 0;
+#ifdef IS_LITTLE_ENDIAN
+ addr->raw.family = ntohs(addr->raw.family);
+#endif
}
}
-#endif
+#endif /* _PR_HAVE_SOCKADDR_LEN */
if (rv < 0) {
err = _MD_ERRNO();
_PR_MD_MAP_GETSOCKNAME_ERROR(err);
@@ -1220,14 +1380,17 @@ PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
rv = getpeername(fd->secret->md.osfd,
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
-#ifdef AIX
+#ifdef _PR_HAVE_SOCKADDR_LEN
if (rv == 0) {
/* mask off the first byte of struct sockaddr (the length field) */
if (addr) {
- addr->inet.family &= 0x00ff;
+ *((unsigned char *) addr) = 0;
+#ifdef IS_LITTLE_ENDIAN
+ addr->raw.family = ntohs(addr->raw.family);
+#endif
}
}
-#endif
+#endif /* _PR_HAVE_SOCKADDR_LEN */
if (rv < 0) {
err = _MD_ERRNO();
_PR_MD_MAP_GETPEERNAME_ERROR(err);
@@ -1272,7 +1435,16 @@ PR_IMPLEMENT(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
_PRCPU *io_cpu;
PRThread *me = _PR_MD_CURRENT_THREAD();
+ if (0 == npds) {
+ PR_Sleep(timeout);
+ return 0;
+ }
+
if (_PR_IS_NATIVE_THREAD(me)) {
+#ifndef _PR_USE_POLL
+ /*
+ * On platforms that don't have poll(), we call select().
+ */
fd_set rd, wt, ex;
struct timeval tv, *tvp = NULL;
int maxfd = -1;
@@ -1398,6 +1570,105 @@ retry:
}
return n;
+#else /* _PR_USE_POLL */
+ /*
+ * For restarting _MD_POLL() if it is interrupted by a signal.
+ * We use these variables to figure out how much time has elapsed
+ * and how much of the timeout still remains.
+ */
+ PRIntervalTime start, elapsed, remaining;
+ int index, msecs;
+ struct pollfd *syspoll;
+
+ syspoll = (struct pollfd *) PR_MALLOC(npds * sizeof(struct pollfd));
+ if (NULL == syspoll) {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return -1;
+ }
+ for (index = 0; index < npds; index++) {
+ PRFileDesc *bottom = pds[index].fd;
+
+ if (NULL == bottom) {
+ /* make poll() ignore this entry */
+ syspoll[index].fd = -1;
+ continue;
+ }
+
+ while (bottom->lower != NULL) {
+ bottom = bottom->lower;
+ }
+ syspoll[index].fd = bottom->secret->md.osfd;
+
+ syspoll[index].events = 0;
+ if (pds[index].in_flags & PR_POLL_READ) {
+ syspoll[index].events |= POLLIN;
+ }
+ if (pds[index].in_flags & PR_POLL_WRITE) {
+ syspoll[index].events |= POLLOUT;
+ }
+ if (pds[index].in_flags & PR_POLL_EXCEPT) {
+ syspoll[index].events |= POLLPRI;
+ }
+ pds[index].out_flags = 0; /* init the result */
+ }
+ if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+ msecs = -1;
+ } else {
+ msecs = PR_IntervalToMilliseconds(timeout);
+ start = PR_IntervalNow();
+ }
+
+retry:
+ n = _MD_POLL(syspoll, npds, msecs);
+ if (n == -1) {
+ err = _MD_ERRNO();
+ if (err == EINTR) {
+ if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+ goto retry;
+ } else if (timeout == PR_INTERVAL_NO_WAIT) {
+ n = 0; /* don't retry, just time out */
+ } else {
+ elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+ if (elapsed > timeout) {
+ n = 0; /* timed out */
+ } else {
+ remaining = timeout - elapsed;
+ msecs = PR_IntervalToMilliseconds(remaining);
+ goto retry;
+ }
+ }
+ } else {
+ _PR_MD_MAP_POLL_ERROR(err);
+ }
+ } else if (n > 0) {
+ for (index = 0; index < npds; index++) {
+ if (NULL == pds[index].fd) {
+ continue;
+ }
+ PR_ASSERT(0 == pds[index].out_flags);
+ if (0 != syspoll[index].revents) {
+ if (syspoll[index].revents & POLLIN) {
+ pds[index].out_flags |= PR_POLL_READ;
+ }
+ if (syspoll[index].revents & POLLOUT) {
+ pds[index].out_flags |= PR_POLL_WRITE;
+ }
+ if (syspoll[index].revents & POLLPRI) {
+ pds[index].out_flags |= PR_POLL_EXCEPT;
+ }
+ if (syspoll[index].revents & POLLERR) {
+ pds[index].out_flags |= PR_POLL_ERR;
+ }
+ if (syspoll[index].revents & POLLNVAL) {
+ pds[index].out_flags |= PR_POLL_NVAL;
+ }
+ }
+ }
+ }
+
+ PR_DELETE(syspoll);
+ return n;
+#endif /* _PR_USE_POLL */
}
/*
@@ -1455,6 +1726,7 @@ retry:
unixpd++;
pdcnt++;
+#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) {
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
_PR_FD_READ_CNT(me->cpu)[osfd]++;
@@ -1467,12 +1739,14 @@ retry:
FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
}
+#endif /* _PR_USE_POLL */
if (osfd > _PR_IOQ_MAX_OSFD(me->cpu))
_PR_IOQ_MAX_OSFD(me->cpu) = osfd;
}
if (timeout < _PR_IOQ_TIMEOUT(me->cpu))
_PR_IOQ_TIMEOUT(me->cpu) = timeout;
+ _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
pq.pds = unixpds;
pq.npds = pdcnt;
@@ -1541,6 +1815,7 @@ retry:
}
osfd = bottom->secret->md.osfd;
PR_ASSERT(osfd >= 0 || in_flags == 0);
+#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) {
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
@@ -1553,7 +1828,10 @@ retry:
if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
}
+#endif
}
+ _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt;
+ PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
}
_PR_MD_IOQ_UNLOCK();
}
@@ -1637,6 +1915,7 @@ static void FindBadFDs(void)
PRInt32 osfd = pds->osfd;
PRInt16 in_flags = pds->in_flags;
PR_ASSERT(osfd >= 0 || in_flags == 0);
+#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) {
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
@@ -1649,6 +1928,7 @@ static void FindBadFDs(void)
if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
}
+#endif /* !_PR_USE_POLL */
}
_PR_THREAD_LOCK(pq->thr);
@@ -1700,6 +1980,7 @@ void _MD_PauseCPU(PRIntervalTime ticks)
struct pollfd *pollfds; /* an array of pollfd structures */
struct pollfd *pollfdPtr; /* a pointer that steps through the array */
unsigned long npollfds; /* number of pollfd structures in array */
+ unsigned long pollfds_size;
int nfd; /* to hold the return value of poll() */
#else
struct timeval timeout, *tvp;
@@ -1723,12 +2004,9 @@ extern sigset_t ints_off;
/* Build up the pollfd structure array to wait on */
/* Find out how many pollfd structures are needed */
- npollfds = 0;
- for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
- PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+ npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
+ PR_ASSERT(npollfds >= 0);
- npollfds += pq->npds;
- }
/*
* We use a pipe to wake up a native thread. An fd is needed
* for the pipe and we poll it for reading.
@@ -1736,8 +2014,21 @@ extern sigset_t ints_off;
if (_PR_IS_NATIVE_THREAD_SUPPORTED())
npollfds++;
- pollfds = (struct pollfd *) PR_MALLOC(npollfds * sizeof(struct pollfd));
- pollfdPtr = pollfds;
+ /*
+ * if the cpu's pollfd array is not big enough, release it and allocate a new one
+ */
+ if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
+ if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
+ PR_DELETE(pollfds);
+ pollfds_size = PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
+ pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
+ _PR_IOQ_POLLFDS(me->cpu) = pollfds;
+ _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
+ pollfdPtr = pollfds;
+ } else {
+ pollfds = _PR_IOQ_POLLFDS(me->cpu);
+ pollfdPtr = pollfds;
+ }
/*
* If we need to poll the pipe for waking up a native thread,
@@ -1769,6 +2060,7 @@ extern sigset_t ints_off;
pollfdPtr->events = pds->in_flags;
}
}
+ _PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
#else
/*
* assigment of fd_sets
@@ -1897,16 +2189,16 @@ extern sigset_t ints_off;
for (; pds < epds; pds++, pollfdPtr++) {
/*
- * Assert that the pollfdPtr pointer does not go beyond
- * the end of the pollfds array.
- */
+ * Assert that the pollfdPtr pointer does not go beyond
+ * the end of the pollfds array.
+ */
PR_ASSERT(pollfdPtr < pollfds + npollfds);
/*
- * Assert that the fd's in the pollfds array (stepped
- * through by pollfdPtr) are in the same order as
- * the fd's in _PR_IOQ() (stepped through by q and pds).
- * This is how the pollfds array was created earlier.
- */
+ * Assert that the fd's in the pollfds array (stepped
+ * through by pollfdPtr) are in the same order as
+ * the fd's in _PR_IOQ() (stepped through by q and pds).
+ * This is how the pollfds array was created earlier.
+ */
PR_ASSERT(pollfdPtr->fd == pds->osfd);
pds->out_flags = pollfdPtr->revents;
/* Negative fd's are ignored by poll() */
@@ -1921,12 +2213,7 @@ extern sigset_t ints_off;
PR_REMOVE_LINK(&pq->links);
pq->on_ioq = PR_FALSE;
- /*
- * Because this thread can run on a different cpu right
- * after being added to the run queue, do not dereference
- * pq
- */
- thred = pq->thr;
+ thred = pq->thr;
_PR_THREAD_LOCK(thred);
if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
_PRCPU *cpu = pq->thr->cpu;
@@ -1944,14 +2231,14 @@ extern sigset_t ints_off;
_PR_MD_WAKEUP_WAITER(thred);
}
_PR_THREAD_UNLOCK(thred);
+ _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;
+ PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
}
}
} else if (nfd == -1) {
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
}
- /* done with pollfds */
- PR_DELETE(pollfds);
#else
if (nfd > 0) {
q = _PR_IOQ(me->cpu).next;
@@ -2136,7 +2423,9 @@ void _MD_InitCPUS()
rv = pipe(_pr_md_pipefd);
PR_ASSERT(rv == 0);
_PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
+#endif
flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);
@@ -2897,6 +3186,8 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
pq.on_ioq = PR_TRUE;
pq.timeout = timeout;
_PR_ADD_TO_IOQ(pq, me->cpu);
+
+#ifndef _PR_USE_POLL
if (how == PR_POLL_READ) {
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
(_PR_FD_READ_CNT(me->cpu))[osfd]++;
@@ -2907,12 +3198,15 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
}
+#endif /* _PR_USE_POLL */
+
if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd)
_PR_IOQ_MAX_OSFD(me->cpu) = osfd;
if (_PR_IOQ_TIMEOUT(me->cpu) > timeout)
_PR_IOQ_TIMEOUT(me->cpu) = timeout;
-
+ _PR_IOQ_OSFD_CNT(me->cpu) += 1;
+
_PR_SLEEPQ_LOCK(me->cpu);
_PR_ADD_SLEEPQ(me, timeout);
me->state = _PR_IO_WAIT;
@@ -2944,17 +3238,21 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
*/
if (pq.on_ioq) {
PR_REMOVE_LINK(&pq.links);
- if (how == PR_POLL_READ) {
- if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0)
- FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
-
- } else if (how == PR_POLL_WRITE) {
- if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
- FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
- } else {
- if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0)
- FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
- }
+#ifndef _PR_USE_POLL
+ if (how == PR_POLL_READ) {
+ if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0)
+ FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+
+ } else if (how == PR_POLL_WRITE) {
+ if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
+ FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+ } else {
+ if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0)
+ FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+ }
+#endif /* _PR_USE_POLL */
+ PR_ASSERT(pq.npds == 1);
+ _PR_IOQ_OSFD_CNT(me->cpu) -= 1;
}
_PR_MD_IOQ_UNLOCK();
rv = 0;
@@ -3238,3 +3536,140 @@ PRStatus _MD_CloseFileMap(PRFileMap *fmap)
PR_DELETE(fmap);
return PR_SUCCESS;
}
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll(). For easier porting of code
+ * that calls poll(), we emulate poll() using select().
+ */
+
+#include <fcntl.h>
+
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+{
+ int i;
+ int rv;
+ int maxfd;
+ fd_set rd, wr, ex;
+ struct timeval tv, *tvp;
+
+ if (timeout < 0 && timeout != -1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (timeout == -1) {
+ tvp = NULL;
+ } else {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tvp = &tv;
+ }
+
+ maxfd = -1;
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_ZERO(&ex);
+
+ for (i = 0; i < nfds; i++) {
+ int osfd = filedes[i].fd;
+ int events = filedes[i].events;
+ PRBool fdHasEvent = PR_FALSE;
+
+ if (osfd < 0) {
+ continue; /* Skip this osfd. */
+ }
+
+ /*
+ * Map the native poll flags to nspr poll flags.
+ * POLLIN, POLLRDNORM ===> PR_POLL_READ
+ * POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
+ * POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
+ * POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+ * are ignored.
+ *
+ * The output events POLLERR and POLLHUP are never turned on.
+ * POLLNVAL may be turned on.
+ */
+
+ if (events & (POLLIN | POLLRDNORM)) {
+ FD_SET(osfd, &rd);
+ fdHasEvent = PR_TRUE;
+ }
+ if (events & (POLLOUT | POLLWRNORM)) {
+ FD_SET(osfd, &wr);
+ fdHasEvent = PR_TRUE;
+ }
+ if (events & (POLLPRI | POLLRDBAND)) {
+ FD_SET(osfd, &ex);
+ fdHasEvent = PR_TRUE;
+ }
+ if (fdHasEvent && osfd > maxfd) {
+ maxfd = osfd;
+ }
+ }
+
+ rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
+
+ /* Compute poll results */
+ if (rv > 0) {
+ rv = 0;
+ for (i = 0; i < nfds; i++) {
+ PRBool fdHasEvent = PR_FALSE;
+
+ filedes[i].revents = 0;
+ if (filedes[i].fd < 0) {
+ continue;
+ }
+ if (FD_ISSET(filedes[i].fd, &rd)) {
+ if (filedes[i].events & POLLIN) {
+ filedes[i].revents |= POLLIN;
+ }
+ if (filedes[i].events & POLLRDNORM) {
+ filedes[i].revents |= POLLRDNORM;
+ }
+ fdHasEvent = PR_TRUE;
+ }
+ if (FD_ISSET(filedes[i].fd, &wr)) {
+ if (filedes[i].events & POLLOUT) {
+ filedes[i].revents |= POLLOUT;
+ }
+ if (filedes[i].events & POLLWRNORM) {
+ filedes[i].revents |= POLLWRNORM;
+ }
+ fdHasEvent = PR_TRUE;
+ }
+ if (FD_ISSET(filedes[i].fd, &ex)) {
+ if (filedes[i].events & POLLPRI) {
+ filedes[i].revents |= POLLPRI;
+ }
+ if (filedes[i].events & POLLRDBAND) {
+ filedes[i].revents |= POLLRDBAND;
+ }
+ fdHasEvent = PR_TRUE;
+ }
+ if (fdHasEvent) {
+ rv++;
+ }
+ }
+ PR_ASSERT(rv > 0);
+ } else if (rv == -1 && errno == EBADF) {
+ rv = 0;
+ for (i = 0; i < nfds; i++) {
+ filedes[i].revents = 0;
+ if (filedes[i].fd < 0) {
+ continue;
+ }
+ if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
+ filedes[i].revents = POLLNVAL;
+ rv++;
+ }
+ }
+ PR_ASSERT(rv > 0);
+ }
+ PR_ASSERT(-1 != timeout || rv != 0);
+
+ return rv;
+}
+#endif /* _PR_NEED_FAKE_POLL */
diff --git a/pr/src/md/unix/unix_errors.c b/pr/src/md/unix/unix_errors.c
index 92d96c73..802125e3 100644
--- a/pr/src/md/unix/unix_errors.c
+++ b/pr/src/md/unix/unix_errors.c
@@ -1412,6 +1412,26 @@ void _MD_unix_map_select_error(int err)
}
}
+void _MD_unix_map_poll_error(int err)
+{
+ PRErrorCode prerror;
+ switch (err) {
+ case EAGAIN:
+ prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+ break;
+ case EINVAL:
+ prerror = PR_INVALID_ARGUMENT_ERROR;
+ break;
+ case EFAULT:
+ prerror = PR_ACCESS_FAULT_ERROR;
+ break;
+ default:
+ prerror = PR_UNKNOWN_ERROR;
+ break;
+ }
+ PR_SetError(prerror, err);
+}
+
void _MD_unix_map_flock_error(int err)
{
switch (err) {
diff --git a/pr/src/md/windows/ntio.c b/pr/src/md/windows/ntio.c
index e9c5779c..c41b0ab3 100644
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -2945,7 +2945,7 @@ PRInt32 IsFileLocal(HANDLE hFile)
}
#endif /* _NEED_351_FILE_LOCKING_HACK */
-void PR_NT_UseNonblock()
+PR_IMPLEMENT(void) PR_NT_UseNonblock()
{
_nt_use_async = 0;
}
diff --git a/pr/src/md/windows/ntmisc.c b/pr/src/md/windows/ntmisc.c
index 729bce4d..bc2ea6af 100644
--- a/pr/src/md/windows/ntmisc.c
+++ b/pr/src/md/windows/ntmisc.c
@@ -60,7 +60,7 @@ PRIntn _PR_MD_PUT_ENV(const char *name)
*-----------------------------------------------------------------------
*/
-PRTime
+PR_IMPLEMENT(PRTime)
PR_Now(void)
{
PRInt64 s, ms, ms2us, s2us;
@@ -601,3 +601,51 @@ PRStatus _MD_CloseFileMap(PRFileMap *fmap)
PR_DELETE(fmap);
return PR_SUCCESS;
}
+
+/*
+ ***********************************************************************
+ *
+ * Atomic increment and decrement operations for x86 processors
+ *
+ * We don't use InterlockedIncrement and InterlockedDecrement
+ * because on NT 3.51 and Win95, they return a number with
+ * the same sign as the incremented/decremented result, rather
+ * than the result itself. On NT 4.0 these functions do return
+ * the incremented/decremented result.
+ *
+ * The result is returned in the eax register by the inline
+ * assembly code. We disable the harmless "no return value"
+ * warning (4035) for these two functions.
+ *
+ ***********************************************************************
+ */
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+ __asm
+ {
+ mov ecx, val
+ mov eax, 1
+ xadd dword ptr [ecx], eax
+ inc eax
+ }
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+ __asm
+ {
+ mov ecx, val
+ mov eax, 0ffffffffh
+ xadd dword ptr [ecx], eax
+ dec eax
+ }
+}
+#pragma warning(default: 4035)
+
+#endif /* x86 processors */
diff --git a/pr/src/md/windows/ntthread.c b/pr/src/md/windows/ntthread.c
index 885a0953..91257aaf 100644
--- a/pr/src/md/windows/ntthread.c
+++ b/pr/src/md/windows/ntthread.c
@@ -191,31 +191,33 @@ _PR_MD_YIELD(void)
void
_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
{
-#if 0
- /* XXXMB - does this work? Should we really set the priorities of
- * native threads? */
- if( newPri < 4 ) {
- newPri = (PRUintn)THREAD_PRIORITY_IDLE;
- } else if( newPri < 8 ) {
- newPri = (PRUintn)THREAD_PRIORITY_LOWEST;
- } else if( newPri < 12 ) {
- newPri = (PRUintn)THREAD_PRIORITY_BELOW_NORMAL;
- } else if( newPri < 16 ) {
- newPri = (PRUintn)THREAD_PRIORITY_NORMAL;
- } else if( newPri < 24 ) {
- newPri = (PRUintn)THREAD_PRIORITY_ABOVE_NORMAL;
- } else if( newPri < 28 ) {
- newPri = (PRUintn)THREAD_PRIORITY_HIGHEST;
- } else if( newPri < 32 ) {
- newPri = (PRUintn)THREAD_PRIORITY_TIME_CRITICAL;
- }
-
- if( ! SetThreadPriority( thread->handle, newPri ) ) {
- PR_LOG(_pr_thread_lm, PR_LOG_MIN,
- ("PR_SetThreadPriority: can't set thread priority\n"));
- }
-#endif
+ int nativePri;
+ BOOL rv;
+ if (newPri < PR_PRIORITY_FIRST) {
+ newPri = PR_PRIORITY_FIRST;
+ } else if (newPri > PR_PRIORITY_LAST) {
+ newPri = PR_PRIORITY_LAST;
+ }
+ switch (newPri) {
+ case PR_PRIORITY_LOW:
+ nativePri = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case PR_PRIORITY_NORMAL:
+ nativePri = THREAD_PRIORITY_NORMAL;
+ break;
+ case PR_PRIORITY_HIGH:
+ nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case PR_PRIORITY_URGENT:
+ nativePri = THREAD_PRIORITY_HIGHEST;
+ }
+ rv = SetThreadPriority(thread->handle, nativePri);
+ PR_ASSERT(rv);
+ if (!rv) {
+ PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+ ("PR_SetThreadPriority: can't set thread priority\n"));
+ }
return;
}
diff --git a/pr/src/md/windows/w16null.c b/pr/src/md/windows/w16null.c
index a32e83d6..bd505697 100644
--- a/pr/src/md/windows/w16null.c
+++ b/pr/src/md/windows/w16null.c
@@ -42,7 +42,7 @@ _PRInterruptTable _pr_interruptTable[] = { { 0 } };
#if defined(HAVE_WATCOM_BUG_2)
PRTime __pascal __export __loadds
#else
-PRTime
+PR_IMPLEMENT(PRTime)
#endif
PR_Now(void)
{
diff --git a/pr/src/md/windows/w95thred.c b/pr/src/md/windows/w95thred.c
index 0b333b85..41da9922 100644
--- a/pr/src/md/windows/w95thred.c
+++ b/pr/src/md/windows/w95thred.c
@@ -22,9 +22,15 @@
extern void _PR_Win32InitTimeZone(void); /* defined in ntmisc.c */
/* --- globals ------------------------------------------------ */
+#ifdef _PR_USE_STATIC_TLS
__declspec(thread) struct PRThread *_pr_thread_last_run;
__declspec(thread) struct PRThread *_pr_currentThread;
__declspec(thread) struct _PRCPU *_pr_currentCPU;
+#else
+DWORD _pr_currentThreadIndex;
+DWORD _pr_lastThreadIndex;
+DWORD _pr_currentCPUIndex;
+#endif
int _pr_intsOff = 0;
_PRInterruptTable _pr_interruptTable[] = { { 0 } };
@@ -32,11 +38,23 @@ void
_PR_MD_EARLY_INIT()
{
_PR_Win32InitTimeZone();
+
+#ifndef _PR_USE_STATIC_TLS
+ _pr_currentThreadIndex = TlsAlloc();
+ _pr_lastThreadIndex = TlsAlloc();
+ _pr_currentCPUIndex = TlsAlloc();
+#endif
}
void _PR_MD_CLEANUP_BEFORE_EXIT(void)
{
WSACleanup();
+
+#ifndef _PR_USE_STATIC_TLS
+ TlsFree(_pr_currentThreadIndex);
+ TlsFree(_pr_lastThreadIndex);
+ TlsFree(_pr_currentCPUIndex);
+#endif
}
void
diff --git a/pr/src/md/windows/win32_errors.c b/pr/src/md/windows/win32_errors.c
index df271678..884d8ce1 100644
--- a/pr/src/md/windows/win32_errors.c
+++ b/pr/src/md/windows/win32_errors.c
@@ -18,6 +18,7 @@
#include "prerror.h"
#include <errno.h>
+#include <windows.h>
void _MD_win32_map_opendir_error(PRInt32 err)
{
diff --git a/pr/src/misc/pratom.c b/pr/src/misc/pratom.c
index c7eccae0..78ba8173 100644
--- a/pr/src/misc/pratom.c
+++ b/pr/src/misc/pratom.c
@@ -47,30 +47,42 @@ void _PR_MD_INIT_ATOMIC()
}
}
-PR_IMPLEMENT(PRInt32)
+PRInt32
_PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
{
PRInt32 rv;
+
+ if (!_pr_initialized) {
+ _PR_ImplicitInitialization();
+ }
PR_Lock(monitor);
rv = ++(*val);
PR_Unlock(monitor);
return rv;
}
-PR_IMPLEMENT(PRInt32)
+PRInt32
_PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
{
PRInt32 rv;
+
+ if (!_pr_initialized) {
+ _PR_ImplicitInitialization();
+ }
PR_Lock(monitor);
rv = --(*val);
PR_Unlock(monitor);
return rv;
}
-PR_IMPLEMENT(PRInt32)
+PRInt32
_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
{
PRInt32 rv;
+
+ if (!_pr_initialized) {
+ _PR_ImplicitInitialization();
+ }
PR_Lock(monitor);
rv = *val;
*val = newval;
diff --git a/pr/src/misc/prdtoa.c b/pr/src/misc/prdtoa.c
index a9253617..ef3d50a0 100644
--- a/pr/src/misc/prdtoa.c
+++ b/pr/src/misc/prdtoa.c
@@ -1,4 +1,20 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
#include "primpl.h"
@@ -30,12 +46,12 @@
dmg@research.att.com or research!dmg
*/
-/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+/* PR_strtod for IEEE-, VAX-, and IBM-arithmetic machines.
*
- * This strtod returns a nearest machine number to the input decimal
- * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
- * broken by the IEEE round-even rule. Otherwise ties are broken by
- * biased rounding (add half and chop).
+ * This PR_strtod returns a nearest machine number to the input decimal
+ * string (or sets the error code to PR_RANGE_ERROR). With IEEE
+ * arithmetic, ties are broken by the IEEE round-even rule. Otherwise
+ * ties are broken by biased rounding (add half and chop).
*
* Inspired loosely by William D. Clinger's paper "How to Read Floating
* Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
@@ -124,7 +140,6 @@ extern void *MALLOC(size_t);
#define MALLOC PR_MALLOC
#endif
-#include "errno.h"
#ifdef Bad_float_h
#undef __STDC__
#ifdef IEEE_MC68k
@@ -1351,7 +1366,7 @@ dig_done:
if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) {
ovfl:
- errno = ERANGE;
+ PR_SetError(PR_RANGE_ERROR, 0);
#ifdef __STDC__
rv = HUGE_VAL;
#else
@@ -1410,7 +1425,7 @@ dig_done:
if (!rv) {
undfl:
rv = 0.;
- errno = ERANGE;
+ PR_SetError(PR_RANGE_ERROR, 0);
if (bd0)
goto retfree;
goto ret;
@@ -1792,647 +1807,7 @@ quorem(Bigint *b, Bigint *S)
return (int)q;
}
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
- *
- * Inspired by "How to Print Floating-Point Numbers Accurately" by
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- * 1. Rather than iterating, we use a simple numeric overestimate
- * to determine k = floor(log10(d)). We scale relevant
- * quantities using O(log2(k)) rather than O(k) multiplications.
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
- * try to generate digits strictly left to right. Instead, we
- * compute with fewer bits and propagate the carry if necessary
- * when rounding the final digit up. This is often faster.
- * 3. Under the assumption that input will be rounded nearest,
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
- * That is, we allow equality in stopping tests when the
- * round-nearest rule will give the same floating-point value
- * as would satisfaction of the stopping test with strict
- * inequality.
- * 4. We remove common factors of powers of 2 from relevant
- * quantities.
- * 5. When converting floating-point integers less than 1e16,
- * we use floating-point arithmetic rather than resorting
- * to multiple-precision integers.
- * 6. When asked to produce fewer than 15 digits, we first try
- * to get by with floating-point arithmetic; we resort to
- * multiple-precision integer arithmetic only if we cannot
- * guarantee that the floating-point calculation has given
- * the correctly rounded result. For k requested digits and
- * "uniformly" distributed input, the probability is
- * something like 10^(k-15) that we must resort to the Long
- * calculation.
- */
-
-PR_IMPLEMENT(char *)
-PR_dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
-{
- /* Arguments ndigits, decpt, sign are similar to those
- of ecvt and fcvt; trailing zeros are suppressed from
- the returned string. If not null, *rve is set to point
- to the end of the return value. If d is +-Infinity or NaN,
- then *decpt is set to 9999.
-
- mode:
- 0 ==> shortest string that yields d when read in
- and rounded to nearest.
- 1 ==> like 0, but with Steele & White stopping rule;
- e.g. with IEEE P754 arithmetic , mode 0 gives
- 1e23 whereas mode 1 gives 9.999999999999999e22.
- 2 ==> max(1,ndigits) significant digits. This gives a
- return value similar to that of ecvt, except
- that trailing zeros are suppressed.
- 3 ==> through ndigits past the decimal point. This
- gives a return value similar to that from fcvt,
- except that trailing zeros are suppressed, and
- ndigits can be negative.
- 4-9 should give the same return values as 2-3, i.e.,
- 4 <= mode <= 9 ==> same return as mode
- 2 + (mode & 1). These modes are mainly for
- debugging; often they run slower but sometimes
- faster than modes 2-3.
- 4,5,8,9 ==> left-to-right digit generation.
- 6-9 ==> don't try fast floating-point estimate
- (if applicable).
-
- Values of mode other than 0-9 are treated as mode 0.
-
- Sufficient space is allocated to the return value
- to hold the suppressed trailing zeros.
- */
-
- PRInt32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
- j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
- spec_case, try_quick;
- Long L;
-#ifndef Sudden_Underflow
- PRInt32 denorm;
- unsigned Long x;
-#endif
- Bigint *b, *b1, *delta, *mlo, *mhi, *S;
- double d2, ds, eps;
- char *s, *s0;
- static Bigint *result;
- static PRInt32 result_k;
-
- if (!_pr_initialized) _PR_ImplicitInitialization();
-
- if (result) {
- result->k = result_k;
- result->maxwds = 1 << result_k;
- Bfree(result);
- result = 0;
- }
-
- if (word0(d) & Sign_bit) {
- /* set sign for everything, including 0's and NaNs */
- *sign = 1;
- word0(d) &= ~Sign_bit; /* clear sign bit */
- }
- else
- *sign = 0;
-
-#if defined(IEEE_Arith) + defined(VAX)
-#ifdef IEEE_Arith
- if ((word0(d) & Exp_mask) == Exp_mask)
-#else
- if (word0(d) == 0x8000)
-#endif
- {
- /* Infinity or NaN */
- *decpt = 9999;
- s =
-#ifdef IEEE_Arith
- !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
-#endif
- "NaN";
- if (rve)
- *rve =
-#ifdef IEEE_Arith
- s[3] ? s + 8 :
-#endif
- s + 3;
- return s;
- }
-#endif
-#ifdef IBM
- d += 0; /* normalize */
-#endif
- if (!d) {
- *decpt = 1;
- s = "0";
- if (rve)
- *rve = s + 1;
- return s;
- }
-
- b = d2b(d, &be, &bbits);
-#ifdef Sudden_Underflow
- i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
-#else
- if ((i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
-#endif
- d2 = d;
- word0(d2) &= Frac_mask1;
- word0(d2) |= Exp_11;
-#ifdef IBM
- if (j = 11 - hi0bits(word0(d2) & Frac_mask))
- d2 /= 1 << j;
-#endif
-
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
- * log10(x) = log(x) / log(10)
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
- *
- * This suggests computing an approximation k to log10(d) by
- *
- * k = (i - Bias)*0.301029995663981
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
- *
- * We want k to be too large rather than too small.
- * The error in the first-order Taylor series approximation
- * is in our favor, so we just round up the constant enough
- * to compensate for any error in the multiplication of
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
- * adding 1e-13 to the constant term more than suffices.
- * Hence we adjust the constant term to 0.1760912590558.
- * (We could get a more accurate k by invoking log10,
- * but this is probably not worthwhile.)
- */
-
- i -= Bias;
-#ifdef IBM
- i <<= 2;
- i += j;
-#endif
-#ifndef Sudden_Underflow
- denorm = 0;
- }
- else {
- /* d is denormalized */
-
- i = bbits + be + (Bias + (P-1) - 1);
- x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
- : word1(d) << (32 - i);
- d2 = x;
- word0(d2) -= 31*Exp_msk1; /* adjust exponent */
- i -= (Bias + (P-1) - 1) + 1;
- denorm = 1;
- }
-#endif
- ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
- k = (PRInt32)ds;
- if (ds < 0. && ds != k)
- k--; /* want k = floor(ds) */
- k_check = 1;
- if (k >= 0 && k <= Ten_pmax) {
- if (d < tens[k])
- k--;
- k_check = 0;
- }
- j = bbits - i - 1;
- if (j >= 0) {
- b2 = 0;
- s2 = j;
- }
- else {
- b2 = -j;
- s2 = 0;
- }
- if (k >= 0) {
- b5 = 0;
- s5 = k;
- s2 += k;
- }
- else {
- b2 -= k;
- b5 = -k;
- s5 = 0;
- }
- if (mode < 0 || mode > 9)
- mode = 0;
- try_quick = 1;
- if (mode > 5) {
- mode -= 4;
- try_quick = 0;
- }
- leftright = 1;
- switch(mode) {
- case 0:
- case 1:
- ilim = ilim1 = -1;
- i = 18;
- ndigits = 0;
- break;
- case 2:
- leftright = 0;
- /* no break */
- case 4:
- if (ndigits <= 0)
- ndigits = 1;
- ilim = ilim1 = i = ndigits;
- break;
- case 3:
- leftright = 0;
- /* no break */
- case 5:
- i = ndigits + k + 1;
- ilim = i;
- ilim1 = i - 1;
- if (i <= 0)
- i = 1;
- }
- j = sizeof(unsigned Long);
- for(result_k = 0; sizeof(Bigint) - sizeof(unsigned Long) <= i - j;
- j <<= 1) result_k++;
- result = Balloc(result_k);
- s = s0 = (char *)result;
-
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {
-
- /* Try to get by with floating-point arithmetic. */
-
- i = 0;
- d2 = d;
- k0 = k;
- ilim0 = ilim;
- ieps = 2; /* conservative */
- if (k > 0) {
- ds = tens[k&0xf];
- j = k >> 4;
- if (j & Bletch) {
- /* prevent overflows */
- j &= Bletch - 1;
- d /= bigtens[n_bigtens-1];
- ieps++;
- }
- for(; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- ds *= bigtens[i];
- }
- d /= ds;
- }
- else if ((j1 = -k) != 0) {
- d *= tens[j1 & 0xf];
- for(j = j1 >> 4; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- d *= bigtens[i];
- }
- }
- if (k_check && d < 1. && ilim > 0) {
- if (ilim1 <= 0)
- goto fast_failed;
- ilim = ilim1;
- k--;
- d *= 10.;
- ieps++;
- }
- eps = ieps*d + 7.;
- word0(eps) -= (P-1)*Exp_msk1;
- if (ilim == 0) {
- S = mhi = 0;
- d -= 5.;
- if (d > eps)
- goto one_digit;
- if (d < -eps)
- goto no_digits;
- goto fast_failed;
- }
-#ifndef No_leftright
- if (leftright) {
- /* Use Steele & White method of only
- * generating digits needed.
- */
- eps = 0.5/tens[ilim-1] - eps;
- for(i = 0;;) {
- L = (Long) d;
- d -= L;
- *s++ = '0' + (PRInt32)L;
- if (d < eps)
- goto ret1;
- if (1. - d < eps)
- goto bump_up;
- if (++i >= ilim)
- break;
- eps *= 10.;
- d *= 10.;
- }
- }
- else {
-#endif
- /* Generate ilim digits, then fix them up. */
- eps *= tens[ilim-1];
- for(i = 1;; i++, d *= 10.) {
- L = (Long) d;
- d -= L;
- *s++ = '0' + (PRInt32)L;
- if (i == ilim) {
- if (d > 0.5 + eps)
- goto bump_up;
- else if (d < 0.5 - eps) {
- while(*--s == '0'){} /* just count -- nothing to execute */
- s++;
- goto ret1;
- }
- break;
- }
- }
-#ifndef No_leftright
- }
-#endif
- fast_failed:
- s = s0;
- d = d2;
- k = k0;
- ilim = ilim0;
- }
-
- /* Do we have a "small" integer? */
-
- if (be >= 0 && k <= Int_max) {
- /* Yes. */
- ds = tens[k];
- if (ndigits < 0 && ilim <= 0) {
- S = mhi = 0;
- if (ilim < 0 || d <= 5*ds)
- goto no_digits;
- goto one_digit;
- }
- for(i = 1;; i++) {
- L = (Long) (d / ds);
- d -= L*ds;
-#ifdef Check_FLT_ROUNDS
- /* If FLT_ROUNDS == 2, L will usually be high by 1 */
- if (d < 0) {
- L--;
- d += ds;
- }
-#endif
- *s++ = '0' + (PRInt32)L;
- if (i == ilim) {
- d += d;
- if ((d > ds) || (d == ds && L & 1)) {
- bump_up:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s = '0';
- break;
- }
- ++*s++;
- }
- break;
- }
- if (!(d *= 10.))
- break;
- }
- goto ret1;
- }
-
- m2 = b2;
- m5 = b5;
- mhi = mlo = 0;
- if (leftright) {
- if (mode < 2) {
- i =
-#ifndef Sudden_Underflow
- denorm ? be + (Bias + (P-1) - 1 + 1) :
-#endif
-#ifdef IBM
- 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
-#else
- 1 + P - bbits;
-#endif
- }
- else {
- j = ilim - 1;
- if (m5 >= j)
- m5 -= j;
- else {
- s5 += j -= m5;
- b5 += j;
- m5 = 0;
- }
- if ((i = ilim) < 0) {
- m2 -= i;
- i = 0;
- }
- }
- b2 += i;
- s2 += i;
- mhi = i2b(1);
- }
- if (m2 > 0 && s2 > 0) {
- i = m2 < s2 ? m2 : s2;
- b2 -= i;
- m2 -= i;
- s2 -= i;
- }
- if (b5 > 0) {
- if (leftright) {
- if (m5 > 0) {
- mhi = pow5mult(mhi, m5);
- b1 = mult(mhi, b);
- Bfree(b);
- b = b1;
- }
- if ((j = b5 - m5) != 0)
- b = pow5mult(b, j);
- }
- else
- b = pow5mult(b, b5);
- }
- S = i2b(1);
- if (s5 > 0)
- S = pow5mult(S, s5);
-
- /* Check for special case that d is a normalized power of 2. */
-
- if (mode < 2) {
- if (!word1(d) && !(word0(d) & Bndry_mask)
-#ifndef Sudden_Underflow
- && word0(d) & Exp_mask
-#endif
- ) {
- /* The special case */
- b2 += Log2P;
- s2 += Log2P;
- spec_case = 1;
- }
- else
- spec_case = 0;
- }
-
- /* Arrange for convenient computation of quotients:
- * shift left if necessary so divisor has 4 leading 0 bits.
- *
- * Perhaps we should just compute leading 28 bits of S once
- * and for all and pass them and a shift to quorem, so it
- * can do shifts and ors to compute the numerator for q.
- */
-#ifdef Pack_32
- if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
- i = 32 - i;
-#else
- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
- i = 16 - i;
-#endif
- if (i > 4) {
- i -= 4;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- else if (i < 4) {
- i += 28;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- if (b2 > 0)
- b = lshift(b, b2);
- if (s2 > 0)
- S = lshift(S, s2);
- if (k_check) {
- if (cmp(b,S) < 0) {
- k--;
- b = multadd(b, 10, 0); /* we botched the k estimate */
- if (leftright)
- mhi = multadd(mhi, 10, 0);
- ilim = ilim1;
- }
- }
- if (ilim <= 0 && mode > 2) {
- if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
- /* no digits, fcvt style */
- no_digits:
- k = -1 - ndigits;
- goto ret;
- }
- one_digit:
- *s++ = '1';
- k++;
- goto ret;
- }
- if (leftright) {
- if (m2 > 0)
- mhi = lshift(mhi, m2);
-
- /* Compute mlo -- check for special case
- * that d is a normalized power of 2.
- */
-
- mlo = mhi;
- if (spec_case) {
- mhi = Balloc(mhi->k);
- Bcopy(mhi, mlo);
- mhi = lshift(mhi, Log2P);
- }
-
- for(i = 1;;i++) {
- dig = quorem(b,S) + '0';
- /* Do we yet have the shortest decimal string
- * that will round to d?
- */
- j = cmp(b, mlo);
- delta = diff(S, mhi);
- j1 = delta->sign ? 1 : cmp(b, delta);
- Bfree(delta);
-#ifndef ROUND_BIASED
- if (j1 == 0 && !mode && !(word1(d) & 1)) {
- if (dig == '9')
- goto round_9_up;
- if (j > 0)
- dig++;
- *s++ = dig;
- goto ret;
- }
-#endif
- if ((j < 0) || ((j == 0) && (!mode)
-#ifndef ROUND_BIASED
- && (!(word1(d) & 1)))
-#endif
- ) {
- if (j1 > 0) {
- b = lshift(b, 1);
- j1 = cmp(b, S);
- if (((j1 > 0) || (j1 == 0 && dig & 1))
- && (dig++ == '9'))
- goto round_9_up;
- }
- *s++ = dig;
- goto ret;
- }
- if (j1 > 0) {
- if (dig == '9') { /* possible if i == 1 */
- round_9_up:
- *s++ = '9';
- goto roundoff;
- }
- *s++ = dig + 1;
- goto ret;
- }
- *s++ = dig;
- if (i == ilim)
- break;
- b = multadd(b, 10, 0);
- if (mlo == mhi)
- mlo = mhi = multadd(mhi, 10, 0);
- else {
- mlo = multadd(mlo, 10, 0);
- mhi = multadd(mhi, 10, 0);
- }
- }
- }
- else
- for(i = 1;; i++) {
- *s++ = dig = quorem(b,S) + '0';
- if (i >= ilim)
- break;
- b = multadd(b, 10, 0);
- }
-
- /* Round off last digit */
-
- b = lshift(b, 1);
- j = cmp(b, S);
- if ((j > 0) || (j == 0 && dig & 1)) {
- roundoff:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s++ = '1';
- goto ret;
- }
- ++*s++;
- }
- else {
- while(*--s == '0'){} /* just count -- nothing to execute */
- s++;
- }
-ret:
- Bfree(S);
- if (mhi) {
- if (mlo && mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
-ret1:
- Bfree(b);
- *s = 0;
- *decpt = k + 1;
- if (rve)
- *rve = s;
- return s0;
-}
-
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+/* PR_dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
@@ -2467,7 +1842,7 @@ ret1:
*/
PR_IMPLEMENT(PRStatus)
-PR_dtoa_r(double d, int mode, int ndigits,
+PR_dtoa(double d, int mode, int ndigits,
int *decpt, int *sign, char **rve, char *buf, PRSize bufsize)
{
/* Arguments ndigits, decpt, sign are similar to those
@@ -3123,7 +2498,7 @@ PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
return;
}
/* XXX Why use mode 1? */
- if (PR_dtoa_r(fval,1,prcsn,&decpt,&sign,&endnum,num,bufsz)
+ if (PR_dtoa(fval,1,prcsn,&decpt,&sign,&endnum,num,bufsz)
== PR_FAILURE) {
buf[0] = '\0';
goto done;
@@ -3156,13 +2531,18 @@ PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
PR_snprintf(bufp,bufsz - (bufp - buf), "%+d",decpt-1);
}
else if(decpt >= 0){
- while(decpt--){
+ if(decpt == 0){
+ *bufp++ = '0';
+ }
+ else {
+ while(decpt--){
if(*nump != '\0'){
*bufp++ = *nump++;
}
else {
*bufp++ = '0';
}
+ }
}
if(*nump != '\0'){
*bufp++ = '.';
diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c
index 247aadb9..31d14702 100644
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -63,6 +63,8 @@ PRLock *_pr_terminationCVLock;
#endif /* !defined(_PR_PTHREADS) */
+PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */
+
static void _PR_InitCallOnce(void);
static void _PR_InitStuff(void);
@@ -114,6 +116,9 @@ static void _PR_InitStuff()
_PR_InitEnv();
_PR_InitLayerCache();
+ _pr_sleeplock = PR_NewLock();
+ PR_ASSERT(NULL != _pr_sleeplock);
+
_PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
#ifdef WIN16
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index acb6b5e3..74bf7aba 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -78,7 +78,8 @@ static sigset_t timer_set;
#define _PR_HAVE_GETPROTO_R_POINTER
#endif
-#if defined(OSF1) || (defined(AIX) && defined(_THREAD_SAFE)) \
+#if defined(OSF1) \
+ || defined(AIX4_3) || (defined(AIX) && defined(_THREAD_SAFE)) \
|| (defined(HPUX10_10) && defined(_REENTRANT)) \
|| (defined(HPUX10_20) && defined(_REENTRANT))
#define _PR_HAVE_GETPROTO_R
@@ -558,25 +559,17 @@ PR_IMPLEMENT(PRUintn) PR_NetAddrSize(const PRNetAddr* addr)
{
PRUintn addrsize;
+ if (AF_INET == addr->raw.family)
+ addrsize = sizeof(addr->inet);
#if defined(_PR_INET6)
-
- if ((AF_INET == (0x00ff & addr->raw.family))
- || (AF_INET == (0x00ff & ntohs(addr->raw.family))))
- addrsize = sizeof(struct sockaddr_in);
- else if ((AF_INET6 == (0x00ff & addr->raw.family))
- || (AF_INET6 == (0x00ff & ntohs(addr->raw.family))))
- addrsize = sizeof(struct sockaddr_in6);
- else addrsize = 0;
-
-#else /* defined(_PR_INET6) */
-
-#if defined(XP_MAC)
-#pragma unused (addr)
+ else if (AF_INET6 == addr->raw.family)
+ addrsize = sizeof(addr->ipv6);
#endif
-
- addrsize = sizeof(struct sockaddr_in);
-
-#endif /* defined(_PR_INET6) */
+#if defined(XP_UNIX)
+ else if (AF_UNIX == addr->raw.family)
+ addrsize = sizeof(addr->local);
+#endif
+ else addrsize = 0;
return addrsize;
} /* PR_NetAddrSize */
diff --git a/pr/src/misc/prtime.c b/pr/src/misc/prtime.c
index 6f92c8ef..ce6e1516 100644
--- a/pr/src/misc/prtime.c
+++ b/pr/src/misc/prtime.c
@@ -1142,7 +1142,7 @@ PR_ParseTimeString(
{
const char *end;
int sign;
- if (zone_offset >= 0)
+ if (zone_offset != -1)
{
/* already got one... */
rest++;
@@ -1196,17 +1196,13 @@ PR_ParseTimeString(
if (*end == ':')
{
- if (hour > 0 && min > 0) /* already got it */
+ if (hour >= 0 && min >= 0) /* already got it */
break;
/* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */
if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */
break;
- else if (rest[1] != ':' &&
- rest[2] != ':')
- /* it is not [0-9]: or [0-9][0-9]: */
- break;
else if ((end - rest) == 2)
tmp_hour = ((rest[0]-'0')*10 +
(rest[1]-'0'));
@@ -1341,26 +1337,31 @@ PR_ParseTimeString(
(DD/MM/YY or MM/DD/YY or YY/MM/DD.)
*/
- if (n1 > 70) /* must be YY/MM/DD */
+ if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */
{
if (n2 > 12) break;
if (n3 > 31) break;
year = n1;
- if (year < 1900) year += 1900;
+ if (year < 70)
+ year += 2000;
+ else if (year < 100)
+ year += 1900;
month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
date = n3;
rest = s;
break;
}
- if (n3 < 70 || /* before epoch - can't represent it. */
- (n1 > 12 && n2 > 12)) /* illegal */
+ if (n1 > 12 && n2 > 12) /* illegal */
{
rest = s;
break;
}
- if (n3 < 1900) n3 += 1900;
+ if (n3 < 70)
+ n3 += 2000;
+ else if (n3 < 100)
+ n3 += 1900;
if (n1 > 12) /* must be DD/MM/YY */
{
@@ -1627,7 +1628,7 @@ PR_FormatTime(char *buf, int buflen, char *fmt, const PRExplodedTime *tm)
* these two fields.
*/
-#if defined(SUNOS4) || defined(MACLINUX) || (__GLIBC__ >= 2)
+#if defined(SUNOS4) || defined(MKLINUX) || (__GLIBC__ >= 2)
if (mktime(&a) == -1) {
PR_snprintf(buf, buflen, "can't get timezone");
return 0;
diff --git a/pr/src/pthreads/ptio.c b/pr/src/pthreads/ptio.c
index 171877e7..e898c73f 100644
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -24,19 +24,10 @@
#if defined(_PR_PTHREADS)
+#include <pthread.h>
#include <string.h> /* for memset() */
#include <sys/types.h>
#include <dirent.h>
-
-/*
- * XXX: On Linux 2.0.27 sched.h uses this _P macro that seems to be undefined.
- * I suspect that it is a typo (should be __P).
- */
-#if defined(LINUX)
-#define _P(x) __P(x)
-#endif
-#include <pthread.h>
-
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
@@ -49,7 +40,7 @@
#endif
/* Linux (except glibc) and FreeBSD don't have poll */
#if !(defined(LINUX) && !(defined(__GLIBC__) && __GLIBC__ >= 2)) \
- && !defined(FREEBSD)
+ && !defined(FREEBSD)
#include <poll.h>
#endif
#ifdef AIX
@@ -71,7 +62,7 @@
#if defined(SOLARIS)
#define _PRSockOptVal_t char *
#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(HPUX) \
- || defined(LINUX) || defined(FREEBSD)
+ || defined(LINUX) || defined(FREEBSD)
#define _PRSockOptVal_t void *
#else
#error "Cannot determine architecture"
@@ -90,7 +81,6 @@
#error "Cannot determine architecture"
#endif
-static PRStatus pt_InitIOContinuation(void);
static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type);
static pthread_condattr_t _pt_cvar_attr;
@@ -100,6 +90,40 @@ static PRLock *_pr_rename_lock; /* For PR_Rename() */
extern struct _PT_Bookeeping pt_book; /* defined in ptthread.c */
extern PRIntn pt_schedpriv; /* defined in ptthread.c */
+/**************************************************************************/
+
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+static PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+ if ((addr != NULL)
+ && (addr->raw.family != AF_UNIX)
+#ifdef _PR_INET6
+ && (addr->raw.family != AF_INET6)
+#endif
+ && (addr->raw.family != AF_INET)) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
+{
+ /*
+ * The definition of the length of a Unix domain socket address
+ * is not uniform, so we don't check it.
+ */
+ if ((addr != NULL)
+ && (addr->raw.family != AF_UNIX)
+ && (PR_NETADDR_SIZE(addr) != addr_len)) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
/*****************************************************************************/
/*****************************************************************************/
/************************** File descriptor caching **************************/
@@ -198,7 +222,7 @@ static void pt_Putfd(PRFileDesc *fd)
* size_t or int.
*/
#if (defined(LINUX) && defined(__GLIBC__) && __GLIBC__ >= 2 \
- && !defined(__alpha))
+ && !defined(__alpha))
typedef socklen_t pt_SockLen;
#elif defined(AIX) || (defined(LINUX) && defined(__alpha))
typedef PRSize pt_SockLen;
@@ -211,8 +235,8 @@ typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents);
typedef enum pr_ContuationStatus
{
- pt_continuation_sumbitted,
- pt_continuation_inprogress,
+ pt_continuation_pending,
+ pt_continuation_recycle,
pt_continuation_abort,
pt_continuation_done
} pr_ContuationStatus;
@@ -261,31 +285,65 @@ struct pt_Continuation
PRIntn syserrno; /* in case it failed, why (errno) */
pr_ContuationStatus status; /* the status of the operation */
- PRCondVar complete; /* to notify the initiating thread */
+ PRCondVar *complete; /* to notify the initiating thread */
};
static struct pt_TimedQueue
{
- PRCallOnceType once; /* controls the initialization
- * of this structure */
PRLock *ml; /* a little protection */
PRThread *thread; /* internal thread's identification */
- PRCondVar *new_op; /* new operation supplied */
PRUintn op_count; /* number of operations in the list */
pt_Continuation *head, *tail; /* head/tail of list of operations */
pt_Continuation *op; /* timed operation furthest in future */
- PRBool exitFlag; /* a Boolean flag for signaling the
- * continuation thread to exit */
} pt_tq;
#if defined(DEBUG)
-static struct pt_debug_s
+
+PTDebug pt_debug; /* this is shared between several modules */
+
+PR_IMPLEMENT(PTDebug) PT_GetStats() { return pt_debug; }
+
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
{
- PRUintn predictionsFoiled;
- PRUintn pollingListMax;
- PRUintn continuationsServed;
-} pt_debug;
+ char buffer[100];
+ PRExplodedTime tod;
+ PRInt64 elapsed, aMil;
+ PTDebug stats = PT_GetStats(); /* a copy */
+ PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod);
+ (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
+
+ LL_SUB(elapsed, PR_Now(), stats.timeStarted);
+ LL_I2L(aMil, 1000000);
+ LL_DIV(elapsed, elapsed, aMil);
+
+ if (NULL != msg) PR_fprintf(debug_out, "%s", msg);
+ PR_fprintf(
+ debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed);
+ PR_fprintf(
+ debug_out, "\tmissed predictions: %u\n", stats.predictionsFoiled);
+ PR_fprintf(
+ debug_out, "\tpollingList max: %u\n", stats.pollingListMax);
+ PR_fprintf(
+ debug_out, "\tcontinuations served: %u\n", stats.continuationsServed);
+ PR_fprintf(
+ debug_out, "\trecycles needed: %u\n", stats.recyclesNeeded);
+ PR_fprintf(
+ debug_out, "\tquiescent IO: %u\n", stats.quiescentIO);
+ PR_fprintf(
+ debug_out, "\tlocks [created: %u, destroyed: %u]\n",
+ stats.locks_created, stats.locks_destroyed);
+ PR_fprintf(
+ debug_out, "\tlocks [acquired: %u, released: %u]\n",
+ stats.locks_acquired, stats.locks_released);
+ PR_fprintf(
+ debug_out, "\tcvars [created: %u, destroyed: %u]\n",
+ stats.cvars_created, stats.cvars_destroyed);
+ PR_fprintf(
+ debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n",
+ stats.cvars_notified, stats.delayed_cv_deletes);
+} /* PT_FPrintStats */
+
#endif /* DEBUG */
/*
@@ -301,6 +359,19 @@ static void pt_InsertTimedInternal(pt_Continuation *op)
pt_Continuation *t_op = NULL;
PRIntervalTime now = PR_IntervalNow();
+#if defined(DEBUG)
+ {
+ PRIntn count;
+ pt_Continuation *tmp;
+ PR_ASSERT((pt_tq.head == NULL) == (pt_tq.tail == NULL));
+ PR_ASSERT((pt_tq.head == NULL) == (pt_tq.op_count == 0));
+ for (tmp = pt_tq.head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ for (tmp = pt_tq.tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ }
+#endif /* defined(DEBUG) */
+
/*
* If this element operation isn't timed, it gets queued at the
* end of the list (just after pt_tq.tail) and we're
@@ -364,7 +435,7 @@ done:
* pointers are linked up correctly at all times so that we can
* traverse the queue by starting with pt_tq.head and following
* the 'next' pointers, without having to acquire the pt_tq.ml lock.
- * (We do that in ContinuationThread.) We traverse the 'prev'
+ * (we do that in pt_ContinuationThreadInternal). We traverse the 'prev'
* pointers only in this function, which is called with the lock held.
*
* Similar care is taken in pt_FinishTimedInternal where we remove
@@ -392,6 +463,32 @@ done:
pt_tq.op_count += 1;
+#if defined(DEBUG)
+ {
+ PRIntn count;
+ pt_Continuation *tmp;
+ PR_ASSERT(pt_tq.head != NULL);
+ PR_ASSERT(pt_tq.tail != NULL);
+ PR_ASSERT(pt_tq.op_count != 0);
+ PR_ASSERT(pt_tq.head->prev == NULL);
+ PR_ASSERT(pt_tq.tail->next == NULL);
+ if (pt_tq.op_count > 1)
+ {
+ PR_ASSERT(pt_tq.head->next != NULL);
+ PR_ASSERT(pt_tq.tail->prev != NULL);
+ }
+ else
+ {
+ PR_ASSERT(pt_tq.head->next == NULL);
+ PR_ASSERT(pt_tq.tail->prev == NULL);
+ }
+ for (tmp = pt_tq.head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ for (tmp = pt_tq.tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ }
+#endif /* defined(DEBUG) */
+
} /* pt_InsertTimedInternal */
/*
@@ -406,6 +503,32 @@ static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op)
{
pt_Continuation *next;
+#if defined(DEBUG)
+ {
+ PRIntn count;
+ pt_Continuation *tmp;
+ PR_ASSERT(pt_tq.head != NULL);
+ PR_ASSERT(pt_tq.tail != NULL);
+ PR_ASSERT(pt_tq.op_count != 0);
+ PR_ASSERT(pt_tq.head->prev == NULL);
+ PR_ASSERT(pt_tq.tail->next == NULL);
+ if (pt_tq.op_count > 1)
+ {
+ PR_ASSERT(pt_tq.head->next != NULL);
+ PR_ASSERT(pt_tq.tail->prev != NULL);
+ }
+ else
+ {
+ PR_ASSERT(pt_tq.head->next == NULL);
+ PR_ASSERT(pt_tq.tail->prev == NULL);
+ }
+ for (tmp = pt_tq.head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ for (tmp = pt_tq.tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ }
+#endif /* defined(DEBUG) */
+
/* remove this one from the list */
if (NULL == op->prev) pt_tq.head = op->next;
else op->prev->next = op->next;
@@ -424,20 +547,39 @@ static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op)
#if defined(DEBUG)
pt_debug.continuationsServed += 1;
#endif
- PR_NotifyCondVar(&op->complete);
+ PR_NotifyCondVar(op->complete);
+
+#if defined(DEBUG)
+ {
+ PRIntn count;
+ pt_Continuation *tmp;
+ PR_ASSERT((pt_tq.head == NULL) == (pt_tq.tail == NULL));
+ PR_ASSERT((pt_tq.head == NULL) == (pt_tq.op_count == 0));
+ for (tmp = pt_tq.head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ for (tmp = pt_tq.tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
+ PR_ASSERT(count == pt_tq.op_count);
+ }
+#endif /* defined(DEBUG) */
return next;
} /* pt_FinishTimedInternal */
-static void ContinuationThread(void *arg)
+static void pt_ContinuationThreadInternal(pt_Continuation *my_op)
{
/* initialization */
PRInt32 msecs, mx_poll_ticks;
- struct pollfd *pollingList = 0; /* list built for polling */
+ PRThreadPriority priority; /* used to save caller's prio */
PRIntn pollingListUsed; /* # entries used in the list */
PRIntn pollingListNeeded; /* # entries needed this time */
- PRIntn pollingSlotsAllocated = 0; /* # entries available in list */
+ static struct pollfd *pollingList = 0; /* list built for polling */
+ static PRIntn pollingSlotsAllocated = 0;/* # entries available in list */
+ PR_Unlock(pt_tq.ml); /* don't need that silly lock for a bit */
+
+ priority = PR_GetThreadPriority(pt_tq.thread);
+ PR_SetThreadPriority(pt_tq.thread, PR_PRIORITY_HIGH);
+
mx_poll_ticks = (PRInt32)PR_MillisecondsToInterval(PT_DEFAULT_POLL_MSEC);
/* do some real work */
@@ -447,16 +589,11 @@ static void ContinuationThread(void *arg)
PRInt32 timeout;
PRIntn pollIndex;
PRIntervalTime now;
- pt_Continuation *op;
+ pt_Continuation *op, *next_op;
- PR_Lock(pt_tq.ml);
- while (!pt_tq.exitFlag && (NULL == pt_tq.head))
- PR_WaitCondVar(pt_tq.new_op, PR_INTERVAL_NO_TIMEOUT);
- pollingListNeeded = pt_tq.op_count;
- PR_Unlock(pt_tq.ml);
+ PR_ASSERT(NULL != pt_tq.head);
- /* Okay. We're history */
- if (pt_tq.exitFlag) break;
+ pollingListNeeded = pt_tq.op_count;
/*
* We are not holding the pt_tq.ml lock now, so more items may
@@ -467,7 +604,7 @@ static void ContinuationThread(void *arg)
if (pollingListNeeded > pollingSlotsAllocated)
{
if (NULL != pollingList) PR_DELETE(pollingList);
- pollingList = (struct pollfd*)PR_Malloc(
+ pollingList = (struct pollfd*)PR_MALLOC(
pollingListNeeded * sizeof(struct pollfd));
PR_ASSERT(NULL != pollingList);
pollingSlotsAllocated = pollingListNeeded;
@@ -479,6 +616,23 @@ static void ContinuationThread(void *arg)
#endif
/*
+ ** This is interrupt processing. If this thread was interrupted,
+ ** the thread state will have the PT_THREAD_ABORTED bit set. This
+ ** overrides good completions as well as timeouts.
+ **
+ ** BTW, it does no good to hold the lock here. This lock doesn't
+ ** protect the thread structure in any way. Testing the bit and
+ ** (perhaps) resetting it are safe 'cause it's the only modifiable
+ ** bit in that word.
+ */
+ if (pt_tq.thread->state & PT_THREAD_ABORTED)
+ {
+ my_op->status = pt_continuation_abort;
+ pt_tq.thread->state &= ~PT_THREAD_ABORTED;
+ }
+
+
+ /*
* Build up a polling list.
* This list is sorted on time. Operations that have been
* interrupted are completed and not included in the list.
@@ -493,13 +647,21 @@ static void ContinuationThread(void *arg)
{
op->result.code = -1;
op->syserrno = EINTR;
- op = pt_FinishTimedInternal(op);
+ next_op = pt_FinishTimedInternal(op);
+ if (op == my_op) goto recycle;
+ else op = next_op;
+ PR_ASSERT(NULL != pt_tq.head);
}
else
{
- if (pollingListUsed == pollingSlotsAllocated) break;
- PR_ASSERT(pt_continuation_done != op->status);
- op->status = pt_continuation_inprogress;
+ op->status = pt_continuation_pending;
+ if (pollingListUsed >= pollingSlotsAllocated)
+ {
+#if defined(DEBUG)
+ pt_debug.predictionsFoiled += 1;
+#endif
+ break;
+ }
pollingList[pollingListUsed].revents = 0;
pollingList[pollingListUsed].fd = op->arg1.osfd;
pollingList[pollingListUsed].events = op->event;
@@ -508,25 +670,6 @@ static void ContinuationThread(void *arg)
}
}
- PR_Unlock(pt_tq.ml);
-
- /*
- * If 'op' isn't NULL at this point, then we didn't get to
- * the end of the list. That means that more items got added
- * to the list than we anticipated. So, forget this iteration,
- * go around the horn again.
- * One would hope this doesn't happen all that often.
- */
- if (NULL != op)
- {
-#if defined(DEBUG)
- pt_debug.predictionsFoiled += 1; /* keep track */
-#endif
- continue; /* make it rethink things */
- }
-
- if (NULL == pt_tq.head) continue; /* did list evaporate? */
-
/*
* We don't want to wait forever on this poll. So keep
* the interval down. The operations, if they are timed,
@@ -542,15 +685,27 @@ static void ContinuationThread(void *arg)
if (timeout <= 0) msecs = 0; /* already timed out */
else if (timeout >= mx_poll_ticks) msecs = PT_DEFAULT_POLL_MSEC;
else msecs = (PRInt32)PR_IntervalToMilliseconds(timeout);
- }
+ }
+
+ PR_Unlock(pt_tq.ml);
+
+ /*
+ * If 'op' isn't NULL at this point, then we didn't get to
+ * the end of the list. That means that more items got added
+ * to the list than we anticipated. So, forget this iteration,
+ * go around the horn again.
+ * One would hope this doesn't happen all that often.
+ */
+ if (NULL != op) continue; /* make it rethink things */
rv = poll(pollingList, pollingListUsed, msecs);
if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
continue; /* go around the loop again */
- if (rv > 0)
- {
+ PR_Lock(pt_tq.ml);
+ if (rv > 0)
+ {
/*
* poll() says that something in our list is ready for some more
* action. Find it, load up the operation and see what happens.
@@ -589,12 +744,12 @@ static void ContinuationThread(void *arg)
* the continuation function. If it reports completion,
* finish off the operation.
*/
- if ((pt_continuation_inprogress == op->status)
+ if ((pt_continuation_pending == op->status)
&& (op->function(op, pollingList[pollIndex].revents)))
{
- PR_Lock(pt_tq.ml);
- op = pt_FinishTimedInternal(op);
- PR_Unlock(pt_tq.ml);
+ next_op = pt_FinishTimedInternal(op);
+ if (op == my_op) goto recycle;
+ else op = next_op;
}
continue;
}
@@ -607,97 +762,135 @@ static void ContinuationThread(void *arg)
* for good completions. Those that just made it under the
* wire are lucky, but none the less, valid.
*/
- if ((NULL != pt_tq.head)
+ now = PR_IntervalNow();
+ while ((NULL != pt_tq.head)
&& (PR_INTERVAL_NO_TIMEOUT != pt_tq.head->timeout))
{
- now = PR_IntervalNow();
- while ((PRInt32)(pt_tq.head->absolute - now) <= 0)
- {
- /*
- * The leading element of the timed queue has timed
- * out. Get rid of it. In any case go around the
- * loop again, computing the polling list, checking
- * for interrupted operations.
- */
-
- PR_Lock(pt_tq.ml);
- pt_tq.head->result.code = -1;
- pt_tq.head->syserrno = ETIMEDOUT;
- (void)pt_FinishTimedInternal(pt_tq.head);
- PR_Unlock(pt_tq.ml);
- if ((NULL == pt_tq.head)
- || (PR_INTERVAL_NO_TIMEOUT == pt_tq.head->timeout))
- break;
- }
+ op = pt_tq.head; /* get a copy of this before finishing it */
+ if ((PRInt32)(op->absolute - now) > 0) break;
+ /*
+ * The head element of the timed queue has timed out. Record
+ * the reason for completion and take it out of the list.
+ */
+ op->result.code = -1;
+ op->syserrno = ETIMEDOUT;
+ (void)pt_FinishTimedInternal(op);
+
+ /*
+ * If it's 'my_op' then we have to switch threads. Exit w/o
+ * finishing the scan. The scan will be completed when another
+ * thread calls in acting as the continuation thread.
+ */
+ if (op == my_op) goto recycle; /* exit w/o unlocking */
}
+ PR_Unlock(pt_tq.ml); /* unlock and go back around again */
+ }
+
+recycle:
+ /*
+ ** Recycling the continuation thread.
+ **
+ ** The thread we were using for I/O continuations just completed
+ ** the I/O it submitted. It has to return to it's caller. We need
+ ** another thread to act in the continuation role. We can do that
+ ** by taking any operation off the timed queue, setting its state
+ ** to 'recycle' and notifying the condition.
+ **
+ ** Selecting a likely thread seems like magic. I'm going to try
+ ** using one that has the longest (or no) timeout, pt_tq.tail.
+ ** If that slot's empty, then there's no outstanding I/O and we
+ ** don't need a thread at all.
+ **
+ ** BTW, we're locked right now, and we'll be returning with the
+ ** the lock held as well. Seems odd, doesn't it?
+ */
+
+ PR_SetThreadPriority(pt_tq.thread, priority); /* reset back to caller's */
+
+ PR_ASSERT((NULL == pt_tq.head) == (0 == pt_tq.op_count));
+ PR_ASSERT((NULL == pt_tq.head) == (NULL == pt_tq.tail));
+ PR_ASSERT(pt_continuation_done == my_op->status);
+
+ if (NULL != pt_tq.tail)
+ {
+ pt_tq.tail->status = pt_continuation_recycle;
+ PR_NotifyCondVar(pt_tq.tail->complete);
+#if defined(DEBUG)
+ pt_debug.recyclesNeeded += 1;
+#endif
}
- if (NULL != pollingList) PR_DELETE(pollingList);
-} /* ContinuationThread */
+#if defined(DEBUG)
+ else pt_debug.quiescentIO += 1;
+#endif
+
+} /* pt_ContinuationThreadInternal */
static PRIntn pt_Continue(pt_Continuation *op)
{
PRIntn rc;
PRStatus rv;
-#ifdef DEBUG
- PRBool waitcv_interrupted = PR_FALSE;
-#endif /* DEBUG */
-
- PR_CallOnce(&pt_tq.once, pt_InitIOContinuation);
-
+ PRThread *self = PR_GetCurrentThread();
+ /* lazy allocation of the thread's cv */
+ if (NULL == self->io_cv)
+ self->io_cv = PR_NewCondVar(pt_tq.ml);
/* Finish filling in the blank slots */
- /* op->complete = PR_NewCondVar(pt_tq.ml); */
- op->complete.lock = pt_tq.ml;
- rc = PTHREAD_COND_INIT(op->complete.cv, _pt_cvar_attr); PR_ASSERT(0 == rc);
- op->status = pt_continuation_sumbitted;
+ op->complete = self->io_cv;
+ op->status = pt_continuation_pending; /* set default value */
PR_Lock(pt_tq.ml); /* we provide the locking */
pt_InsertTimedInternal(op); /* insert in the structure */
- PR_NotifyCondVar(pt_tq.new_op); /* notify the continuation thread */
-
- while (pt_continuation_done != op->status) /* wait for completion */
+ /*
+ ** At this point, we try to decide whether there is a continuation
+ ** thread, or whether we should assign this one to serve in that role.
+ */
+ do
{
- rv = PR_WaitCondVar(&op->complete, PR_INTERVAL_NO_TIMEOUT);
- /*
- * If we get interrupted, we set state the continuation thread will
- * see and allow it to finish the I/O operation w/ error. That way
- * the rule that only the continuation thread is removing elements
- * from the list is still valid.
- *
- * Don't call interrupt on the continuation thread. That'll just
- * irritate him. He's cycling around at least every mx_poll_ticks
- * anyhow and should notice the request in there.
- */
- if ((PR_FAILURE == rv)
- && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
+ if (NULL == pt_tq.thread)
{
-#ifdef DEBUG
- waitcv_interrupted = PR_TRUE;
-#endif /* DEBUG */
- if (pt_continuation_done != op->status)
- {
- /* tell the continuation thread to abort the operation */
- op->status = pt_continuation_abort;
- }
- else
+ /*
+ ** We're the one. Call the processing function with the lock
+ ** held. It will return with it held as well, though there
+ ** will certainly be times within the function when it gets
+ ** released.
+ */
+ pt_tq.thread = PR_GetCurrentThread(); /* I'm taking control */
+ pt_ContinuationThreadInternal(op); /* go slash and burn */
+ PR_ASSERT(pt_continuation_done == op->status);
+ pt_tq.thread = NULL; /* I'm abdicating my rule */
+ }
+ else
+ {
+ rv = PR_WaitCondVar(op->complete, PR_INTERVAL_NO_TIMEOUT);
+ /*
+ * If we get interrupted, we set state the continuation thread will
+ * see and allow it to finish the I/O operation w/ error. That way
+ * the rule that only the continuation thread is removing elements
+ * from the list is still valid.
+ *
+ * Don't call interrupt on the continuation thread. That'll just
+ * irritate him. He's cycling around at least every mx_poll_ticks
+ * anyhow and should notice the request in there. When he does
+ * notice, this operation will be finished and the op's status
+ * marked as pt_continuation_done.
+ */
+ if ((PR_FAILURE == rv) /* the wait failed */
+ && (pt_continuation_pending == op->status) /* but the op hasn't */
+ && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) /* was interrupted */
{
- op->result.code = -1;
- op->syserrno = EINTR;
+ op->status = pt_continuation_abort; /* go around the loop again */
}
+ /*
+ * If we're to recycle, continue within this loop. This will
+ * cause this thread to be come the continuation thread.
+ */
+
}
- }
+ } while (pt_continuation_done != op->status);
- PR_Unlock(pt_tq.ml); /* we provide the locking */
- rc = pthread_cond_destroy(&op->complete.cv); PR_ASSERT(0 == rc);
- /* make sure that the continuation thread did abort the operation */
-#ifdef DEBUG
- if (PR_TRUE == waitcv_interrupted)
- {
- PR_ASSERT(-1 == op->result.code);
- PR_ASSERT(EINTR == op->syserrno);
- }
-#endif /* DEBUG */
+ PR_Unlock(pt_tq.ml); /* we provided the locking */
+
return op->result.code; /* and the primary answer */
} /* pt_Continue */
@@ -820,14 +1013,13 @@ static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents)
* modify an individual vector parms or we might have to eliminate
* a pair altogether.
*/
- PRIntn bytes = writev(
- op->arg1.osfd, (struct iovec*)op->arg2.buffer, op->arg3.amount);
+ struct iovec *iov = (struct iovec*)op->arg2.buffer;
+ PRIntn bytes = writev(op->arg1.osfd, iov, op->arg3.amount);
op->syserrno = errno;
if (bytes > 0) /* this is progress */
{
PRIntn iov_index;
- struct iovec *iov = (struct iovec*)op->arg2.buffer;
- op->result.code += bytes; /* accumulate the number sent */
+ op->result.code += bytes; /* accumulate the number sent */
for (iov_index = 0; iov_index < op->arg3.amount; ++iov_index)
{
/* how much progress did we make in the i/o vector? */
@@ -921,64 +1113,28 @@ static PRBool pt_hpux_transmitfile_cont(pt_Continuation *op, PRInt16 revents)
}
#endif /* HPUX11 */
-#if !defined(PT_NO_ATFORK)
-
-static void pt_BeforeFork()
-{
- PRStatus rv;
- PRThread *thred = pt_tq.thread;
-
- /*
- * We shut down the continuation thread cleanly only if there are
- * no other threads in the process when fork() is called.
- * If there are other threads, they won't be duplicated in the child
- * process. Then the child process may already be unclean, so there
- * is no point for us to try to be clean.
- */
-
- if ((NULL != thred) && (2 == pt_book.user + pt_book.system))
- {
- /* pt_tq should be empty */
- PR_ASSERT((0 == pt_tq.op_count)
- && (NULL == pt_tq.head)
- && (NULL == pt_tq.tail)
- && (NULL == pt_tq.op));
- pt_tq.exitFlag = PR_TRUE;
- rv = PR_Interrupt(thred);
- PR_ASSERT(PR_SUCCESS == rv);
- rv = PR_JoinThread(thred);
- PR_ASSERT(PR_SUCCESS == rv);
- pt_tq.exitFlag = PR_FALSE;
- /* Indicates that the continuation thread is shut down cleanly */
- pt_tq.thread = NULL;
- memset(&pt_tq.once, 0, sizeof(pt_tq.once));
- PR_ASSERT(1 == pt_book.user + pt_book.system);
- }
-} /* pt_BeforeFork */
-
-static void pt_AfterForkParent(void)
-{
-} /* pt_AfterForkParent */
-
-static void pt_AfterForkChild(void)
-{
- /*
- * pt_tq may be in a corrupted state if the continuation thread
- * existed and was not terminated cleanly before fork. In this
- * case, we expect the child process to call exec immediately.
- */
-} /* pt_AfterForkChild */
-
-#endif /* PT_NO_ATFORK */
-
void _PR_InitIO()
{
+ PRIntn rv;
_pr_stdin = pt_SetMethods(0, PR_DESC_FILE);
_pr_stdout = pt_SetMethods(1, PR_DESC_FILE);
_pr_stderr = pt_SetMethods(2, PR_DESC_FILE);
PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr);
+ pt_tq.ml = PR_NewLock();
+ PR_ASSERT(NULL != pt_tq.ml);
+
+#if defined(DEBUG)
+ memset(&pt_debug, 0, sizeof(PTDebug));
+ pt_debug.timeStarted = PR_Now();
+#endif
+
+ rv = PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);
+ PR_ASSERT(0 == rv);
+
+ pt_tq.thread = NULL;
+
_pr_flock_lock = PR_NewLock();
PR_ASSERT(NULL != _pr_flock_lock);
_pr_rename_lock = PR_NewLock();
@@ -989,41 +1145,6 @@ void _PR_InitIO()
pt_fd_cache.limit = FD_SETSIZE;
} /* _PR_InitIO */
-static PRStatus pt_InitIOContinuation()
-{
- PRIntn rv;
-
- PR_ASSERT((0 == pt_tq.op_count)
- && (NULL == pt_tq.head)
- && (NULL == pt_tq.tail)
- && (NULL == pt_tq.op)
- && (PR_FALSE == pt_tq.exitFlag));
-
- if (NULL == pt_tq.ml)
- {
- /* The very first time */
- pt_tq.ml = PR_NewLock();
- PR_ASSERT(NULL != pt_tq.ml);
- pt_tq.new_op = PR_NewCondVar(pt_tq.ml);
- PR_ASSERT(NULL != pt_tq.new_op);
- rv = PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);
- PR_ASSERT(0 == rv);
-
-#if !defined(PT_NO_ATFORK)
- rv = pthread_atfork(pt_BeforeFork,
- pt_AfterForkParent, pt_AfterForkChild);
- PR_ASSERT(0 == rv);
-#endif
- }
-
- pt_tq.thread = PR_CreateThread(
- PR_SYSTEM_THREAD, ContinuationThread, NULL,
- PR_PRIORITY_URGENT, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
- PR_ASSERT(NULL != pt_tq.thread);
-
- return PR_SUCCESS;
-}
-
PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
{
PRFileDesc *result = NULL;
@@ -1074,7 +1195,8 @@ static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno)
static PRStatus pt_Close(PRFileDesc *fd)
{
PRIntn syserrno, rv = 0;
- if ((NULL == fd) || (NULL == fd->secret))
+ if ((NULL == fd) || (NULL == fd->secret) ||
+ (_PR_FILEDESC_OPEN != fd->secret->state))
{
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
return PR_FAILURE;
@@ -1230,7 +1352,7 @@ static PRInt32 pt_Writev(
*/
struct iovec *osiov = NULL, *tiov;
PRIntn osiov_len = iov_len - iov_index; /* recompute */
- osiov = (struct iovec*)PR_Malloc(osiov_len * sizeof(struct iovec));
+ osiov = (struct iovec*)PR_MALLOC(osiov_len * sizeof(struct iovec));
PR_ASSERT(NULL != osiov);
for (tiov = osiov; iov_index < iov_len; ++iov_index)
{
@@ -1413,10 +1535,14 @@ static PRStatus pt_Connect(
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
{
- PRInt32 osfd;
- PRFileDesc *bottom = pd->fd;
int err;
+ PRInt32 osfd;
+ PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+ if (NULL == bottom) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
+ }
if (pd->out_flags & PR_POLL_NVAL) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
return PR_FAILURE;
@@ -1427,9 +1553,6 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
return PR_FAILURE;
}
- while (bottom->lower != NULL) {
- bottom = bottom->lower;
- }
osfd = bottom->secret->md.osfd;
err = _MD_unix_get_nonblocking_connect_error(osfd);
@@ -1484,13 +1607,8 @@ static PRFileDesc* pt_Accept(
if (newfd == NULL) close(osfd); /* $$$ whoops! this doesn't work $$$ */
else
{
- PR_ASSERT((NULL == addr) || (PR_NETADDR_SIZE(addr) == addr_len));
-#if defined(_PR_INET6)
- PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET)
- || (addr->raw.family == AF_INET6));
-#else
- PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET));
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
}
return newfd;
@@ -1506,18 +1624,27 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
if (pt_TestAbort()) return PR_FAILURE;
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
- rv = setsockopt(
- fd->secret->md.osfd, SOL_SOCKET, SO_REUSEADDR,
- (_PRSockOptVal_t) &one, sizeof(one));
- if (rv == -1) {
- pt_MapError(_PR_MD_MAP_SETSOCKOPT_ERROR, errno);
- return PR_FAILURE;
+ if (addr->raw.family == AF_UNIX)
+ {
+ /* Disallow relative pathnames */
+ if (addr->local.path[0] != '/')
+ {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
+ }
+ }
+ else
+ {
+ rv = setsockopt(
+ fd->secret->md.osfd, SOL_SOCKET, SO_REUSEADDR,
+ (_PRSockOptVal_t) &one, sizeof(one));
+ if (rv == -1)
+ {
+ pt_MapError(_PR_MD_MAP_SETSOCKOPT_ERROR, errno);
+ return PR_FAILURE;
+ }
}
rv = bind(fd->secret->md.osfd, (struct sockaddr*)addr, PR_NETADDR_SIZE(addr));
@@ -1557,6 +1684,12 @@ static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how)
return PR_SUCCESS;
} /* pt_Shutdown */
+static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+ *out_flags = 0;
+ return in_flags;
+} /* pt_Poll */
+
static PRInt32 pt_Recv(
PRFileDesc *fd, void *buf, PRInt32 amount,
PRIntn flags, PRIntervalTime timeout)
@@ -1601,7 +1734,7 @@ static PRInt32 pt_Send(
/*
* Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,
* which has the following:
- * # define send cma_send
+ * # define send cma_send
* extern int cma_send (int , void *, int, int );
* So we need to cast away the 'const' of argument #2 for send().
*/
@@ -1670,11 +1803,7 @@ static PRInt32 pt_SendTo(
if (pt_TestAbort()) return PR_FAILURE;
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
bytes = sendto(
fd->secret->md.osfd, buf, amount, flags,
(struct sockaddr*)addr, PR_NETADDR_SIZE(addr));
@@ -1753,12 +1882,12 @@ static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
/*
* pt_HPUXTransmitFile
*
- * Send file fd across socket sd. If headers is non-NULL, 'hlen'
- * bytes of headers is sent before sending the file.
+ * Send file fd across socket sd. If headers is non-NULL, 'hlen'
+ * bytes of headers is sent before sending the file.
*
- * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
- *
- * return number of bytes sent or -1 on error
+ * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *
+ * return number of bytes sent or -1 on error
*
* This implementation takes advantage of the sendfile() system
* call available in HP-UX B.11.00.
@@ -1831,7 +1960,7 @@ static PRInt32 pt_HPUXTransmitFile(PRFileDesc *sd, PRFileDesc *fd,
if (count == -1) {
_MD_hpux_map_sendfile_error(syserrno);
- return -1;
+ return -1;
}
if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
PR_Close(sd);
@@ -1914,12 +2043,8 @@ static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
return PR_FAILURE;
} else {
- PR_ASSERT(addr_len == PR_NETADDR_SIZE(addr));
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
return PR_SUCCESS;
}
} /* pt_GetSockName */
@@ -1942,12 +2067,8 @@ static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
return PR_FAILURE;
} else {
- PR_ASSERT(addr_len == PR_NETADDR_SIZE(addr));
-#if defined(_PR_INET6)
- PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
-#else
- PR_ASSERT(addr->raw.family == AF_INET);
-#endif
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
return PR_SUCCESS;
}
} /* pt_GetPeerName */
@@ -2101,13 +2222,13 @@ static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
}
case PR_SockOpt_McastLoopback:
{
- PRUint8 boolean;
- length = sizeof(boolean);
+ PRUint8 xbool;
+ length = sizeof(xbool);
rv = getsockopt(
fd->secret->md.osfd, level, name,
- (char*)&boolean, &length);
- PR_ASSERT((-1 == rv) || (sizeof(boolean) == length));
- data->value.mcast_loopback = (0 == boolean) ? PR_FALSE : PR_TRUE;
+ (char*)&xbool, &length);
+ PR_ASSERT((-1 == rv) || (sizeof(xbool) == length));
+ data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE;
break;
}
case PR_SockOpt_RecvBufferSize:
@@ -2179,7 +2300,7 @@ static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
{
PRIntn rv;
- PRInt32 level, name;
+ PRInt32 level, name;
/*
* PR_SockOpt_Nonblocking is a special case that does not
@@ -2217,10 +2338,10 @@ static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *dat
}
case PR_SockOpt_McastLoopback:
{
- PRUint8 boolean = data->value.mcast_loopback ? 1 : 0;
+ PRUint8 xbool = data->value.mcast_loopback ? 1 : 0;
rv = setsockopt(
fd->secret->md.osfd, level, name,
- (char*)&boolean, sizeof(boolean));
+ (char*)&xbool, sizeof(xbool));
break;
}
case PR_SockOpt_RecvBufferSize:
@@ -2295,23 +2416,23 @@ static PRIOMethods _pr_file_methods = {
pt_Seek64,
pt_FileInfo,
pt_FileInfo64,
- (PRWritevFN)_PR_InvalidInt,
- (PRConnectFN)_PR_InvalidStatus,
- (PRAcceptFN)_PR_InvalidDesc,
- (PRBindFN)_PR_InvalidStatus,
- (PRListenFN)_PR_InvalidStatus,
- (PRShutdownFN)_PR_InvalidStatus,
- (PRRecvFN)_PR_InvalidInt,
- (PRSendFN)_PR_InvalidInt,
- (PRRecvfromFN)_PR_InvalidInt,
- (PRSendtoFN)_PR_InvalidInt,
- (PRPollFN)0,
+ (PRWritevFN)_PR_InvalidInt,
+ (PRConnectFN)_PR_InvalidStatus,
+ (PRAcceptFN)_PR_InvalidDesc,
+ (PRBindFN)_PR_InvalidStatus,
+ (PRListenFN)_PR_InvalidStatus,
+ (PRShutdownFN)_PR_InvalidStatus,
+ (PRRecvFN)_PR_InvalidInt,
+ (PRSendFN)_PR_InvalidInt,
+ (PRRecvfromFN)_PR_InvalidInt,
+ (PRSendtoFN)_PR_InvalidInt,
+ pt_Poll,
(PRAcceptreadFN)_PR_InvalidInt,
(PRTransmitfileFN)_PR_InvalidInt,
- (PRGetsocknameFN)_PR_InvalidStatus,
- (PRGetpeernameFN)_PR_InvalidStatus,
- (PRGetsockoptFN)_PR_InvalidStatus,
- (PRSetsockoptFN)_PR_InvalidStatus,
+ (PRGetsocknameFN)_PR_InvalidStatus,
+ (PRGetpeernameFN)_PR_InvalidStatus,
+ (PRGetsockoptFN)_PR_InvalidStatus,
+ (PRSetsockoptFN)_PR_InvalidStatus,
};
static PRIOMethods _pr_tcp_methods = {
@@ -2322,10 +2443,10 @@ static PRIOMethods _pr_tcp_methods = {
pt_Available,
pt_Available64,
pt_Synch,
- (PRSeekFN)_PR_InvalidInt,
- (PRSeek64FN)_PR_InvalidInt64,
- (PRFileInfoFN)_PR_InvalidStatus,
- (PRFileInfo64FN)_PR_InvalidStatus,
+ (PRSeekFN)_PR_InvalidInt,
+ (PRSeek64FN)_PR_InvalidInt64,
+ (PRFileInfoFN)_PR_InvalidStatus,
+ (PRFileInfo64FN)_PR_InvalidStatus,
pt_Writev,
pt_Connect,
pt_Accept,
@@ -2334,9 +2455,9 @@ static PRIOMethods _pr_tcp_methods = {
pt_Shutdown,
pt_Recv,
pt_Send,
- (PRRecvfromFN)_PR_InvalidInt,
- (PRSendtoFN)_PR_InvalidInt,
- (PRPollFN)0,
+ (PRRecvfromFN)_PR_InvalidInt,
+ (PRSendtoFN)_PR_InvalidInt,
+ pt_Poll,
pt_AcceptRead,
pt_TransmitFile,
pt_GetSockName,
@@ -2355,13 +2476,13 @@ static PRIOMethods _pr_udp_methods = {
pt_Available,
pt_Available64,
pt_Synch,
- (PRSeekFN)_PR_InvalidInt,
- (PRSeek64FN)_PR_InvalidInt64,
- (PRFileInfoFN)_PR_InvalidStatus,
- (PRFileInfo64FN)_PR_InvalidStatus,
+ (PRSeekFN)_PR_InvalidInt,
+ (PRSeek64FN)_PR_InvalidInt64,
+ (PRFileInfoFN)_PR_InvalidStatus,
+ (PRFileInfo64FN)_PR_InvalidStatus,
pt_Writev,
pt_Connect,
- (PRAcceptFN)_PR_InvalidDesc,
+ (PRAcceptFN)_PR_InvalidDesc,
pt_Bind,
pt_Listen,
pt_Shutdown,
@@ -2369,9 +2490,9 @@ static PRIOMethods _pr_udp_methods = {
pt_Send,
pt_RecvFrom,
pt_SendTo,
- (PRPollFN)0,
- (PRAcceptreadFN)_PR_InvalidInt,
- (PRTransmitfileFN)_PR_InvalidInt,
+ pt_Poll,
+ (PRAcceptreadFN)_PR_InvalidInt,
+ (PRTransmitfileFN)_PR_InvalidInt,
pt_GetSockName,
pt_GetPeerName,
pt_GetSockOpt,
@@ -2427,22 +2548,23 @@ static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
return fd;
} /* pt_SetMethods */
-PR_IMPLEMENT(PRIOMethods*) PR_GetFileMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods()
{
return &_pr_file_methods;
} /* PR_GetFileMethods */
-PR_IMPLEMENT(PRIOMethods*) PR_GetTCPMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
{
return &_pr_tcp_methods;
} /* PR_GetTCPMethods */
-PR_IMPLEMENT(PRIOMethods*) PR_GetUDPMethods()
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
{
return &_pr_udp_methods;
} /* PR_GetUDPMethods */
-PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd, PRIOMethods *methods)
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+ PRInt32 osfd, const PRIOMethods *methods)
{
PRFileDesc *fd = pt_Getfd();
@@ -2483,9 +2605,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
if (PF_INET != domain
#if defined(_PR_INET6)
- && PF_INET6 != domain
+ && PF_INET6 != domain
#endif
- )
+ && PF_UNIX != domain)
{
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
return fd;
@@ -2746,34 +2868,54 @@ PR_IMPLEMENT(PRInt32) PR_Poll(
{
PRIntn index, msecs;
struct pollfd *syspoll = NULL;
- syspoll = (struct pollfd*)PR_Malloc(npds * sizeof(struct pollfd));
+ syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+ if (NULL == syspoll)
+ {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return -1;
+ }
for (index = 0; index < npds; ++index)
{
PRFileDesc *bottom = pds[index].fd;
+ PRInt16 polling_flags = pds[index].in_flags;
- if (bottom == NULL)
+ /* 'bottom' is really 'top' until we make it the bottom */
+ if (NULL != bottom)
{
- /* make poll() ignore this entry */
- syspoll[index].fd = -1;
- continue;
- }
+ polling_flags = (bottom->methods->poll)(
+ bottom, polling_flags, &pds[index].out_flags);
- while (bottom->lower != NULL) bottom = bottom->lower;
- syspoll[index].fd = bottom->secret->md.osfd;
-
- syspoll[index].events = 0;
- if (pds[index].in_flags & PR_POLL_READ)
- syspoll[index].events |= POLLIN;
- if (pds[index].in_flags & PR_POLL_WRITE)
- syspoll[index].events |= POLLOUT;
- if (pds[index].in_flags & PR_POLL_EXCEPT)
- syspoll[index].events |= POLLPRI;
- if (_PR_FILEDESC_OPEN == bottom->secret->state)
- pds[index].out_flags = 0; /* init the result */
+ if (0 != (polling_flags & pds[index].out_flags))
+ ready += 1; /* this one is ready right now */
+ else
+ {
+ /* now locate the NSPR layer at the bottom of the stack */
+ bottom = PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER);
+ PR_ASSERT(NULL != bottom); /* what to do about that? */
+ if ((NULL != bottom)
+ && (_PR_FILEDESC_OPEN == bottom->secret->state))
+ {
+ syspoll[index].fd = bottom->secret->md.osfd;
+ pds[index].out_flags = 0; /* init the result */
+ syspoll[index].events = 0;
+ if (polling_flags & PR_POLL_READ)
+ syspoll[index].events |= POLLIN;
+ if (polling_flags & PR_POLL_WRITE)
+ syspoll[index].events |= POLLOUT;
+ if (polling_flags & PR_POLL_EXCEPT)
+ syspoll[index].events |= POLLPRI;
+ }
+ else
+ {
+ ready += 1; /* this will cause an abrupt return */
+ pds[index].out_flags = POLLNVAL; /* bogii */
+ }
+ }
+ }
else
{
- ready += 1; /* this will cause an abrupt return */
- pds[index].out_flags = POLLNVAL; /* bogii */
+ /* make poll() ignore this entry */
+ syspoll[index].fd = -1;
}
}
if (0 == ready)
@@ -2792,41 +2934,30 @@ retry:
if (-1 == ready)
{
PRIntn oserror = errno;
- PRErrorCode prerror;
-
- switch (oserror) {
- case EAGAIN:
- prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
- break;
- case EINTR:
- if (timeout == PR_INTERVAL_NO_TIMEOUT)
- goto retry;
- else if (timeout == PR_INTERVAL_NO_WAIT)
- ready = 0; /* don't retry, just time out */
+
+ if (EINTR == oserror)
+ {
+ if (timeout == PR_INTERVAL_NO_TIMEOUT)
+ goto retry;
+ else if (timeout == PR_INTERVAL_NO_WAIT)
+ ready = 0; /* don't retry, just time out */
+ {
+ elapsed = (PRIntervalTime) (PR_IntervalNow()
+ - start);
+ if (elapsed > timeout)
+ ready = 0; /* timed out */
+ else
{
- elapsed = (PRIntervalTime) (PR_IntervalNow()
- - start);
- if (elapsed > timeout)
- ready = 0; /* timed out */
- else
- {
- remaining = timeout - elapsed;
- msecs = PR_IntervalToMilliseconds(remaining);
- goto retry;
- }
+ remaining = timeout - elapsed;
+ msecs = PR_IntervalToMilliseconds(remaining);
+ goto retry;
}
- break;
- case EINVAL:
- prerror = PR_INVALID_ARGUMENT_ERROR;
- break;
- case EFAULT:
- prerror = PR_ACCESS_FAULT_ERROR;
- break;
- default:
- prerror = PR_UNKNOWN_ERROR;
- break;
- }
- PR_SetError(prerror, oserror);
+ }
+ }
+ else
+ {
+ _PR_MD_MAP_POLL_ERROR(oserror);
+ }
}
else if (ready > 0)
{
@@ -2876,7 +3007,7 @@ PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
&& ('.' == dp->d_name[1])
&& (0 == dp->d_name[2])) continue;
if ((flags & PR_SKIP_HIDDEN) && ('.' == dp->d_name[0]))
- continue;
+ continue;
break;
}
dir->d.name = dp->d_name;
@@ -2974,7 +3105,7 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
if (pipe(pipefd) == -1)
{
- /* XXX map pipe error */
+ /* XXX map pipe error */
PR_SetError(PR_UNKNOWN_ERROR, errno);
return PR_FAILURE;
}
@@ -3026,25 +3157,14 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd)
return fd;
} /* PR_ImportUDPSocket */
-PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *fd)
+PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom)
{
- if (fd)
- {
- /*
- * The fd may be layered. Chase the links to the
- * bottom layer to get the osfd.
- */
- PRFileDesc *bottom = fd;
- while (bottom->lower != NULL) {
- bottom = bottom->lower;
- }
- return bottom->secret->md.osfd;
- }
- else
- {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return -1;
- }
+ PRInt32 osfd = -1;
+ bottom = (NULL == bottom) ?
+ NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER);
+ if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ else osfd = bottom->secret->md.osfd;
+ return osfd;
} /* PR_FileDesc2NativeHandle */
PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd,
diff --git a/pr/src/pthreads/ptsynch.c b/pr/src/pthreads/ptsynch.c
index 8906cda3..f3fa4711 100644
--- a/pr/src/pthreads/ptsynch.c
+++ b/pr/src/pthreads/ptsynch.c
@@ -33,10 +33,14 @@
static pthread_condattr_t _pt_cvar_attr;
-#if defined(DEBUG) && defined(_PR_DCETHREADS)
+#if defined(DEBUG)
+extern PTDebug pt_debug; /* this is shared between several modules */
+
+#if defined(_PR_DCETHREADS)
static pthread_t pt_zero_tid; /* a null pthread_t (pthread_t is a struct
* in DCE threads) to compare with */
-#endif
+#endif /* defined(_PR_DCETHREADS) */
+#endif /* defined(DEBUG) */
/**************************************************************/
/**************************************************************/
@@ -83,21 +87,33 @@ static void pt_PostNotifies(PRLock *lock, PRBool unlock)
{
for (index = 0; index < notified->length; ++index)
{
- PR_ASSERT(NULL != notified->cv[index].cv);
+ PRCondVar *cv = notified->cv[index].cv;
+ PR_ASSERT(NULL != cv);
PR_ASSERT(0 != notified->cv[index].times);
if (-1 == notified->cv[index].times)
{
- rv = pthread_cond_broadcast(&notified->cv[index].cv->cv);
+ rv = pthread_cond_broadcast(&cv->cv);
PR_ASSERT(0 == rv);
}
else
{
while (notified->cv[index].times-- > 0)
{
- rv = pthread_cond_signal(&notified->cv[index].cv->cv);
- PR_ASSERT(0 == rv);
+ rv = pthread_cond_signal(&cv->cv);
+ PR_ASSERT((0 == rv) || (EINVAL == rv));
}
}
+#if defined(DEBUG)
+ pt_debug.cvars_notified += 1;
+ if (0 > PR_AtomicDecrement(&cv->notify_pending))
+ {
+ pt_debug.delayed_cv_deletes += 1;
+ PR_DestroyCondVar(cv);
+ }
+#else /* defined(DEBUG) */
+ if (0 > PR_AtomicDecrement(&cv->notify_pending))
+ PR_DestroyCondVar(cv);
+#endif /* defined(DEBUG) */
}
prev = notified;
notified = notified->link;
@@ -123,6 +139,9 @@ PR_IMPLEMENT(PRLock*) PR_NewLock(void)
rv = PTHREAD_MUTEXATTR_DESTROY(&mattr);
PR_ASSERT(0 == rv);
}
+#if defined(DEBUG)
+ pt_debug.locks_created += 1;
+#endif
return lock;
} /* PR_NewLock */
@@ -137,6 +156,7 @@ PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
PR_ASSERT(0 == rv);
#if defined(DEBUG)
memset(lock, 0xaf, sizeof(PRLock));
+ pt_debug.locks_destroyed += 1;
#endif
PR_DELETE(lock);
} /* PR_DestroyLock */
@@ -151,6 +171,9 @@ PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
PR_ASSERT(NULL == lock->notified.link);
PR_ASSERT(PTHREAD_THR_HANDLE_IS_ZERO(lock->owner));
PTHREAD_COPY_THR_HANDLE(pthread_self(), lock->owner);
+#if defined(DEBUG)
+ pt_debug.locks_acquired += 1;
+#endif
} /* PR_Lock */
PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
@@ -172,6 +195,9 @@ PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
}
else pt_PostNotifies(lock, PR_TRUE);
+#if defined(DEBUG)
+ pt_debug.locks_released += 1;
+#endif
return PR_SUCCESS;
} /* PR_Unlock */
@@ -262,6 +288,7 @@ static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast)
}
/* A brand new entry in the array */
+ (void)PR_AtomicIncrement(&cvar->notify_pending);
notified->cv[index].times = (broadcast) ? -1 : 1;
notified->cv[index].cv = cvar;
notified->length += 1;
@@ -279,18 +306,25 @@ PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
int rv = PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr);
PR_ASSERT(0 == rv);
cv->lock = lock;
+ cv->notify_pending = 0;
+#if defined(DEBUG)
+ pt_debug.cvars_created += 1;
+#endif
}
return cv;
} /* PR_NewCondVar */
PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
{
- int rv;
- rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
+ if (0 > PR_AtomicDecrement(&cvar->notify_pending))
+ {
+ PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
#if defined(DEBUG)
memset(cvar, 0xaf, sizeof(PRCondVar));
+ pt_debug.cvars_destroyed += 1;
#endif
- PR_DELETE(cvar);
+ PR_DELETE(cvar);
+ }
} /* PR_DestroyCondVar */
PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c
index 784ffb29..d555c9fd 100644
--- a/pr/src/pthreads/ptthread.c
+++ b/pr/src/pthreads/ptthread.c
@@ -39,6 +39,7 @@
*/
PRIntn pt_schedpriv;
+extern PRLock *_pr_sleeplock;
struct _PT_Bookeeping pt_book = {0};
@@ -158,6 +159,8 @@ static void *_pt_root(void *arg)
/* last chance to delete this puppy if the thread is detached */
if (detached)
{
+ if (NULL != thred->io_cv)
+ PR_DestroyCondVar(thred->io_cv);
PR_DELETE(thred->stack);
#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread));
@@ -448,11 +451,15 @@ PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred)
{
pthread_t id = thred->id;
rv = pthread_join(id, &result);
+ PR_ASSERT(rv == 0 && result == NULL);
if (0 != rv)
PR_SetError(PR_UNKNOWN_ERROR, errno);
+ if (NULL != thred->io_cv)
+ PR_DestroyCondVar(thred->io_cv);
PR_DELETE(thred->stack);
+#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread));
- PR_ASSERT(result == NULL);
+#endif
PR_DELETE(thred);
}
return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
@@ -481,10 +488,14 @@ PR_IMPLEMENT(void) PR_DetachThread()
thred->next->prev = thred->prev;
PR_Unlock(pt_book.ml);
+ if (NULL != thred->io_cv)
+ PR_DestroyCondVar(thred->io_cv);
rv = pthread_setspecific(pt_book.key, NULL);
PR_ASSERT(0 == rv);
PR_DELETE(thred->stack);
+#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread));
+#endif
PR_DELETE(thred);
}
} /* PR_DetachThread */
@@ -612,17 +623,27 @@ PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred)
** I don't expect very many threads to be waiting on
** a single condition and I don't expect interrupt to
** be used very often.
+ **
+ ** I don't know why I thought this would work. Must have
+ ** been one of those weaker momements after I'd been
+ ** smelling the vapors.
+ **
+ ** Even with the followng changes it is possible that
+ ** the pointer to the condition variable is pointing
+ ** at a bogus value. Will the unerlying code detect
+ ** that?
*/
- PRCondVar *victim;
- PR_ASSERT(thred != NULL);
+ PRCondVar *cv;
+ PR_ASSERT(NULL != thred);
+ if (NULL == thred) return PR_FAILURE;
+
thred->state |= PT_THREAD_ABORTED;
- victim = thred->waiting;
- if (NULL != victim)
+
+ cv = thred->waiting;
+ if (NULL != cv)
{
- PRIntn haveLock = pthread_equal(victim->lock->owner, pthread_self());
- if (!haveLock) PR_Lock(victim->lock);
- PR_NotifyAllCondVar(victim);
- if (!haveLock) PR_Unlock(victim->lock);
+ PRIntn rv = pthread_cond_broadcast(&cv->cv);
+ PR_ASSERT(0 == rv);
}
return PR_SUCCESS;
} /* PR_Interrupt */
@@ -654,11 +675,11 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
}
else
{
- PRCondVar *cv = PR_NewCondVar(pt_book.ml);
+ PRCondVar *cv = PR_NewCondVar(_pr_sleeplock);
PR_ASSERT(cv != NULL);
- PR_Lock(pt_book.ml);
+ PR_Lock(_pr_sleeplock);
rv = PR_WaitCondVar(cv, ticks);
- PR_Unlock(pt_book.ml);
+ PR_Unlock(_pr_sleeplock);
PR_DestroyCondVar(cv);
}
return rv;
@@ -1252,7 +1273,9 @@ PR_IMPLEMENT(void) PR_SuspendAll()
{
PRIntn rv;
+#ifdef DEBUG
suspendAllOn = PR_TRUE;
+#endif
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
/*
* turn off preemption - i.e add virtual alarm signal to the set of
@@ -1275,7 +1298,9 @@ PR_IMPLEMENT(void) PR_ResumeAll()
rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL);
PR_ASSERT(0 == rv);
+#ifdef DEBUG
suspendAllOn = PR_FALSE;
+#endif
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n"));
} /* PR_ResumeAll */
diff --git a/pr/src/threads/combined/prucv.c b/pr/src/threads/combined/prucv.c
index 08962d9f..bf2bd551 100644
--- a/pr/src/threads/combined/prucv.c
+++ b/pr/src/threads/combined/prucv.c
@@ -26,7 +26,7 @@
** Notify one thread that it has finished waiting on a condition variable
** Caller must hold the _PR_CVAR_LOCK(cv)
*/
-PRBool NotifyThread (PRThread *thread, PRThread *me)
+PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
{
PRBool rv;
@@ -274,7 +274,7 @@ void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me)
PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
#endif
if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) {
- if (NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
+ if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
break;
}
q = q->next;
@@ -381,7 +381,7 @@ void _PR_ClockInterrupt(void)
if (thread->wait.cvar) {
PRThreadPriority pri;
- /* Do work very similar to what NotifyThread does */
+ /* Do work very similar to what _PR_NotifyThread does */
PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
/* Make thread runnable */
@@ -545,7 +545,7 @@ PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
q = cvar->condQ.next;
while (q != &cvar->condQ) {
PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
- NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+ _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
q = q->next;
}
_PR_CVAR_UNLOCK(cvar);
@@ -623,7 +623,7 @@ PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
q = cvar->condQ.next;
while (q != &cvar->condQ) {
PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
- NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+ _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
q = q->next;
}
_PR_MD_UNLOCK( &(cvar->ilock) );
diff --git a/pr/src/threads/combined/prulock.c b/pr/src/threads/combined/prulock.c
index 0ec89fc9..2ac56c57 100644
--- a/pr/src/threads/combined/prulock.c
+++ b/pr/src/threads/combined/prulock.c
@@ -260,18 +260,26 @@ PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
add this thread thread in the right priority order so when the unlock
occurs, the thread with the higher priority will get the lock.
*/
- /* Sort thread into lock's waitQ at appropriate point */
q = lock->waitQ.next;
-
- /* Now scan the list for where to insert this entry */
- while (q != &lock->waitQ) {
- t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next);
- if (me->priority > t->priority) {
- /* Found a lower priority thread to insert in front of */
- break;
- }
- q = q->next;
- }
+ if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority ==
+ _PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) {
+ /*
+ * If all the threads in the lock waitQ have the same priority,
+ * then avoid scanning the list: insert the element at the end.
+ */
+ q = &lock->waitQ;
+ } else {
+ /* Sort thread into lock's waitQ at appropriate point */
+ /* Now scan the list for where to insert this entry */
+ while (q != &lock->waitQ) {
+ t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next);
+ if (me->priority > t->priority) {
+ /* Found a lower priority thread to insert in front of */
+ break;
+ }
+ q = q->next;
+ }
+ }
PR_INSERT_BEFORE(&me->waitQLinks, q);
/*
diff --git a/pr/src/threads/combined/pruthr.c b/pr/src/threads/combined/pruthr.c
index 5a2174c6..2a3c38d6 100644
--- a/pr/src/threads/combined/pruthr.c
+++ b/pr/src/threads/combined/pruthr.c
@@ -121,7 +121,10 @@ void _PR_InitThreads(PRThreadType type, PRThreadPriority priority,
thread->flags |= _PR_PRIMORDIAL;
#endif
- /* Needs _PR_PRIMORDIAL flag set before calling _PR_MD_INIT_THREAD() */
+ /*
+ * Needs _PR_PRIMORDIAL flag set before calling
+ * _PR_MD_INIT_THREAD()
+ */
if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
/*
* XXX do what?
@@ -724,7 +727,7 @@ static void _PR_Resume(PRThread *thread)
}
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
-static PRThread *get_thread(_PRCPU *cpu)
+static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus)
{
PRThread *thread;
PRIntn pri;
@@ -755,16 +758,20 @@ static PRThread *get_thread(_PRCPU *cpu)
PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
if (thread->no_sched){
thread = NULL;
- /*
- * Need to wakeup cpus to avoid missing a
- * runnable thread
- */
- _PR_MD_WAKEUP_CPUS();
+ /*
+ * Need to wakeup cpus to avoid missing a
+ * runnable thread
+ * Waking up all CPU's need happen only once.
+ */
+
+ *wakeup_cpus = PR_TRUE;
continue;
} else if (thread->io_pending == PR_TRUE) {
/*
* A thread that is blocked for I/O needs to run
- * on the same cpu on which it was blocked
+ * on the same cpu on which it was blocked. This is because
+ * the cpu's ioq is accessed without lock protection and scheduling
+ * the thread on a different cpu would preclude this optimization.
*/
thread = NULL;
continue;
@@ -772,7 +779,7 @@ static PRThread *get_thread(_PRCPU *cpu)
/* Pull thread off of its run queue */
_PR_DEL_RUNQ(thread);
_PR_RUNQ_UNLOCK(cpu);
- return(thread);
+ return(thread);
}
}
}
@@ -800,6 +807,9 @@ void _PR_Schedule(void)
PRUint32 r;
PRCList *qp;
PRIntn priMin, priMax;
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+ PRBool wakeup_cpus;
+#endif
/* Interrupts must be disabled */
PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
@@ -869,17 +879,25 @@ void _PR_Schedule(void)
_PR_RUNQ_UNLOCK(cpu);
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+
+ wakeup_cpus = PR_FALSE;
_PR_CPU_LIST_LOCK();
for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
if (cpu != _PR_CPU_PTR(qp)) {
- if ((thread = get_thread(_PR_CPU_PTR(qp))) != NULL) {
- thread->cpu = cpu;
- _PR_CPU_LIST_UNLOCK();
- goto found_thread;
- }
+ if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus))
+ != NULL) {
+ thread->cpu = cpu;
+ _PR_CPU_LIST_UNLOCK();
+ if (wakeup_cpus == PR_TRUE)
+ _PR_MD_WAKEUP_CPUS();
+ goto found_thread;
+ }
}
}
_PR_CPU_LIST_UNLOCK();
+ if (wakeup_cpus == PR_TRUE)
+ _PR_MD_WAKEUP_CPUS();
+
#endif /* _PR_LOCAL_THREADS_ONLY */
idle_thread:
diff --git a/pr/src/threads/prcthr.c b/pr/src/threads/prcthr.c
index cf87e22b..6b3c80c7 100644
--- a/pr/src/threads/prcthr.c
+++ b/pr/src/threads/prcthr.c
@@ -18,6 +18,7 @@
#include "primpl.h"
+extern PRLock *_pr_sleeplock; /* allocated and initialized in prinit */
/*
** Routines common to both native and user threads.
**
@@ -85,8 +86,7 @@ PR_IMPLEMENT(PRStatus) PR_Yield()
*/
PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout)
{
- static PRLock *ml = NULL;
- PRStatus rv = PR_SUCCESS;
+ PRStatus rv = PR_SUCCESS;
if (PR_INTERVAL_NO_WAIT == timeout)
{
/*
@@ -129,27 +129,20 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout)
** but the lock and cvar used are local to the implementation
** and not visible to the caller, therefore not notifiable.
*/
- if (ml == NULL) ml = PR_NewLock();
+ PRIntervalTime timein = PR_IntervalNow();
+ PRCondVar *cv = PR_NewCondVar(_pr_sleeplock);
- if (ml == NULL) rv = PR_FAILURE;
- else
+ PR_Lock(_pr_sleeplock);
+ while (rv == PR_SUCCESS)
{
- PRCondVar *cv = PR_NewCondVar(ml);
- PRIntervalTime timein = PR_IntervalNow();
-
- PR_Lock(ml);
- while (rv == PR_SUCCESS)
- {
- PRIntervalTime delta = PR_IntervalNow() - timein;
- if (delta > timeout) break;
- rv = PR_WaitCondVar(cv, timeout - delta);
- }
- PR_Unlock(ml);
-
- PR_DestroyCondVar(cv);
+ PRIntervalTime delta = PR_IntervalNow() - timein;
+ if (delta > timeout) break;
+ rv = PR_WaitCondVar(cv, timeout - delta);
}
+ PR_Unlock(_pr_sleeplock);
+ PR_DestroyCondVar(cv);
}
- return rv;
+ return rv;
}
PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread)
diff --git a/pr/src/threads/prdump.c b/pr/src/threads/prdump.c
index 471a0dfe..de8939c3 100644
--- a/pr/src/threads/prdump.c
+++ b/pr/src/threads/prdump.c
@@ -104,7 +104,7 @@ void _PR_DumpThreads(PRFileDesc *fd)
DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu));
}
-void PR_ShowStatus(void)
+PR_IMPLEMENT(void) PR_ShowStatus(void)
{
PRIntn is;
diff --git a/pr/tests/accept.c b/pr/tests/accept.c
index 226ae24d..79ab811f 100644
--- a/pr/tests/accept.c
+++ b/pr/tests/accept.c
@@ -75,7 +75,7 @@ extern void SetupMacPrintfLog(char *logFile);
#endif
PRIntervalTime timeoutTime;
-static PRInt32 count = 10;
+static PRInt32 count = 1;
static PRNetAddr serverAddr;
static PRThreadScope thread_scope = PR_LOCAL_THREAD;
@@ -118,9 +118,9 @@ ClientThread(void *_action)
PRInt32 iterations = count;
PRFileDesc *sock = NULL;
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(BASE_PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
for (; iterations--;) {
PRInt32 rv;
@@ -201,29 +201,26 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
/* First bind to the socket */
listenSock = PR_NewTCPSocket();
if (!listenSock) {
- if (!debug_mode)
- failed_already=1;
- else
+ failed_already=1;
+ if (debug_mode)
printf("unable to create listen socket\n");
return;
}
- listenAddr.inet.family = AF_INET;
+ listenAddr.inet.family = PR_AF_INET;
listenAddr.inet.port = PR_htons(BASE_PORT);
- listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+ listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
rv = PR_Bind(listenSock, &listenAddr);
if (rv == PR_FAILURE) {
- if (!debug_mode)
- failed_already=1;
- else
+ failed_already=1;
+ if (debug_mode)
printf("unable to bind\n");
return;
}
rv = PR_Listen(listenSock, 100);
if (rv == PR_FAILURE) {
- if (!debug_mode)
- failed_already=1;
- else
+ failed_already=1;
+ if (debug_mode)
printf("unable to listen\n");
return;
}
@@ -233,9 +230,8 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
(void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
PR_JOINABLE_THREAD, 0);
if (!clientThread) {
- if (!debug_mode)
- failed_already=1;
- else
+ failed_already=1;
+ if (debug_mode)
printf("error creating client thread\n");
return;
}
@@ -470,7 +466,6 @@ int main(int argc, char **argv)
}
PL_DestroyOptState(opt);
-
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
PR_STDIO_INIT();
@@ -495,9 +490,9 @@ int main(int argc, char **argv)
#ifdef WINNT
Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
#endif
+ Measure(TimeoutReadUpdatedTest, "PR_Accept()");
if (debug_mode)
printf("\nRun accept() timeout in the read tests\n");
- Measure(TimeoutReadUpdatedTest, "PR_Accept()");
Measure(TimeoutReadReadTest, "PR_AcceptRead()");
#ifdef WINNT
Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
diff --git a/pr/tests/alarm.c b/pr/tests/alarm.c
index 94b921c1..730e9de8 100644
--- a/pr/tests/alarm.c
+++ b/pr/tests/alarm.c
@@ -239,7 +239,7 @@ static PRIntervalTime Alarms1(PRUint32 loops)
PRAlarm *alarm;
AlarmData ad;
PRIntervalTime overhead, timein = PR_IntervalNow();
- PRIntervalTime duration = PR_SecondsToInterval(30);
+ PRIntervalTime duration = PR_SecondsToInterval(3);
PRLock *ml = PR_NewLock();
PRCondVar *cv = PR_NewCondVar(ml);
@@ -469,7 +469,7 @@ static PRUint32 TimeThis(
int prmain(int argc, char** argv)
{
- PRUint32 cpu, cpus = 2, loops = 100;
+ PRUint32 cpu, cpus = 0, loops = 0;
/* The command line argument: -d is used to determine if the test is being run
in debug mode. The regress tool requires only one line output:PASS or FAIL.
@@ -503,8 +503,8 @@ int prmain(int argc, char** argv)
PL_DestroyOptState(opt);
- if (cpus == 0) cpus = 2;
- if (loops == 0) loops = 100;
+ if (cpus == 0) cpus = 1;
+ if (loops == 0) loops = 4;
if (debug_mode)
printf("Alarm: Using %d loops\n", loops);
diff --git a/pr/tests/atomic.c b/pr/tests/atomic.c
index 784fd274..d5e334d5 100644
--- a/pr/tests/atomic.c
+++ b/pr/tests/atomic.c
@@ -59,6 +59,7 @@ PRIntn main(PRIntn argc, char **argv)
output, "PR_AtomicDecrement(%d) == %d: %s\n",
test, rv, (rv < 0) ? "PASSED" : "FAILED");
+ /* set to a different value */
test = -2;
rv = PR_AtomicSet(&test, 2);
result = result | (((rv == -2) && (test == 2)) ? 0 : 1);
@@ -66,6 +67,14 @@ PRIntn main(PRIntn argc, char **argv)
output, "PR_AtomicSet(%d) == %d: %s\n",
test, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED");
+ /* set to the same value */
+ test = -2;
+ rv = PR_AtomicSet(&test, -2);
+ result = result | (((rv == -2) && (test == -2)) ? 0 : 1);
+ PR_fprintf(
+ output, "PR_AtomicSet(%d) == %d: %s\n",
+ test, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED");
+
PR_fprintf(
output, "Atomic operations test %s\n",
(result == 0) ? "PASSED" : "FAILED");
diff --git a/pr/tests/attach.c b/pr/tests/attach.c
index 53598bd3..3fa38d49 100644
--- a/pr/tests/attach.c
+++ b/pr/tests/attach.c
@@ -48,16 +48,9 @@
#include <stdio.h>
#ifdef WIN32
-#include "process.h"
+#include <windows.h>
+#include <process.h>
#elif defined(_PR_PTHREADS)
-/*
- * XXX: On Linux 2.0.27 (installed on tioman.mcom.com), sched.h uses
- * this _P macro that seems to be undefined. I suspect that it is
- * a typo (should be __P).
- */
-#if defined(LINUX)
-#define _P(x) __P(x)
-#endif
#include <pthread.h>
#include "md/_pth.h"
#elif defined(IRIX)
diff --git a/pr/tests/cltsrv.c b/pr/tests/cltsrv.c
index b9da03c2..346ff2f9 100644
--- a/pr/tests/cltsrv.c
+++ b/pr/tests/cltsrv.c
@@ -867,31 +867,16 @@ static void PR_CALLBACK Server(void *arg)
} /* Server */
-#if 0 && defined(DEBUG) && defined(_PR_PTHREADS)
+#if defined(DEBUG) && defined(_PR_PTHREADS)
static void PrintPthreadStats(void)
{
- char buffer[100];
- PRExplodedTime tod;
- PTDebug stats = PT_GetStats();
- PRInt64 elapsed, aMil;
- PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod);
- (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
-
- LL_SUB(elapsed, PR_Now(), stats.timeStarted);
- LL_I2L(aMil, 1000000);
- LL_DIV(elapsed, elapsed, aMil);
- PR_fprintf(debug_out, "\npthread statistics\n\tstarted: %s[%lld]\n", buffer, elapsed);
- PR_fprintf(debug_out, "\tmissed predictions: %u\n", stats.predictionsFoiled);
- PR_fprintf(debug_out, "\tpollingList max: %u\n", stats.pollingListMax);
- PR_fprintf(debug_out, "\tcontinuations served: %u\n", stats.continuationsServed);
- PR_fprintf(debug_out, "\trecycles needed: %u\n", stats.recyclesNeeded);
- PR_fprintf(debug_out, "\tquiescent IO: %u\n", stats.quiescentIO);
+ PT_FPrintStats(debug_out, "\nPThread Statistics\n");
} /* PrintPthreadStats */
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
static void WaitForCompletion(PRIntn execution)
{
-#if 0 && defined(DEBUG) && defined(_PR_PTHREADS)
+#if defined(DEBUG) && defined(_PR_PTHREADS)
while (execution > 0)
{
PRIntn dally = (execution > 30) ? 30 : execution;
@@ -930,7 +915,8 @@ static Verbosity IncrementVerbosity(void)
PRIntn verboge = (PRIntn)verbosity + 1;
return (Verbosity)verboge;
} /* IncrementVerbosity */
-PRIntn xmain(PRIntn argc, char** argv)
+
+PRIntn main(PRIntn argc, char** argv)
{
PRUintn index;
PRBool boolean;
@@ -960,7 +946,7 @@ PRIntn xmain(PRIntn argc, char** argv)
*/
PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:l:w:W:e:s:vdhp");
+ PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:vdhp");
debug_out = PR_GetSpecialFD(PR_StandardError);
@@ -990,8 +976,6 @@ PRIntn xmain(PRIntn argc, char** argv)
case 'c': /* number of client threads */
clients = atoi(opt->value);
break;
- case 'l': /* number of outer loops */
- break;
case 'w': /* minimum server worker threads */
workersMin = atoi(opt->value);
break;
@@ -1212,40 +1196,12 @@ PRIntn xmain(PRIntn argc, char** argv)
cltsrv_log_file, TEST_LOG_ALWAYS,
("main(0x%lx): test complete\n", PR_CurrentThread()));
-#if 0 && defined(DEBUG) && defined(_PR_PTHREADS)
+#if defined(DEBUG) && defined(_PR_PTHREADS)
PrintPthreadStats();
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
TimeOfDayMessage("Test exiting at", PR_CurrentThread());
return 0;
-} /* xmain */
-
-PRIntn main(PRIntn argc, char **argv)
-{
- PRIntn loops = 1;
- PRIntn rv;
- PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:l:w:W:e:s:vdhp");
- while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
- {
- if (PL_OPT_BAD == os) continue;
- switch (opt->option)
- {
- case 'l': /* number of outer loops */
- loops = atoi(opt->value);
- break;
- default:
- break;
- }
- }
- PL_DestroyOptState(opt);
- while (loops-- > 0)
- {
- rv = xmain(argc, argv);
- PR_fprintf(debug_out, "*****\n\n");
- if (0 != rv) break;
- }
- return rv;
} /* main */
/* cltsrv.c */
diff --git a/pr/tests/intrupt.c b/pr/tests/intrupt.c
index 7cd9a428..d8d1de53 100644
--- a/pr/tests/intrupt.c
+++ b/pr/tests/intrupt.c
@@ -194,8 +194,8 @@ void PR_CALLBACK Intrupt(void *arg)
if (debug_mode) printf("Part III\n");
listner = PR_NewTCPSocket();
memset(&netaddr, 0, sizeof(netaddr));
- netaddr.inet.ip = PR_htonl(INADDR_ANY);
- netaddr.inet.family = AF_INET;
+ netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+ netaddr.inet.family = PR_AF_INET;
do
{
netaddr.inet.port = PR_htons(port);
diff --git a/pr/tests/io_timeout.c b/pr/tests/io_timeout.c
index 74914efe..2e1e46f2 100644
--- a/pr/tests/io_timeout.c
+++ b/pr/tests/io_timeout.c
@@ -75,9 +75,9 @@ thread_main(void *_info)
goto dead;
}
- listenAddr.inet.family = AF_INET;
+ listenAddr.inet.family = PR_AF_INET;
listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
- listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+ listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
rv = PR_Bind(listenSock, &listenAddr);
if (rv == PR_FAILURE) {
printf("unable to bind\n");
diff --git a/pr/tests/ipv6.c b/pr/tests/ipv6.c
index 3eb5b841..63ddfbf6 100644
--- a/pr/tests/ipv6.c
+++ b/pr/tests/ipv6.c
@@ -65,6 +65,7 @@ static PRStatus PrintAddress(const PRNetAddr* address)
else
{
PR_fprintf(err, "\t%s\n", buffer);
+ memset(&translation, 0, sizeof(translation));
rv = PR_StringToNetAddr(buffer, &translation);
if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr");
else
diff --git a/pr/tests/layer.c b/pr/tests/layer.c
index 83aea2d9..e6be944f 100644
--- a/pr/tests/layer.c
+++ b/pr/tests/layer.c
@@ -61,7 +61,7 @@ static PRFileDesc *PushLayer(PRFileDesc *stack)
if (verbosity > quiet)
PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
PR_ASSERT(PR_SUCCESS == rv);
- return layer;
+ return stack;
} /* PushLayer */
static PRFileDesc *PopLayer(PRFileDesc *stack)
@@ -149,19 +149,91 @@ static void PR_CALLBACK Server(void *arg)
} /* Server */
+static PRInt32 PR_CALLBACK MyRecv(
+ PRFileDesc *fd, void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ char *b = (char*)buf;
+ PRFileDesc *lo = fd->lower;
+ PRInt32 rv, readin = 0, request;
+ rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout);
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MyRecv sending permission for %d bytes\n", request);
+ if (0 < rv)
+ {
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MyRecv received permission request for %d bytes\n", request);
+ rv = lo->methods->send(
+ lo, &request, sizeof(request), flags, timeout);
+ if (0 < rv)
+ {
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MyRecv sending permission for %d bytes\n", request);
+ while (readin < request)
+ {
+ rv = lo->methods->recv(
+ lo, b + readin, amount - readin, flags, timeout);
+ if (rv <= 0) break;
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MyRecv received %d bytes\n", rv);
+ readin += rv;
+ }
+ rv = readin;
+ }
+ }
+ return rv;
+} /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+ PRFileDesc *fd, const void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ PRFileDesc *lo = fd->lower;
+ const char *b = (const char*)buf;
+ PRInt32 rv, wroteout = 0, request;
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MySend asking permission to send %d bytes\n", amount);
+ rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout);
+ if (0 < rv)
+ {
+ rv = lo->methods->recv(
+ lo, &request, sizeof(request), flags, timeout);
+ if (0 < rv)
+ {
+ PR_ASSERT(request == amount);
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MySend got permission to send %d bytes\n", request);
+ while (wroteout < request)
+ {
+ rv = lo->methods->send(
+ lo, b + wroteout, request - wroteout, flags, timeout);
+ if (rv <= 0) break;
+ if (verbosity > chatty) PR_fprintf(
+ logFile, "MySend wrote %d bytes\n", rv);
+ wroteout += rv;
+ }
+ rv = amount;
+ }
+ }
+ return rv;
+} /* MySend */
+
static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
{
- PRIntn verbage = (PRIntn)verbosity;
- return (Verbosity)(verbage + delta);
+ PRIntn verbage = (PRIntn)verbosity + delta;
+ if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+ else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+ return (Verbosity)verbage;
} /* ChangeVerbosity */
PRIntn main(PRIntn argc, char **argv)
{
PRStatus rv;
+ PRIntn mits;
PLOptStatus os;
PRFileDesc *client, *service;
const char *server_name = NULL;
- PRIOMethods const *stubMethods;
+ const PRIOMethods *stubMethods;
PRThread *client_thread, *server_thread;
PRThreadScope thread_scope = PR_LOCAL_THREAD;
PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
@@ -206,11 +278,13 @@ PRIntn main(PRIntn argc, char **argv)
stubMethods = PR_GetDefaultIOMethods();
/*
- ** Normally here one would pick and choose between the default
- ** stub methods and local, unique implmentation. I'm not going
- ** quite that far.
+ ** The protocol we're going to implement is one where in order to initiate
+ ** a send, the sender must first solicit permission. Therefore, every
+ ** send is really a send - receive - send sequence.
*/
- myMethods = *stubMethods;
+ myMethods = *stubMethods; /* first get the entire batch */
+ myMethods.recv = MyRecv; /* then override the ones we care about */
+ myMethods.send = MySend; /* then override the ones we care about */
if (NULL == server_name)
rv = PR_InitializeNetAddr(
@@ -226,6 +300,7 @@ PRIntn main(PRIntn argc, char **argv)
/* one type w/o layering */
+ mits = minor_iterations;
while (major_iterations-- > 0)
{
if (verbosity > silent)
@@ -233,6 +308,7 @@ PRIntn main(PRIntn argc, char **argv)
client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+ minor_iterations = mits;
server_thread = PR_CreateThread(
PR_USER_THREAD, Server, service,
PR_PRIORITY_HIGH, thread_scope,
@@ -261,6 +337,7 @@ PRIntn main(PRIntn argc, char **argv)
client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+ minor_iterations = mits;
server_thread = PR_CreateThread(
PR_USER_THREAD, Server, PushLayer(service),
PR_PRIORITY_HIGH, thread_scope,
diff --git a/pr/tests/many_cv.c b/pr/tests/many_cv.c
index 75c898e7..ae973655 100644
--- a/pr/tests/many_cv.c
+++ b/pr/tests/many_cv.c
@@ -24,10 +24,18 @@
#include "prlog.h"
#include "prmem.h"
+#include "primpl.h"
+
#include "plgetopt.h"
#include <stdlib.h>
+static PRInt32 Random(void)
+{
+ PRInt32 ran = rand() >> 16;
+ return ran;
+} /* Random */
+
static void Help(void)
{
PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
@@ -43,15 +51,19 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
PRIntn index, nl;
PRLock *ml = NULL;
PRCondVar **cv = NULL;
- PRIntn loops = 1, cvs = 10;
+ PRBool stats = PR_FALSE;
+ PRIntn nc, loops = 1, cvs = 10;
PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
- PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:");
+ PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:");
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
{
if (PL_OPT_BAD == os) continue;
switch (opt->option)
{
+ case 's': /* number of CVs to association with lock */
+ stats = PR_TRUE;
+ break;
case 'c': /* number of CVs to association with lock */
cvs = atoi(opt->value);
break;
@@ -86,7 +98,12 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
{
PR_Lock(ml);
for (nl = 0; nl < cvs; ++nl)
- PR_NotifyCondVar(cv[nl]);
+ {
+ PRInt32 ran = Random() % 8;
+ if (0 == ran) PR_NotifyAllCondVar(cv[nl]);
+ else for (nc = 0; nc < ran; ++nc)
+ PR_NotifyCondVar(cv[nl]);
+ }
PR_Unlock(ml);
}
@@ -97,6 +114,9 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
printf("PASS\n");
+#if defined(DEBUG) && defined(_PR_PTHREADS)
+ PT_FPrintStats(err, "\nPThread Statistics\n");
+#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
return 0;
}
diff --git a/pr/tests/nonblock.c b/pr/tests/nonblock.c
index 24e6db73..c15807b7 100644
--- a/pr/tests/nonblock.c
+++ b/pr/tests/nonblock.c
@@ -74,9 +74,9 @@ clientThreadFunc(void *arg)
PRStatus retVal;
PRInt32 nBytes;
- addr.inet.family = AF_INET;
+ addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port);
- addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
/* time 1 */
@@ -148,8 +148,8 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
fprintf(stderr, "Can't create a new TCP socket\n");
exit(1);
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
diff --git a/pr/tests/poll_nm.c b/pr/tests/poll_nm.c
index f092be6a..a8995b3b 100644
--- a/pr/tests/poll_nm.c
+++ b/pr/tests/poll_nm.c
@@ -85,9 +85,9 @@ clientThreadFunc(void *arg)
PRStatus sts;
PRInt32 n;
- addr.inet.family = AF_INET;
+ addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port);
- addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
memset(buf, 0, sizeof(buf));
PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
@@ -162,8 +162,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
@@ -188,8 +188,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
diff --git a/pr/tests/poll_to.c b/pr/tests/poll_to.c
index 767c41da..e617efd1 100644
--- a/pr/tests/poll_to.c
+++ b/pr/tests/poll_to.c
@@ -105,8 +105,8 @@ int main(int argc, char **argv)
if (!debug_mode) failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
@@ -130,8 +130,8 @@ int main(int argc, char **argv)
if (!debug_mode) failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
diff --git a/pr/tests/priotest.c b/pr/tests/priotest.c
index 5c53daae..cdc76953 100644
--- a/pr/tests/priotest.c
+++ b/pr/tests/priotest.c
@@ -21,6 +21,11 @@
* Purpose: testing priorities
*/
+#ifdef XP_MAC
+#error "This test does not run on Macintosh"
+#else
+
+
#include "prcmon.h"
#include "prinit.h"
#include "prinrval.h"
@@ -37,22 +42,12 @@
#include <stdio.h>
#include <stdlib.h>
-#ifdef XP_MAC
-#include "prlog.h"
-unsigned int PR_fprintf(PRFileDesc *fd, const char *fmt, ...)
-{
-PR_LogPrint(fmt);
-return 0;
-}
-#define printf PR_LogPrint
-extern void SetupMacPrintfLog(char *logFile);
-#endif
-
#define DEFAULT_DURATION 20
static PRBool failed = PR_FALSE;
static PRIntervalTime oneSecond;
static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
static PRUint32 PerSecond(PRIntervalTime timein)
{
@@ -96,22 +91,63 @@ static void Help(void)
debug_out, "-d\tturn on debugging output (default: FALSE)\n");
} /* Help */
+static void RudimentaryTests(void)
+{
+ /*
+ ** Try some rudimentary tests like setting valid priority and
+ ** getting it back, or setting invalid priorities and getting
+ ** back a valid answer.
+ */
+ PRThreadPriority priority;
+ PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
+ priority = PR_GetThreadPriority(PR_GetCurrentThread());
+ failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
+ ? PR_TRUE : PR_FALSE;
+ if (debug_mode && (PR_PRIORITY_URGENT != priority))
+ {
+ PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
+ }
+
+
+ PR_SetThreadPriority(
+ PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
+ priority = PR_GetThreadPriority(PR_GetCurrentThread());
+ failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
+ ? PR_TRUE : PR_FALSE;
+ if (debug_mode && (PR_PRIORITY_FIRST != priority))
+ {
+ PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
+ }
+
+ PR_SetThreadPriority(
+ PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
+ priority = PR_GetThreadPriority(PR_GetCurrentThread());
+ failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
+ ? PR_TRUE : PR_FALSE;
+ if (debug_mode && (PR_PRIORITY_LAST != priority))
+ {
+ PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
+ }
+
+} /* RudimentataryTests */
+
+static void CreateThreads(PRInt32 *lowCount, PRInt32 *highCount)
+{
+ (void)PR_CreateThread(
+ PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW,
+ PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+ (void)PR_CreateThread(
+ PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH,
+ PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+} /* CreateThreads */
+
PRIntn main(PRIntn argc, char **argv)
{
PLOptStatus os;
- PRThread *low, *high;
- PRThreadPriority priority;
- PRBool debug_mode = PR_FALSE;
PRIntn duration = DEFAULT_DURATION;
PRUint32 totalCount, highCount = 0, lowCount = 0;
PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
-
-#ifdef XP_MAC
- SetupMacPrintfLog("priotest.log");
- debug_mode = PR_TRUE;
-#endif
-
debug_out = PR_STDOUT;
oneSecond = PR_SecondsToInterval(1);
@@ -137,53 +173,13 @@ PRIntn main(PRIntn argc, char **argv)
if (duration == 0) duration = DEFAULT_DURATION;
+ RudimentaryTests();
+
printf("Priority test: running for %d seconds\n\n", duration);
(void)PerSecond(PR_IntervalNow());
totalCount = PerSecond(PR_IntervalNow());
- /*
- ** Try some rudimentary tests like setting valid priority and
- ** getting it back, or setting invalid priorities and getting
- ** back a valid answer.
- */
- PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
- priority = PR_GetThreadPriority(PR_GetCurrentThread());
- failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
- ? PR_TRUE : PR_FALSE;
- if (debug_mode && (PR_PRIORITY_URGENT != priority))
- {
- PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
- }
-
-/*
- The following test is bogus. PRThreadPriority is enum and (PR_PRIORITY_FIRST - 1)
- evaluates to 255 (at least on Mac). This causes the pinning test in PR_SetThreadPriority
- to fail. That test in PR_SetThreadPriority should be looked at.
-*/
-#if 0
- PR_SetThreadPriority(
- PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
- priority = PR_GetThreadPriority(PR_GetCurrentThread());
- failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
- ? PR_TRUE : PR_FALSE;
- if (debug_mode && (PR_PRIORITY_FIRST != priority))
- {
- PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
- }
-#endif
-
- PR_SetThreadPriority(
- PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
- priority = PR_GetThreadPriority(PR_GetCurrentThread());
- failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
- ? PR_TRUE : PR_FALSE;
- if (debug_mode && (PR_PRIORITY_LAST != priority))
- {
- PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
- }
-
-
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
if (debug_mode)
@@ -195,27 +191,8 @@ PRIntn main(PRIntn argc, char **argv)
PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount);
}
-#ifdef XP_MAC
- if (debug_mode)
- {
- PR_fprintf(debug_out,
- "On Mac, this test should hang indefinitely \n");
- PR_fprintf( debug_out,
- "because low priority task never gives up time \n");
- PR_fprintf( debug_out, "and the program will hang there.\n");
- }
-
-#endif
-
- low = PR_CreateThread(
- PR_USER_THREAD, Low, &lowCount, PR_PRIORITY_LOW,
- PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
-
- high = PR_CreateThread(
- PR_USER_THREAD, High, &highCount, PR_PRIORITY_HIGH,
- PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
-
duration = (duration + 4) / 5;
+ CreateThreads(&lowCount, &highCount);
while (duration--)
{
PRIntn loop = 5;
@@ -224,11 +201,14 @@ PRIntn main(PRIntn argc, char **argv)
PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
}
+
PR_ProcessExit((failed) ? 1 : 0);
- PR_ASSERT(!"Can't get here");
+ PR_ASSERT(!"You can't get here -- but you did!");
return 1; /* or here */
} /* main */
+#endif /* ifdef XP_MAC */
+
/* priotest.c */
diff --git a/pr/tests/ranfile.c b/pr/tests/ranfile.c
index 6869f3e4..1ee6ca20 100644
--- a/pr/tests/ranfile.c
+++ b/pr/tests/ranfile.c
@@ -284,7 +284,7 @@ int main (int argc, char *argv[])
debug_mode = 1;
break;
case 'l': /* limiting number */
- limit = limit = atoi(opt->value);
+ limit = atoi(opt->value);
break;
case 't': /* number of threads */
threads = atoi(opt->value);
diff --git a/pr/tests/sel_spd.c b/pr/tests/sel_spd.c
index a0e76a23..f4ce1483 100644
--- a/pr/tests/sel_spd.c
+++ b/pr/tests/sel_spd.c
@@ -153,10 +153,10 @@ _server_thread(void *arg_id)
goto done;
}
- memset(&sa, 0 , PR_NETADDR_SIZE(&sa));
- sa.inet.family = AF_INET;
+ memset(&sa, 0 , sizeof(sa));
+ sa.inet.family = PR_AF_INET;
sa.inet.port = PORT_BASE + *id;
- sa.inet.ip = PR_htonl(INADDR_ANY);
+ sa.inet.ip = PR_htonl(PR_INADDR_ANY);
if ( PR_Bind(sock, &sa) < 0) {
fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno);
@@ -283,7 +283,7 @@ _client_thread(void *arg_id)
goto done;
}
- memset(&sa, 0 , PR_NETADDR_SIZE(&sa));
+ memset(&sa, 0 , sizeof(sa));
rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa);
PR_ASSERT(PR_SUCCESS == rv);
diff --git a/pr/tests/selct_nm.c b/pr/tests/selct_nm.c
index b051b132..c8bbe30e 100644
--- a/pr/tests/selct_nm.c
+++ b/pr/tests/selct_nm.c
@@ -51,6 +51,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+
PRIntn failed_already=0;
PRIntn debug_mode;
@@ -63,9 +64,9 @@ clientThreadFunc(void *arg)
char buf[128];
int i;
- addr.inet.family = AF_INET;
+ addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port);
- addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
for (i = 0; i < 5; i++) {
@@ -127,8 +128,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
@@ -152,8 +153,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
diff --git a/pr/tests/selct_to.c b/pr/tests/selct_to.c
index d538acc0..0b13a814 100644
--- a/pr/tests/selct_to.c
+++ b/pr/tests/selct_to.c
@@ -103,8 +103,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
@@ -128,8 +128,8 @@ int main(int argc, char **argv)
failed_already=1;
goto exit_now;
}
- addr.inet.family = AF_INET;
- addr.inet.ip = PR_htonl(INADDR_ANY);
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n");
diff --git a/pr/tests/servr_kk.c b/pr/tests/servr_kk.c
index dac96e41..1efc7c61 100644
--- a/pr/tests/servr_kk.c
+++ b/pr/tests/servr_kk.c
@@ -232,9 +232,9 @@ ServerSetup(void)
}
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
@@ -328,9 +328,9 @@ ClientThreadFunc(void *unused)
if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) {
diff --git a/pr/tests/servr_ku.c b/pr/tests/servr_ku.c
index edf55bbf..e394ec4f 100644
--- a/pr/tests/servr_ku.c
+++ b/pr/tests/servr_ku.c
@@ -233,9 +233,9 @@ ServerSetup(void)
}
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
@@ -329,9 +329,9 @@ ClientThreadFunc(void *unused)
if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) {
diff --git a/pr/tests/servr_uk.c b/pr/tests/servr_uk.c
index c71a49ba..c462a56f 100644
--- a/pr/tests/servr_uk.c
+++ b/pr/tests/servr_uk.c
@@ -235,9 +235,9 @@ ServerSetup(void)
}
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
@@ -331,9 +331,9 @@ ClientThreadFunc(void *unused)
if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) {
diff --git a/pr/tests/servr_uu.c b/pr/tests/servr_uu.c
index d5dbe679..ffa36a23 100644
--- a/pr/tests/servr_uu.c
+++ b/pr/tests/servr_uu.c
@@ -233,9 +233,9 @@ ServerSetup(void)
}
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
@@ -329,9 +329,9 @@ ClientThreadFunc(void *unused)
if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr));
- serverAddr.inet.family = AF_INET;
+ serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT);
- serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) {
diff --git a/pr/tests/socket.c b/pr/tests/socket.c
index ccf04e8a..33ce32bb 100644
--- a/pr/tests/socket.c
+++ b/pr/tests/socket.c
@@ -267,9 +267,9 @@ TCP_Server(void *arg)
goto exit;
}
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = AF_INET;
+ netaddr.inet.family = PR_AF_INET;
netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
- netaddr.inet.ip = PR_htonl(INADDR_ANY);
+ netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
/*
* try a few times to bind server's address, if addresses are in
* use
@@ -386,9 +386,9 @@ UDP_Server(void *arg)
return;
}
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = AF_INET;
+ netaddr.inet.family = PR_AF_INET;
netaddr.inet.port = PR_htons(UDP_SERVER_PORT);
- netaddr.inet.ip = PR_htonl(INADDR_ANY);
+ netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
/*
* try a few times to bind server's address, if addresses are in
* use
@@ -426,10 +426,10 @@ UDP_Server(void *arg)
/*
* We can't use the IP address returned by PR_GetSockName in
* netaddr.inet.ip because netaddr.inet.ip is returned
- * as 0 (= INADDR_ANY).
+ * as 0 (= PR_INADDR_ANY).
*/
- udp_server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ udp_server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
/*
* Wake up parent thread because server address is bound and made
@@ -624,8 +624,8 @@ UDP_Client(void *arg)
* number
*/
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = AF_INET;
- netaddr.inet.ip = PR_htonl(INADDR_ANY);
+ netaddr.inet.family = PR_AF_INET;
+ netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
netaddr.inet.port = PR_htons(0);
if (PR_Bind(sockfd, &netaddr) < 0) {
fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
@@ -796,7 +796,7 @@ TCP_Socket_Client_Server_Test(void)
return -1;
}
cparamp->server_addr = tcp_server_addr;
- cparamp->server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
cparamp->exit_mon = mon2;
cparamp->exit_counter = &thread_count;
cparamp->datalen = datalen;
@@ -1152,9 +1152,9 @@ TransmitFile_Server(void *arg)
goto exit;
}
memset(&netaddr, 0 , sizeof(netaddr));
- netaddr.inet.family = AF_INET;
+ netaddr.inet.family = PR_AF_INET;
netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
- netaddr.inet.ip = PR_htonl(INADDR_ANY);
+ netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
/*
* try a few times to bind server's address, if addresses are in
* use
@@ -1480,7 +1480,7 @@ Socket_Misc_Test(void)
goto done;
}
cparamp->server_addr = tcp_server_addr;
- cparamp->server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+ cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
cparamp->exit_mon = mon2;
cparamp->exit_counter = &thread_count;
cparamp->datalen = datalen;
diff --git a/pr/tests/suspend.c b/pr/tests/suspend.c
index a09262fd..e44dc97b 100644
--- a/pr/tests/suspend.c
+++ b/pr/tests/suspend.c
@@ -39,13 +39,13 @@ PRMonitor *mon;
PRInt32 count;
PRInt32 alive;
-#define SLEEP_TIME 4 /* secs */
+#define SLEEP_TIME 4 /* secs */
void PR_CALLBACK
Level_2_Thread(void *arg)
{
- PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
- printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread());
+ PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
+ printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread());
return;
}
@@ -57,21 +57,21 @@ Level_1_Thread(void *arg)
PRThread *thr;
thr = PR_CreateThreadGCAble(PR_USER_THREAD,
- Level_2_Thread,
- NULL,
- PR_PRIORITY_HIGH,
- scope,
- PR_JOINABLE_THREAD,
- 0);
+ Level_2_Thread,
+ NULL,
+ PR_PRIORITY_HIGH,
+ scope,
+ PR_JOINABLE_THREAD,
+ 0);
if (!thr) {
printf("Could not create thread!\n");
} else {
- printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
- PR_GetCurrentThread(),
- (scope == PR_GLOBAL_THREAD) ?
- "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
- thr);
+ printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
+ PR_GetCurrentThread(),
+ (scope == PR_GLOBAL_THREAD) ?
+ "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+ thr);
PR_JoinThread(thr);
}
PR_EnterMonitor(mon);
@@ -83,18 +83,18 @@ Level_1_Thread(void *arg)
static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg)
{
-PRInt32 words;
-PRWord *registers;
-
- printf(
- "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread,
- (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ?
- "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i);
- registers = PR_GetGCRegisters(thread, 0, (int *)&words);
- printf("Regsters R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
- registers[0],registers[1],registers[2],registers[3]);
- printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
- return PR_SUCCESS;
+ PRInt32 words;
+ PRWord *registers;
+
+ printf(
+ "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread,
+ (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ?
+ "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i);
+ registers = PR_GetGCRegisters(thread, 0, (int *)&words);
+ printf("Regsters R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+ registers[0],registers[1],registers[2],registers[3]);
+ printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
+ return PR_SUCCESS;
}
static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
@@ -102,8 +102,8 @@ static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
PRThread *thr;
PRThread *me = PR_GetCurrentThread();
int n;
- PRInt32 words;
- PRWord *registers;
+ PRInt32 words;
+ PRWord *registers;
alive = 0;
mon = PR_NewMonitor();
@@ -111,30 +111,30 @@ static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
alive = count;
for (n=0; n<count; n++) {
thr = PR_CreateThreadGCAble(PR_USER_THREAD,
- Level_1_Thread,
- (void *)scope2,
- PR_PRIORITY_NORMAL,
- scope1,
- PR_UNJOINABLE_THREAD,
- 0);
+ Level_1_Thread,
+ (void *)scope2,
+ PR_PRIORITY_NORMAL,
+ scope1,
+ PR_UNJOINABLE_THREAD,
+ 0);
if (!thr) {
printf("Could not create thread!\n");
alive--;
}
- printf("Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
- PR_GetCurrentThread(),
- (scope1 == PR_GLOBAL_THREAD) ?
- "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
- thr);
-
+ printf("Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
+ PR_GetCurrentThread(),
+ (scope1 == PR_GLOBAL_THREAD) ?
+ "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+ thr);
+
PR_Sleep(0);
}
PR_SuspendAll();
PR_EnumerateThreads(print_thread, NULL);
- registers = PR_GetGCRegisters(me, 1, (int *)&words);
- printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
- registers[0],registers[1],registers[2],registers[3]);
- printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
+ registers = PR_GetGCRegisters(me, 1, (int *)&words);
+ printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+ registers[0],registers[1],registers[2],registers[3]);
+ printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
PR_ResumeAll();
/* Wait for all threads to exit */
@@ -171,27 +171,27 @@ static void CreateThreadsKK(void)
void
main(int argc, char **argv)
{
- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
PR_STDIO_INIT();
#ifdef XP_MAC
- SetupMacPrintfLog("suspend.log");
+ SetupMacPrintfLog("suspend.log");
#endif
- if (argc > 1) {
- count = atoi(argv[1]);
- } else {
- count = 5;
- }
+ if (argc > 1) {
+ count = atoi(argv[1]);
+ } else {
+ count = 5;
+ }
- printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test");
+ printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test");
CreateThreadsUU();
CreateThreadsUK();
CreateThreadsKU();
CreateThreadsKK();
- PR_SetConcurrency(2);
+ PR_SetConcurrency(2);
- printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n");
+ printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n");
CreateThreadsUK();
CreateThreadsKK();
diff --git a/pr/tests/testfile.c b/pr/tests/testfile.c
index c9173be5..d492a0ff 100644
--- a/pr/tests/testfile.c
+++ b/pr/tests/testfile.c
@@ -22,6 +22,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
static int _debug_on = 0;
diff --git a/pr/tests/thruput.c b/pr/tests/thruput.c
index 654a6bac..23843e19 100644
--- a/pr/tests/thruput.c
+++ b/pr/tests/thruput.c
@@ -46,7 +46,7 @@
#define SAMPLING_INTERVAL 10
#define BUFFER_SIZE (32 * 1024)
-static PRInt32 domain = AF_INET;
+static PRInt32 domain = PR_AF_INET;
static PRInt32 protocol = 6; /* TCP */
static PRFileDesc *err = NULL;
static PRIntn concurrency = 1;
@@ -95,7 +95,7 @@ static void PR_CALLBACK Clientel(void *arg)
do
{
- xport = PR_Socket(domain, SOCK_STREAM, protocol);
+ xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
if (NULL == xport)
{
PL_FPrintError(err, "PR_Socket");
@@ -244,7 +244,7 @@ static void Server(void)
{
PRStatus rv;
PRNetAddr server_address, client_address;
- PRFileDesc *xport = PR_Socket(domain, SOCK_STREAM, protocol);
+ PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
if (NULL == xport)
{
@@ -327,7 +327,7 @@ PRIntn main(PRIntn argc, char **argv)
break;
#ifdef _PR_INET6
case '6': /* Use IPv6 */
- domain = AF_INET6;
+ domain = PR_AF_INET6;
PR_SetIPv6Enable(PR_TRUE);
break;
#endif /* _PR_INET6 */
diff --git a/pr/tests/tmocon.c b/pr/tests/tmocon.c
index f4721914..018c98b6 100644
--- a/pr/tests/tmocon.c
+++ b/pr/tests/tmocon.c
@@ -105,7 +105,7 @@ static PRStatus MakeReceiver(Shared *shared)
#if defined(_PR_INET6)
if (IN6_IS_ADDR_LOOPBACK(&shared->serverAddress.ipv6.ip))
#else
- if (PR_htonl(INADDR_LOOPBACK) == shared->serverAddress.inet.ip)
+ if (PR_htonl(PR_INADDR_LOOPBACK) == shared->serverAddress.inet.ip)
#endif
{
char *argv[3];
diff --git a/pr/tests/udpsrv.c b/pr/tests/udpsrv.c
index e3264a91..4e9292d1 100644
--- a/pr/tests/udpsrv.c
+++ b/pr/tests/udpsrv.c
@@ -82,8 +82,8 @@
#define NUM_UDP_DATAGRAMS_PER_CLIENT 5
#define UDP_SERVER_PORT 9050
#define UDP_CLIENT_PORT 9053
-/* #define MY_INADDR INADDR_ANY */
-#define MY_INADDR INADDR_LOOPBACK
+#define MY_INADDR PR_INADDR_ANY
+#define PEER_INADDR PR_INADDR_LOOPBACK
#define UDP_TIMEOUT 400000
/* #define UDP_TIMEOUT PR_INTERVAL_NO_TIMEOUT */
@@ -161,7 +161,7 @@ static void PR_CALLBACK UDP_Server( void *arg )
/* --- Initialize the sockaddr_in structure --- */
memset( &netaddr, 0, sizeof( netaddr ));
- netaddr.inet.family = AF_INET;
+ netaddr.inet.family = PR_AF_INET;
netaddr.inet.port = PR_htons( UDP_SERVER_PORT );
netaddr.inet.ip = PR_htonl( MY_INADDR );
@@ -290,7 +290,7 @@ static void PR_CALLBACK UDP_Client( void *arg )
/* --- Initialize the sockaddr_in structure --- */
memset( &netaddr, 0, sizeof( netaddr ));
- netaddr.inet.family = AF_INET;
+ netaddr.inet.family = PR_AF_INET;
netaddr.inet.ip = PR_htonl( MY_INADDR );
netaddr.inet.port = PR_htons( UDP_CLIENT_PORT );
@@ -327,8 +327,8 @@ static void PR_CALLBACK UDP_Client( void *arg )
/* --- Initialize the sockaddr_in structure --- */
memset( &netaddr, 0, sizeof( netaddr ));
- netaddr.inet.family = AF_INET;
- netaddr.inet.ip = PR_htonl( MY_INADDR );
+ netaddr.inet.family = PR_AF_INET;
+ netaddr.inet.ip = PR_htonl( PEER_INADDR );
netaddr.inet.port = PR_htons( UDP_SERVER_PORT );
/* --- send and receive packets until no more data left */
diff --git a/pr/tests/w16gui/poppad.rc b/pr/tests/w16gui/poppad.rc
index 4f690a73..efdd5dc3 100644
--- a/pr/tests/w16gui/poppad.rc
+++ b/pr/tests/w16gui/poppad.rc
@@ -1,4 +1,20 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
/*---------------------------
POPPAD.RC resource script
diff --git a/pr/tests/yield.c b/pr/tests/yield.c
index 7adfca13..7f9d4548 100644
--- a/pr/tests/yield.c
+++ b/pr/tests/yield.c
@@ -18,8 +18,7 @@
#include <stdio.h>
#include "prthread.h"
-#include "private/pprmisc.h"
-#include <windows.h>
+#include "prinit.h"
#define THREADS 10
diff --git a/tools/httpget.c b/tools/httpget.c
index aa824993..5c5602b4 100644
--- a/tools/httpget.c
+++ b/tools/httpget.c
@@ -349,8 +349,8 @@ int main(int argc, char **argv)
exit(1);
}
- addr.inet.family = AF_INET;
- addr.inet.port = htons((short) atoi(port));
+ addr.inet.family = PR_AF_INET;
+ addr.inet.port = PR_htons((short) atoi(port));
addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]);
socket = PR_NewTCPSocket();