diff --git a/nsprpub/lib/ds/plevent.c b/nsprpub/lib/ds/plevent.c index 46c1c609bd5..d164955ef8d 100644 --- a/nsprpub/lib/ds/plevent.c +++ b/nsprpub/lib/ds/plevent.c @@ -15,9 +15,6 @@ * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ -#if defined(WIN16) -#include -#endif #include "plevent.h" #include "prmem.h" #include "prcmon.h" diff --git a/nsprpub/lib/ds/plevent.h b/nsprpub/lib/ds/plevent.h index d8361144894..81c7340e10b 100644 --- a/nsprpub/lib/ds/plevent.h +++ b/nsprpub/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 +#elif defined(WIN16) +#include +#endif + PR_BEGIN_EXTERN_C /* Typedefs */ diff --git a/nsprpub/lib/msgc/src/prmsgc.c b/nsprpub/lib/msgc/src/prmsgc.c index f01d2cd1812..650ebd6dbe6 100644 --- a/nsprpub/lib/msgc/src/prmsgc.c +++ b/nsprpub/lib/msgc/src/prmsgc.c @@ -21,6 +21,11 @@ #include #include +#ifdef WIN32 +#include +#include +#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/nsprpub/lib/prstreams/prstrms.cpp b/nsprpub/lib/prstreams/prstrms.cpp index 8dd71fc6df6..473b70bf829 100644 --- a/nsprpub/lib/prstreams/prstrms.cpp +++ b/nsprpub/lib/prstreams/prstrms.cpp @@ -21,9 +21,7 @@ */ #include "prstrms.h" -#ifdef SVR4 #include // memmove -#endif // // Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C. diff --git a/nsprpub/pr/include/md/_aix.h b/nsprpub/pr/include/md/_aix.h index e1a1643a66e..7ea19b7ff65 100644 --- a/nsprpub/pr/include/md/_aix.h +++ b/nsprpub/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 +#define _PR_HAVE_SOCKADDR_LEN -#undef _PR_HAVE_ATOMIC_OPS +#define _MD_GET_INTERVAL _PR_UNIX_GetInterval +#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond -#define _MD_GET_INTERVAL _PR_UNIX_GetInterval -#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond +/* The atomic operations */ +#include +#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/nsprpub/pr/include/md/_freebsd.h b/nsprpub/pr/include/md/_freebsd.h index 1d8a52401b6..916c11c2490 100644 --- a/nsprpub/pr/include/md/_freebsd.h +++ b/nsprpub/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/nsprpub/pr/include/md/_irix.cfg b/nsprpub/pr/include/md/_irix.cfg index b9873fcb380..e69de29bb2d 100644 --- a/nsprpub/pr/include/md/_irix.cfg +++ b/nsprpub/pr/include/md/_irix.cfg @@ -1,126 +0,0 @@ -/* -*- 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. - */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef _SGI_MP_SOURCE -#define _SGI_MP_SOURCE -#endif - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef IRIX -#define IRIX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define HAVE_LONG_LONG -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff --git a/nsprpub/pr/include/md/_irix.h b/nsprpub/pr/include/md/_irix.h index 405dd03ce11..694b809bef6 100644 --- a/nsprpub/pr/include/md/_irix.h +++ b/nsprpub/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/nsprpub/pr/include/md/_linux.h b/nsprpub/pr/include/md/_linux.h index 03b526e3224..a7ac63261b3 100644 --- a/nsprpub/pr/include/md/_linux.h +++ b/nsprpub/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 +extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds, + int timeout); +#define _MD_POLL __syscall_poll +#endif /* For writev() */ #include diff --git a/nsprpub/pr/include/md/_macos.h b/nsprpub/pr/include/md/_macos.h index b38b53741a2..dae22d0aa20 100644 --- a/nsprpub/pr/include/md/_macos.h +++ b/nsprpub/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/nsprpub/pr/include/md/_ncr.cfg b/nsprpub/pr/include/md/_ncr.cfg index 23757a60336..337b933d657 100644 --- a/nsprpub/pr/include/md/_ncr.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_os2.cfg b/nsprpub/pr/include/md/_os2.cfg index 989d8d880ae..1271e0f1c82 100644 --- a/nsprpub/pr/include/md/_os2.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_os2.h b/nsprpub/pr/include/md/_os2.h index aa440567669..acdf4c64334 100644 --- a/nsprpub/pr/include/md/_os2.h +++ b/nsprpub/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 +#undef TID /* and restore */ #include #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/nsprpub/pr/include/md/_os2_errors.h b/nsprpub/pr/include/md/_os2_errors.h index 34fa4c59d26..17b331295ee 100644 --- a/nsprpub/pr/include/md/_os2_errors.h +++ b/nsprpub/pr/include/md/_os2_errors.h @@ -20,7 +20,9 @@ #define nspr_os2_errors_h___ #include "md/_os2.h" -#include +#ifndef assert + #include +#endif #include PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err); diff --git a/nsprpub/pr/include/md/_osf1.cfg b/nsprpub/pr/include/md/_osf1.cfg index 83208941ae1..16bc9ac94aa 100644 --- a/nsprpub/pr/include/md/_osf1.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_pcos.h b/nsprpub/pr/include/md/_pcos.h index c430972c212..6e325b36e70 100644 --- a/nsprpub/pr/include/md/_pcos.h +++ b/nsprpub/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/nsprpub/pr/include/md/_pth.h b/nsprpub/pr/include/md/_pth.h index fba4726c739..bf0be7f72f8 100644 --- a/nsprpub/pr/include/md/_pth.h +++ b/nsprpub/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 #define PTHREAD_YIELD() \ diff --git a/nsprpub/pr/include/md/_reliantunix.cfg b/nsprpub/pr/include/md/_reliantunix.cfg index d5a71fe105d..634acfe32e0 100644 --- a/nsprpub/pr/include/md/_reliantunix.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_scoos.cfg b/nsprpub/pr/include/md/_scoos.cfg index 4db48681493..3f414650dfa 100644 --- a/nsprpub/pr/include/md/_scoos.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_unix_errors.h b/nsprpub/pr/include/md/_unix_errors.h index ce1ef0040ba..b022462cc61 100644 --- a/nsprpub/pr/include/md/_unix_errors.h +++ b/nsprpub/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/nsprpub/pr/include/md/_unixos.h b/nsprpub/pr/include/md/_unixos.h index e6d1a4f2338..b82f92654fd 100644 --- a/nsprpub/pr/include/md/_unixos.h +++ b/nsprpub/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/nsprpub/pr/include/md/_unixware.cfg b/nsprpub/pr/include/md/_unixware.cfg index a44724154d9..d8261908cc7 100644 --- a/nsprpub/pr/include/md/_unixware.cfg +++ b/nsprpub/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/nsprpub/pr/include/md/_win32_errors.h b/nsprpub/pr/include/md/_win32_errors.h index 4a3170bbb27..005caee673f 100644 --- a/nsprpub/pr/include/md/_win32_errors.h +++ b/nsprpub/pr/include/md/_win32_errors.h @@ -24,109 +24,109 @@ #include -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/nsprpub/pr/include/md/_win95.h b/nsprpub/pr/include/md/_win95.h index 3609046c9b6..7b4129237e3 100644 --- a/nsprpub/pr/include/md/_win95.h +++ b/nsprpub/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/nsprpub/pr/include/md/_winnt.h b/nsprpub/pr/include/md/_winnt.h index a754c08777e..ba2a6a10f65 100644 --- a/nsprpub/pr/include/md/_winnt.h +++ b/nsprpub/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/nsprpub/pr/include/obsolete/protypes.h b/nsprpub/pr/include/obsolete/protypes.h index 3c45ed4f25d..676d848bf81 100644 --- a/nsprpub/pr/include/obsolete/protypes.h +++ b/nsprpub/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/nsprpub/pr/include/prbit.h b/nsprpub/pr/include/prbit.h index 17965aedf01..5785338424b 100644 --- a/nsprpub/pr/include/prbit.h +++ b/nsprpub/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/nsprpub/pr/include/prdtoa.h b/nsprpub/pr/include/prdtoa.h index d362a1e4ff7..fec81a59904 100644 --- a/nsprpub/pr/include/prdtoa.h +++ b/nsprpub/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/nsprpub/pr/include/prinet.h b/nsprpub/pr/include/prinet.h index 3e40616e36c..149b943ea5d 100644 --- a/nsprpub/pr/include/prinet.h +++ b/nsprpub/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 +/* Do not include any system header files. */ #elif defined(WIN16) diff --git a/nsprpub/pr/include/prio.h b/nsprpub/pr/include/prio.h index 411d8e1a864..1cc6719e430 100644 --- a/nsprpub/pr/include/prio.h +++ b/nsprpub/pr/include/prio.h @@ -82,6 +82,36 @@ typedef enum PRTransmitFileFlags { * is transmitted. */ } 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 @@ -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,14 +144,43 @@ 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 #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/nsprpub/pr/include/private/pprio.h b/nsprpub/pr/include/private/pprio.h index 8cd92a29f43..c9d6eec1590 100644 --- a/nsprpub/pr/include/private/pprio.h +++ b/nsprpub/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. @@ -58,6 +59,24 @@ PR_EXTERN(PRFileDesc*) PR_ImportFile(PRInt32 osfd); 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. */ diff --git a/nsprpub/pr/include/private/primpl.h b/nsprpub/pr/include/private/primpl.h index 5cfbf3a262b..f93ed80f293 100644 --- a/nsprpub/pr/include/private/primpl.h +++ b/nsprpub/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 #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/nsprpub/pr/include/prmwait.h b/nsprpub/pr/include/prmwait.h index 008e6a80377..c63398bd66f 100644 --- a/nsprpub/pr/include/prmwait.h +++ b/nsprpub/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/nsprpub/pr/include/prtypes.h b/nsprpub/pr/include/prtypes.h index dda8663bb72..a4a3b69593d 100644 --- a/nsprpub/pr/include/prtypes.h +++ b/nsprpub/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 /* 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/nsprpub/pr/include/prwin16.h b/nsprpub/pr/include/prwin16.h index f87de046310..2420b235346 100644 --- a/nsprpub/pr/include/prwin16.h +++ b/nsprpub/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 PR_BEGIN_EXTERN_C diff --git a/nsprpub/pr/src/io/pprmwait.h b/nsprpub/pr/src/io/pprmwait.h index 55b258e00dd..e69de29bb2d 100644 --- a/nsprpub/pr/src/io/pprmwait.h +++ b/nsprpub/pr/src/io/pprmwait.h @@ -1,77 +0,0 @@ -/* -*- 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. - */ - -#if defined(_PPRMWAIT_H) -#else -#define _PPRMWAIT_H - -#include "prlock.h" -#include "prcvar.h" -#include "prclist.h" -#include "prthread.h" - -#define _PR_HASH_OFFSET 75013 -#define MAX_POLLING_INTERVAL 100 -#define _PR_POLL_COUNT_FUDGE 64 -#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_ABORTED(_rv) \ - ((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) - -typedef enum {_prmw_success, _prmw_rehash, _prmw_error} _PR_HashStory; - -typedef struct _PRWaiterHash -{ - PRUint16 count; /* current number in hash table */ - PRUint16 length; /* current size of the hash table */ - PRRecvWait *recv_wait; /* hash table of receive wait objects */ -} _PRWaiterHash; - -typedef enum {_prmw_running, _prmw_stopping, _prmw_stopped} PRMWGroupState; - -struct PRWaitGroup -{ - PRCList group_link; /* all groups are linked to each other */ - PRCList io_ready; /* list of I/O requests that are ready */ - PRMWGroupState state; /* state of this group (so we can shut down) */ - - PRLock *ml; /* lock for synchronizing this wait group */ - PRCondVar *io_taken; /* calling threads notify when they take I/O */ - PRCondVar *io_complete; /* calling threads wait here for completions */ - PRCondVar *new_business; /* polling thread waits here more work */ - PRCondVar *mw_manage; /* used to manage group lists */ - PRThread* poller; /* thread that's actually doing the poll() */ - PRUint16 waiting_threads; /* number of threads waiting for recv */ - PRUint16 polling_count; /* number of elements in the polling list */ - PRPollDesc *polling_list; /* list poller builds for polling */ - PRIntervalTime last_poll; /* last time we polled */ - _PRWaiterHash *waiter; /* pointer to hash table of wait receive objects */ -}; - -typedef struct _PRGlobalState -{ - PRCList group_list; /* master of the group list */ - PRWaitGroup *group; /* the default (NULL) group */ -} _PRGlobalState; - -#endif /* defined(_PPRMWAIT_H) */ - -/* pprmwait.h */ diff --git a/nsprpub/pr/src/io/prfile.c b/nsprpub/pr/src/io/prfile.c index ab20b2a3f5b..95210eae184 100644 --- a/nsprpub/pr/src/io/prfile.c +++ b/nsprpub/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/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c index d0be59fcd7f..fc8f005fdf8 100644 --- a/nsprpub/pr/src/io/prio.c +++ b/nsprpub/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/nsprpub/pr/src/io/prlayer.c b/nsprpub/pr/src/io/prlayer.c index d70a935eda5..1ca1596281a 100644 --- a/nsprpub/pr/src/io/prlayer.c +++ b/nsprpub/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/nsprpub/pr/src/io/prmapopt.c b/nsprpub/pr/src/io/prmapopt.c index c9ed829a6ad..6bd4dddc1a7 100644 --- a/nsprpub/pr/src/io/prmapopt.c +++ b/nsprpub/pr/src/io/prmapopt.c @@ -40,106 +40,6 @@ #include /* 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/nsprpub/pr/src/io/prprf.c b/nsprpub/pr/src/io/prprf.c index d8dd9ec0727..2ce93d18ab0 100644 --- a/nsprpub/pr/src/io/prprf.c +++ b/nsprpub/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/nsprpub/pr/src/io/prscanf.c b/nsprpub/pr/src/io/prscanf.c index 4a23543fcca..96530bf6a66 100644 --- a/nsprpub/pr/src/io/prscanf.c +++ b/nsprpub/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/nsprpub/pr/src/io/prsocket.c b/nsprpub/pr/src/io/prsocket.c index f34cf267e8f..9c4be75c04d 100644 --- a/nsprpub/pr/src/io/prsocket.c +++ b/nsprpub/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 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; } @@ -1011,6 +1047,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) if (AF_INET != domain #if defined(_PR_INET6) && AF_INET6 != domain +#endif +#if defined(XP_UNIX) + && AF_UNIX != domain #endif ) { PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); @@ -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/nsprpub/pr/src/md/mac/macsockotpt.c b/nsprpub/pr/src/md/mac/macsockotpt.c index 4c74bb8d5d5..a227c0633ee 100644 --- a/nsprpub/pr/src/md/mac/macsockotpt.c +++ b/nsprpub/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/nsprpub/pr/src/md/os2/os2cv.c b/nsprpub/pr/src/md/os2/os2cv.c index 34264dd5c78..95cedff4052 100644 --- a/nsprpub/pr/src/md/os2/os2cv.c +++ b/nsprpub/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/nsprpub/pr/src/md/os2/os2gc.c b/nsprpub/pr/src/md/os2/os2gc.c index 00db7e15faa..625df4c9794 100644 --- a/nsprpub/pr/src/md/os2/os2gc.c +++ b/nsprpub/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/nsprpub/pr/src/md/os2/os2io.c b/nsprpub/pr/src/md/os2/os2io.c index b2e89d2762f..b08f2155aeb 100644 --- a/nsprpub/pr/src/md/os2/os2io.c +++ b/nsprpub/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/nsprpub/pr/src/md/os2/os2misc.c b/nsprpub/pr/src/md/os2/os2misc.c index 00913013068..153d595c2e3 100644 --- a/nsprpub/pr/src/md/os2/os2misc.c +++ b/nsprpub/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/nsprpub/pr/src/md/os2/os2thred.c b/nsprpub/pr/src/md/os2/os2thred.c index e51b3eb3f2a..3be132f536f 100644 --- a/nsprpub/pr/src/md/os2/os2thred.c +++ b/nsprpub/pr/src/md/os2/os2thred.c @@ -19,7 +19,7 @@ #include "primpl.h" #include /* 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/nsprpub/pr/src/md/unix/aix.c b/nsprpub/pr/src/md/unix/aix.c index 8ae7e303638..544b2584cdc 100644 --- a/nsprpub/pr/src/md/unix/aix.c +++ b/nsprpub/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 #include #include #include @@ -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/nsprpub/pr/src/md/unix/freebsd.c b/nsprpub/pr/src/md/unix/freebsd.c index 2cedf308dac..05652483a42 100644 --- a/nsprpub/pr/src/md/unix/freebsd.c +++ b/nsprpub/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 - -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/nsprpub/pr/src/md/unix/irix.c b/nsprpub/pr/src/md/unix/irix.c index 58ebe9223e2..ca49378d3b1 100644 --- a/nsprpub/pr/src/md/unix/irix.c +++ b/nsprpub/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) { - 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); +#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; + + 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/nsprpub/pr/src/md/unix/linux.c b/nsprpub/pr/src/md/unix/linux.c index a653f47ba0b..7cea254201b 100644 --- a/nsprpub/pr/src/md/unix/linux.c +++ b/nsprpub/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 - -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/nsprpub/pr/src/md/unix/os_AIX.s b/nsprpub/pr/src/md/unix/os_AIX.s index 63ca4e78e8a..48a1f5b1d66 100644 --- a/nsprpub/pr/src/md/unix/os_AIX.s +++ b/nsprpub/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/nsprpub/pr/src/md/unix/os_BSD_386_2.s b/nsprpub/pr/src/md/unix/os_BSD_386_2.s index 971ac1b2825..a47c4a4ea42 100644 --- a/nsprpub/pr/src/md/unix/os_BSD_386_2.s +++ b/nsprpub/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/nsprpub/pr/src/md/unix/os_ReliantUNIX.s b/nsprpub/pr/src/md/unix/os_ReliantUNIX.s index 4ac8b0c16f9..86cb2f06ce3 100644 --- a/nsprpub/pr/src/md/unix/os_ReliantUNIX.s +++ b/nsprpub/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/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s b/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s index b98b820fd37..1391a9bc641 100644 --- a/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s +++ b/nsprpub/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/nsprpub/pr/src/md/unix/unix.c b/nsprpub/pr/src/md/unix/unix.c index 9c62e80d50c..880e8bba836 100644 --- a/nsprpub/pr/src/md/unix/unix.c +++ b/nsprpub/pr/src/md/unix/unix.c @@ -28,6 +28,10 @@ #include #include +#ifdef _PR_POLL_AVAILABLE +#include +#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 + +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/nsprpub/pr/src/md/unix/unix_errors.c b/nsprpub/pr/src/md/unix/unix_errors.c index 92d96c73a09..802125e3823 100644 --- a/nsprpub/pr/src/md/unix/unix_errors.c +++ b/nsprpub/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/nsprpub/pr/src/md/windows/ntio.c b/nsprpub/pr/src/md/windows/ntio.c index e9c5779cc40..c41b0ab3374 100644 --- a/nsprpub/pr/src/md/windows/ntio.c +++ b/nsprpub/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/nsprpub/pr/src/md/windows/ntmisc.c b/nsprpub/pr/src/md/windows/ntmisc.c index 729bce4dd60..bc2ea6af34a 100644 --- a/nsprpub/pr/src/md/windows/ntmisc.c +++ b/nsprpub/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/nsprpub/pr/src/md/windows/ntthread.c b/nsprpub/pr/src/md/windows/ntthread.c index 885a0953942..91257aaf2c6 100644 --- a/nsprpub/pr/src/md/windows/ntthread.c +++ b/nsprpub/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; - } + int nativePri; + BOOL rv; - if( ! SetThreadPriority( thread->handle, newPri ) ) { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: can't set thread priority\n")); + 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")); } -#endif - return; } diff --git a/nsprpub/pr/src/md/windows/w16null.c b/nsprpub/pr/src/md/windows/w16null.c index a32e83d6fef..bd5056978ee 100644 --- a/nsprpub/pr/src/md/windows/w16null.c +++ b/nsprpub/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/nsprpub/pr/src/md/windows/w95thred.c b/nsprpub/pr/src/md/windows/w95thred.c index 0b333b855e6..41da9922624 100644 --- a/nsprpub/pr/src/md/windows/w95thred.c +++ b/nsprpub/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/nsprpub/pr/src/md/windows/win32_errors.c b/nsprpub/pr/src/md/windows/win32_errors.c index df271678c5f..884d8ce136d 100644 --- a/nsprpub/pr/src/md/windows/win32_errors.c +++ b/nsprpub/pr/src/md/windows/win32_errors.c @@ -18,6 +18,7 @@ #include "prerror.h" #include +#include void _MD_win32_map_opendir_error(PRInt32 err) { diff --git a/nsprpub/pr/src/misc/pratom.c b/nsprpub/pr/src/misc/pratom.c index c7eccae0a51..78ba817356b 100644 --- a/nsprpub/pr/src/misc/pratom.c +++ b/nsprpub/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/nsprpub/pr/src/misc/prdtoa.c b/nsprpub/pr/src/misc/prdtoa.c index a925361735d..ef3d50a0157 100644 --- a/nsprpub/pr/src/misc/prdtoa.c +++ b/nsprpub/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/nsprpub/pr/src/misc/prinit.c b/nsprpub/pr/src/misc/prinit.c index 247aadb9ed8..31d14702acf 100644 --- a/nsprpub/pr/src/misc/prinit.c +++ b/nsprpub/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/nsprpub/pr/src/misc/prnetdb.c b/nsprpub/pr/src/misc/prnetdb.c index acb6b5e32ff..74bf7abad83 100644 --- a/nsprpub/pr/src/misc/prnetdb.c +++ b/nsprpub/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/nsprpub/pr/src/misc/prtime.c b/nsprpub/pr/src/misc/prtime.c index 6f92c8ef5b9..ce6e1516364 100644 --- a/nsprpub/pr/src/misc/prtime.c +++ b/nsprpub/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/nsprpub/pr/src/pthreads/ptio.c b/nsprpub/pr/src/pthreads/ptio.c index 171877e75fb..e898c73fe9e 100644 --- a/nsprpub/pr/src/pthreads/ptio.c +++ b/nsprpub/pr/src/pthreads/ptio.c @@ -24,19 +24,10 @@ #if defined(_PR_PTHREADS) +#include #include /* for memset() */ #include #include - -/* - * 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 - #include #include #include @@ -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 #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_ASSERT(NULL != pt_tq.head); - 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); - - /* Okay. We're history */ - if (pt_tq.exitFlag) break; /* * 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; @@ -478,6 +615,23 @@ static void ContinuationThread(void *arg) pt_debug.pollingListMax = pollingListNeeded; #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 @@ -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. - */ + 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); - 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; - } + /* + * 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 */ } - if (NULL != pollingList) PR_DELETE(pollingList); -} /* ContinuationThread */ + +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 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 - { - op->result.code = -1; - op->syserrno = EINTR; - } + /* + ** 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->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. + */ - PR_Unlock(pt_tq.ml); /* we provide the locking */ - rc = pthread_cond_destroy(&op->complete.cv); PR_ASSERT(0 == rc); + } + } while (pt_continuation_done != op->status); + + + PR_Unlock(pt_tq.ml); /* we provided the locking */ - /* 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 */ 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) + { + polling_flags = (bottom->methods->poll)( + bottom, polling_flags, &pds[index].out_flags); + + 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 { /* 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; - if (_PR_FILEDESC_OPEN == bottom->secret->state) - pds[index].out_flags = 0; /* init the result */ - else - { - ready += 1; /* this will cause an abrupt return */ - pds[index].out_flags = POLLNVAL; /* bogii */ } } 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/nsprpub/pr/src/pthreads/ptsynch.c b/nsprpub/pr/src/pthreads/ptsynch.c index 8906cda3ea3..f3fa4711233 100644 --- a/nsprpub/pr/src/pthreads/ptsynch.c +++ b/nsprpub/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(¬ified->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(¬ified->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/nsprpub/pr/src/pthreads/ptthread.c b/nsprpub/pr/src/pthreads/ptthread.c index 784ffb2918d..d555c9fd945 100644 --- a/nsprpub/pr/src/pthreads/ptthread.c +++ b/nsprpub/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/nsprpub/pr/src/threads/combined/prucv.c b/nsprpub/pr/src/threads/combined/prucv.c index 08962d9f957..bf2bd551fce 100644 --- a/nsprpub/pr/src/threads/combined/prucv.c +++ b/nsprpub/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/nsprpub/pr/src/threads/combined/prulock.c b/nsprpub/pr/src/threads/combined/prulock.c index 0ec89fc9198..2ac56c57c4e 100644 --- a/nsprpub/pr/src/threads/combined/prulock.c +++ b/nsprpub/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/nsprpub/pr/src/threads/combined/pruthr.c b/nsprpub/pr/src/threads/combined/pruthr.c index 5a2174c63b3..2a3c38d677d 100644 --- a/nsprpub/pr/src/threads/combined/pruthr.c +++ b/nsprpub/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/nsprpub/pr/src/threads/prcthr.c b/nsprpub/pr/src/threads/prcthr.c index cf87e22b11e..6b3c80c776d 100644 --- a/nsprpub/pr/src/threads/prcthr.c +++ b/nsprpub/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/nsprpub/pr/src/threads/prdump.c b/nsprpub/pr/src/threads/prdump.c index 471a0dfe0bd..de8939c3e37 100644 --- a/nsprpub/pr/src/threads/prdump.c +++ b/nsprpub/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/nsprpub/pr/tests/accept.c b/nsprpub/pr/tests/accept.c index 226ae24df97..79ab811f3ec 100644 --- a/nsprpub/pr/tests/accept.c +++ b/nsprpub/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/nsprpub/pr/tests/alarm.c b/nsprpub/pr/tests/alarm.c index 94b921c143f..730e9de847d 100644 --- a/nsprpub/pr/tests/alarm.c +++ b/nsprpub/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/nsprpub/pr/tests/atomic.c b/nsprpub/pr/tests/atomic.c index 784fd2749aa..d5e334d5f05 100644 --- a/nsprpub/pr/tests/atomic.c +++ b/nsprpub/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/nsprpub/pr/tests/attach.c b/nsprpub/pr/tests/attach.c index 53598bd369d..3fa38d499c9 100644 --- a/nsprpub/pr/tests/attach.c +++ b/nsprpub/pr/tests/attach.c @@ -48,16 +48,9 @@ #include #ifdef WIN32 -#include "process.h" +#include +#include #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 #include "md/_pth.h" #elif defined(IRIX) diff --git a/nsprpub/pr/tests/cltsrv.c b/nsprpub/pr/tests/cltsrv.c index b9da03c2987..346ff2f9de1 100644 --- a/nsprpub/pr/tests/cltsrv.c +++ b/nsprpub/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/nsprpub/pr/tests/intrupt.c b/nsprpub/pr/tests/intrupt.c index 7cd9a428e71..d8d1de537ec 100644 --- a/nsprpub/pr/tests/intrupt.c +++ b/nsprpub/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/nsprpub/pr/tests/io_timeout.c b/nsprpub/pr/tests/io_timeout.c index 74914efedaf..2e1e46f2e98 100644 --- a/nsprpub/pr/tests/io_timeout.c +++ b/nsprpub/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/nsprpub/pr/tests/ipv6.c b/nsprpub/pr/tests/ipv6.c index 3eb5b841a7d..63ddfbf63cb 100644 --- a/nsprpub/pr/tests/ipv6.c +++ b/nsprpub/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/nsprpub/pr/tests/layer.c b/nsprpub/pr/tests/layer.c index 83aea2d95aa..e6be944fe94 100644 --- a/nsprpub/pr/tests/layer.c +++ b/nsprpub/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/nsprpub/pr/tests/many_cv.c b/nsprpub/pr/tests/many_cv.c index 75c898e7b4b..ae973655a8b 100644 --- a/nsprpub/pr/tests/many_cv.c +++ b/nsprpub/pr/tests/many_cv.c @@ -24,10 +24,18 @@ #include "prlog.h" #include "prmem.h" +#include "primpl.h" + #include "plgetopt.h" #include +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/nsprpub/pr/tests/nonblock.c b/nsprpub/pr/tests/nonblock.c index 24e6db732fd..c15807b7732 100644 --- a/nsprpub/pr/tests/nonblock.c +++ b/nsprpub/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/nsprpub/pr/tests/poll_nm.c b/nsprpub/pr/tests/poll_nm.c index f092be6a18c..a8995b3b112 100644 --- a/nsprpub/pr/tests/poll_nm.c +++ b/nsprpub/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/nsprpub/pr/tests/poll_to.c b/nsprpub/pr/tests/poll_to.c index 767c41da167..e617efd17a1 100644 --- a/nsprpub/pr/tests/poll_to.c +++ b/nsprpub/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/nsprpub/pr/tests/priotest.c b/nsprpub/pr/tests/priotest.c index 5c53daaefd8..cdc76953a31 100644 --- a/nsprpub/pr/tests/priotest.c +++ b/nsprpub/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 #include -#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/nsprpub/pr/tests/ranfile.c b/nsprpub/pr/tests/ranfile.c index 6869f3e4d1d..1ee6ca2015f 100644 --- a/nsprpub/pr/tests/ranfile.c +++ b/nsprpub/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/nsprpub/pr/tests/sel_spd.c b/nsprpub/pr/tests/sel_spd.c index a0e76a23147..f4ce1483c16 100644 --- a/nsprpub/pr/tests/sel_spd.c +++ b/nsprpub/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/nsprpub/pr/tests/selct_nm.c b/nsprpub/pr/tests/selct_nm.c index b051b132eed..c8bbe30ea0a 100644 --- a/nsprpub/pr/tests/selct_nm.c +++ b/nsprpub/pr/tests/selct_nm.c @@ -51,6 +51,7 @@ #include #include #include + 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/nsprpub/pr/tests/selct_to.c b/nsprpub/pr/tests/selct_to.c index d538acc0d17..0b13a81493c 100644 --- a/nsprpub/pr/tests/selct_to.c +++ b/nsprpub/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/nsprpub/pr/tests/servr_kk.c b/nsprpub/pr/tests/servr_kk.c index dac96e4172e..1efc7c61489 100644 --- a/nsprpub/pr/tests/servr_kk.c +++ b/nsprpub/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/nsprpub/pr/tests/servr_ku.c b/nsprpub/pr/tests/servr_ku.c index edf55bbf62a..e394ec4fc49 100644 --- a/nsprpub/pr/tests/servr_ku.c +++ b/nsprpub/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/nsprpub/pr/tests/servr_uk.c b/nsprpub/pr/tests/servr_uk.c index c71a49bafe0..c462a56fad0 100644 --- a/nsprpub/pr/tests/servr_uk.c +++ b/nsprpub/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/nsprpub/pr/tests/servr_uu.c b/nsprpub/pr/tests/servr_uu.c index d5dbe679597..ffa36a23736 100644 --- a/nsprpub/pr/tests/servr_uu.c +++ b/nsprpub/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/nsprpub/pr/tests/socket.c b/nsprpub/pr/tests/socket.c index ccf04e8a615..33ce32bbb0a 100644 --- a/nsprpub/pr/tests/socket.c +++ b/nsprpub/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/nsprpub/pr/tests/suspend.c b/nsprpub/pr/tests/suspend.c index a09262fda57..e44dc97bb02 100644 --- a/nsprpub/pr/tests/suspend.c +++ b/nsprpub/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; + 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; + 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 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/nsprpub/pr/tests/testfile.c b/nsprpub/pr/tests/testfile.c index c9173be5038..d492a0ff2c6 100644 --- a/nsprpub/pr/tests/testfile.c +++ b/nsprpub/pr/tests/testfile.c @@ -22,6 +22,9 @@ #include #include #include +#ifdef WIN32 +#include +#endif static int _debug_on = 0; diff --git a/nsprpub/pr/tests/thruput.c b/nsprpub/pr/tests/thruput.c index 654a6baca8e..23843e195e5 100644 --- a/nsprpub/pr/tests/thruput.c +++ b/nsprpub/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/nsprpub/pr/tests/tmocon.c b/nsprpub/pr/tests/tmocon.c index f4721914947..018c98b66f3 100644 --- a/nsprpub/pr/tests/tmocon.c +++ b/nsprpub/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/nsprpub/pr/tests/udpsrv.c b/nsprpub/pr/tests/udpsrv.c index e3264a916fa..4e9292d1b2a 100644 --- a/nsprpub/pr/tests/udpsrv.c +++ b/nsprpub/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/nsprpub/pr/tests/w16gui/poppad.rc b/nsprpub/pr/tests/w16gui/poppad.rc index 4f690a73e36..efdd5dc327d 100644 --- a/nsprpub/pr/tests/w16gui/poppad.rc +++ b/nsprpub/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/nsprpub/pr/tests/yield.c b/nsprpub/pr/tests/yield.c index 7adfca13a51..7f9d4548720 100644 --- a/nsprpub/pr/tests/yield.c +++ b/nsprpub/pr/tests/yield.c @@ -18,8 +18,7 @@ #include #include "prthread.h" -#include "private/pprmisc.h" -#include +#include "prinit.h" #define THREADS 10 diff --git a/nsprpub/tools/httpget.c b/nsprpub/tools/httpget.c index aa824993ff6..5c5602b4cc2 100644 --- a/nsprpub/tools/httpget.c +++ b/nsprpub/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();