Merged NSPRPUB_19980421_BRANCH to the main trunk.
This commit is contained in:
Родитель
e6dc748005
Коммит
74f75ec4ba
|
@ -15,9 +15,6 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#if defined(WIN16)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "plevent.h"
|
||||
#include "prmem.h"
|
||||
#include "prcmon.h"
|
||||
|
|
|
@ -170,6 +170,13 @@ and to ensure that no more events will be delivered for that owner.
|
|||
#include "prthread.h"
|
||||
#include "prmon.h"
|
||||
|
||||
/* For HWND */
|
||||
#ifdef _WIN32
|
||||
#include <windef.h>
|
||||
#elif defined(WIN16)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/* Typedefs */
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#endif
|
||||
|
||||
#include "prclist.h"
|
||||
#include "prbit.h"
|
||||
|
||||
|
@ -2365,7 +2370,7 @@ PR_TraceRoot()
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(DEBUG) && defined(_WIN32)
|
||||
#if defined(DEBUG) && defined(WIN32)
|
||||
static void DumpApplicationHeap(FILE *out, HANDLE heap)
|
||||
{
|
||||
PROCESS_HEAP_ENTRY entry;
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "prstrms.h"
|
||||
#ifdef SVR4
|
||||
#include <string.h> // memmove
|
||||
#endif
|
||||
|
||||
//
|
||||
// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.
|
||||
|
|
|
@ -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 <sys/atomic_op.h>
|
||||
#define _PR_HAVE_ATOMIC_OPS
|
||||
#define _MD_INIT_ATOMIC()
|
||||
#define _MD_ATOMIC_INCREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1)
|
||||
#define _MD_ATOMIC_DECREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1)
|
||||
#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval)
|
||||
|
||||
#define USE_SETJMP
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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___ */
|
|
@ -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 {
|
||||
|
|
|
@ -56,14 +56,10 @@
|
|||
#undef USE_DLFCN
|
||||
#endif
|
||||
|
||||
#if !defined(MACLINUX) && !defined(NEED_TIME_R)
|
||||
#if !defined(MKLINUX) && !defined(NEED_TIME_R)
|
||||
#define NEED_TIME_R
|
||||
#endif
|
||||
|
||||
#if defined(_PR_PTHREADS) && !(defined(__GLIBC__) && __GLIBC__ >= 2)
|
||||
#define _PR_NEED_FAKE_POLL
|
||||
#endif
|
||||
|
||||
#define USE_SETJMP
|
||||
|
||||
#ifdef _PR_PTHREADS
|
||||
|
@ -250,40 +246,12 @@ extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
|
|||
*/
|
||||
#define _MD_SELECT __select
|
||||
|
||||
#if defined(_PR_NEED_FAKE_POLL)
|
||||
|
||||
/*
|
||||
* XXX: Linux doesn't have poll(), but our pthreads code calls poll().
|
||||
* As a temporary measure, I implemented a fake poll() using select().
|
||||
* Here are the struct and macro definitions copied from sys/poll.h
|
||||
* on Solaris 2.5.
|
||||
*/
|
||||
|
||||
struct pollfd {
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
|
||||
/* poll events */
|
||||
|
||||
#define POLLIN 0x0001 /* fd is readable */
|
||||
#define POLLPRI 0x0002 /* high priority info at fd */
|
||||
#define POLLOUT 0x0004 /* fd is writeable (won't block) */
|
||||
#define POLLRDNORM 0x0040 /* normal data is readable */
|
||||
#define POLLWRNORM POLLOUT
|
||||
#define POLLRDBAND 0x0080 /* out-of-band data is readable */
|
||||
#define POLLWRBAND 0x0100 /* out-of-band data is writeable */
|
||||
|
||||
#define POLLNORM POLLRDNORM
|
||||
|
||||
#define POLLERR 0x0008 /* fd has error condition */
|
||||
#define POLLHUP 0x0010 /* fd has been hung up on */
|
||||
#define POLLNVAL 0x0020 /* invalid pollfd entry */
|
||||
|
||||
extern int poll(struct pollfd *, unsigned long, int);
|
||||
|
||||
#endif /* _PR_NEED_FAKE_POLL */
|
||||
#ifdef _PR_POLL_AVAILABLE
|
||||
#include <poll.h>
|
||||
extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
|
||||
int timeout);
|
||||
#define _MD_POLL __syscall_poll
|
||||
#endif
|
||||
|
||||
/* For writev() */
|
||||
#include <sys/uio.h>
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
#define INCL_DOSERRORS
|
||||
#define INCL_WIN
|
||||
#define INCL_WPS
|
||||
#define TID OS2TID /* global rename in OS2 H's! */
|
||||
#include <os2.h>
|
||||
#undef TID /* and restore */
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "prio.h"
|
||||
|
@ -42,7 +44,11 @@
|
|||
#undef HAVE_THREAD_AFFINITY
|
||||
#define HAVE_SOCKET_REUSEADDR
|
||||
#define HAVE_SOCKET_KEEPALIVE
|
||||
#define _PR_HAVE_ATOMIC_OPS
|
||||
|
||||
/*********************************************
|
||||
/* We don't have atomic ops on OS/2 natively */
|
||||
/* #define _PR_HAVE_ATOMIC_OPS */
|
||||
/*********************************************/
|
||||
|
||||
#define HANDLE unsigned long
|
||||
#define HINSTANCE HMODULE
|
||||
|
@ -59,6 +65,7 @@ typedef void (*FiberFunc)(void *);
|
|||
typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS];
|
||||
#define GC_VMBASE 0x40000000
|
||||
#define GC_VMLIMIT 0x00FFFFFF
|
||||
typedef int (*FARPROC)();
|
||||
|
||||
#define _MD_MAGIC_THREAD 0x22222222
|
||||
#define _MD_MAGIC_THREADSTACK 0x33333333
|
||||
|
@ -66,6 +73,8 @@ typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS];
|
|||
#define _MD_MAGIC_DIR 0x55555555
|
||||
#define _MD_MAGIC_CV 0x66666666
|
||||
|
||||
#define CALLBACK
|
||||
|
||||
typedef struct _MDSemaphore
|
||||
{
|
||||
HEV sem;
|
||||
|
@ -82,7 +91,7 @@ struct _MDThread {
|
|||
PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the
|
||||
* wait queue of some cond var.
|
||||
* PR_FALSE otherwise. */
|
||||
TID handle; /* OS/2 thread handle */
|
||||
OS2TID handle; /* OS/2 thread handle */
|
||||
void *sp; /* only valid when suspended */
|
||||
PRUint32 magic; /* for debugging */
|
||||
PR_CONTEXT_TYPE gcContext; /* Thread context for GC */
|
||||
|
@ -133,7 +142,7 @@ struct _MDNotified {
|
|||
};
|
||||
|
||||
struct _MDLock {
|
||||
CRITICAL_SECTION mutex; /* this is recursive on NT */
|
||||
HMTX mutex; /* this is recursive on NT */
|
||||
|
||||
/*
|
||||
* When notifying cvars, there is no point in actually
|
||||
|
@ -189,6 +198,10 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
|
|||
#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE
|
||||
|
||||
/* --- Socket IO stuff --- */
|
||||
|
||||
/* The ones that don't map directly may need to be re-visited... */
|
||||
#define EPIPE EBADF
|
||||
#define EIO ECONNREFUSED
|
||||
#define _MD_EACCES EACCES
|
||||
#define _MD_EADDRINUSE EADDRINUSE
|
||||
#define _MD_EADDRNOTAVAIL EADDRNOTAVAIL
|
||||
|
@ -230,14 +243,10 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
|
|||
#define _MD_SELECT select
|
||||
#define _MD_FSYNC _PR_MD_FSYNC
|
||||
|
||||
long _System InterlockedIncrement(PLONG);
|
||||
long _System InterlockedDecrement(PLONG);
|
||||
long _System InterlockedExchange(PLONG, LONG);
|
||||
|
||||
#define _MD_INIT_ATOMIC()
|
||||
#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x)
|
||||
#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x)
|
||||
#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
|
||||
#define _MD_INIT_ATOMIC _PR_MD_INIT_ATOMIC
|
||||
#define _MD_ATOMIC_INCREMENT(x) _PR_MD_ATOMIC_INCREMENT(x)
|
||||
#define _MD_ATOMIC_DECREMENT(x) _PR_MD_ATOMIC_DECREMENT(x)
|
||||
#define _MD_ATOMIC_SET(x,y) _PR_MD_ATOMIC_SET(x, y)
|
||||
|
||||
#define _MD_INIT_IO _PR_MD_INIT_IO
|
||||
#define _MD_TRANSMITFILE _PR_MD_TRANSMITFILE
|
||||
|
@ -304,10 +313,10 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
|
|||
#define _PR_LOCK _MD_LOCK
|
||||
#define _PR_UNLOCK _MD_UNLOCK
|
||||
|
||||
#define _MD_NEW_LOCK(lock) (InitializeCriticalSection(&((lock)->mutex)),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
|
||||
#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex))
|
||||
#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex))
|
||||
#define _MD_TEST_AND_LOCK(lock) (EnterCriticalSection(&((lock)->mutex)),PR_SUCCESS)
|
||||
#define _MD_NEW_LOCK(lock) (DosCreateMutexSem(0, &((lock)->mutex), 0, 0),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
|
||||
#define _MD_FREE_LOCK(lock) DosCloseMutexSem(((lock)->mutex))
|
||||
#define _MD_LOCK(lock) DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT)
|
||||
#define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT),PR_SUCCESS)
|
||||
#define _MD_UNLOCK _PR_MD_UNLOCK
|
||||
|
||||
/* --- lock and cv waiting --- */
|
||||
|
@ -376,8 +385,8 @@ extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
|
|||
|
||||
typedef struct __NSPR_TLS
|
||||
{
|
||||
PRThread *_pr_thread_last_run;
|
||||
PRThread *_pr_currentThread;
|
||||
struct PRThread *_pr_thread_last_run;
|
||||
struct PRThread *_pr_currentThread;
|
||||
struct _PRCPU *_pr_currentCPU;
|
||||
} _NSPR_TLS;
|
||||
|
||||
|
@ -431,7 +440,10 @@ extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
|
|||
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
|
||||
|
||||
/* Some stuff for setting up thread contexts */
|
||||
typedef ULONG DWORD, *PDWORD;
|
||||
#undef DWORD
|
||||
#undef PDWORD
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned long *PDWORD;
|
||||
|
||||
/* The following definitions and two structures are new in OS/2 Warp 4.0.
|
||||
*/
|
||||
|
@ -472,7 +484,7 @@ typedef struct _CONTEXTRECORD {
|
|||
#pragma pack()
|
||||
#endif
|
||||
|
||||
extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
|
||||
extern APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
|
||||
|
||||
/*
|
||||
#define _pr_tid (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
|
||||
|
@ -484,5 +496,6 @@ extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
|
|||
* not emulating anything. Just mapping.
|
||||
*/
|
||||
#define FreeLibrary(x) DosFreeModule(x)
|
||||
#define OutputDebugString(str) ;
|
||||
|
||||
#endif /* nspr_os2_defs_h___ */
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#define nspr_os2_errors_h___
|
||||
|
||||
#include "md/_os2.h"
|
||||
#include <assert.h>
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#include <nerrno.h>
|
||||
|
||||
PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -194,10 +194,13 @@ PR_EXTERN(PRIntn) pt_hpux_privcheck(void);
|
|||
/* Needed for garbage collection -- Look at PR_Suspend/PR_Resume implementation */
|
||||
#if defined(OSF1)
|
||||
#define PTHREAD_YIELD() pthread_yield_np()
|
||||
#elif defined(HPUX10_30) || defined(HPUX11) || defined(AIX4_3)
|
||||
#elif defined(HPUX10_30) || defined(HPUX11)
|
||||
#define PTHREAD_YIELD() sched_yield()
|
||||
#elif (defined(AIX) && !defined(AIX4_3)) || defined(HPUX)
|
||||
#elif defined(HPUX)
|
||||
#define PTHREAD_YIELD() pthread_yield()
|
||||
#elif defined(AIX)
|
||||
extern int (*_PT_aix_yield_fcn)();
|
||||
#define PTHREAD_YIELD() (*_PT_aix_yield_fcn)()
|
||||
#elif defined(IRIX)
|
||||
#include <time.h>
|
||||
#define PTHREAD_YIELD() \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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___ */
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#define PR_ALIGN_OF_POINTER 4
|
||||
|
||||
#define _PR_USE_POLL
|
||||
#define _PR_POLL_AVAILABLE
|
||||
|
||||
#ifndef NO_NSPR_10_SUPPORT
|
||||
|
||||
|
|
|
@ -24,109 +24,109 @@
|
|||
#include <errno.h>
|
||||
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_opendir_error(PRInt32 err);
|
||||
extern void _MD_win32_map_opendir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_OPENDIR_ERROR _MD_win32_map_opendir_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_closedir_error(PRInt32 err);
|
||||
extern void _MD_win32_map_closedir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_win32_map_closedir_error
|
||||
|
||||
PR_EXTERN(void) _MD_unix_readdir_error(PRInt32 err);
|
||||
extern void _MD_unix_readdir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_delete_error(PRInt32 err);
|
||||
extern void _MD_win32_map_delete_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_DELETE_ERROR _MD_win32_map_delete_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_stat_error(PRInt32 err);
|
||||
extern void _MD_win32_map_stat_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_STAT_ERROR _MD_win32_map_stat_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_fstat_error(PRInt32 err);
|
||||
extern void _MD_win32_map_fstat_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_FSTAT_ERROR _MD_win32_map_fstat_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_rename_error(PRInt32 err);
|
||||
extern void _MD_win32_map_rename_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_RENAME_ERROR _MD_win32_map_rename_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_access_error(PRInt32 err);
|
||||
extern void _MD_win32_map_access_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_ACCESS_ERROR _MD_win32_map_access_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_mkdir_error(PRInt32 err);
|
||||
extern void _MD_win32_map_mkdir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_MKDIR_ERROR _MD_win32_map_mkdir_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_rmdir_error(PRInt32 err);
|
||||
extern void _MD_win32_map_rmdir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_RMDIR_ERROR _MD_win32_map_rmdir_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_read_error(PRInt32 err);
|
||||
extern void _MD_win32_map_read_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_READ_ERROR _MD_win32_map_read_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_transmitfile_error(PRInt32 err);
|
||||
extern void _MD_win32_map_transmitfile_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_win32_map_transmitfile_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_write_error(PRInt32 err);
|
||||
extern void _MD_win32_map_write_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_WRITE_ERROR _MD_win32_map_write_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_lseek_error(PRInt32 err);
|
||||
extern void _MD_win32_map_lseek_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_LSEEK_ERROR _MD_win32_map_lseek_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_fsync_error(PRInt32 err);
|
||||
extern void _MD_win32_map_fsync_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_FSYNC_ERROR _MD_win32_map_fsync_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_close_error(PRInt32 err);
|
||||
extern void _MD_win32_map_close_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_CLOSE_ERROR _MD_win32_map_close_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_socket_error(PRInt32 err);
|
||||
extern void _MD_win32_map_socket_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SOCKET_ERROR _MD_win32_map_socket_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_recv_error(PRInt32 err);
|
||||
extern void _MD_win32_map_recv_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_RECV_ERROR _MD_win32_map_recv_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_recvfrom_error(PRInt32 err);
|
||||
extern void _MD_win32_map_recvfrom_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_RECVFROM_ERROR _MD_win32_map_recvfrom_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_send_error(PRInt32 err);
|
||||
extern void _MD_win32_map_send_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SEND_ERROR _MD_win32_map_send_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_sendto_error(PRInt32 err);
|
||||
extern void _MD_win32_map_sendto_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SENDTO_ERROR _MD_win32_map_sendto_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_accept_error(PRInt32 err);
|
||||
extern void _MD_win32_map_accept_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_ACCEPT_ERROR _MD_win32_map_accept_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_acceptex_error(PRInt32 err);
|
||||
extern void _MD_win32_map_acceptex_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_win32_map_acceptex_error
|
||||
|
||||
PR_EXTERN(PRInt32) _MD_win32_map_connect_error(PRInt32 err);
|
||||
extern PRInt32 _MD_win32_map_connect_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_CONNECT_ERROR _MD_win32_map_connect_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_bind_error(PRInt32 err);
|
||||
extern void _MD_win32_map_bind_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_BIND_ERROR _MD_win32_map_bind_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_listen_error(PRInt32 err);
|
||||
extern void _MD_win32_map_listen_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_LISTEN_ERROR _MD_win32_map_listen_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_shutdown_error(PRInt32 err);
|
||||
extern void _MD_win32_map_shutdown_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_win32_map_shutdown_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_getsockname_error(PRInt32 err);
|
||||
extern void _MD_win32_map_getsockname_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_win32_map_getsockname_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_getpeername_error(PRInt32 err);
|
||||
extern void _MD_win32_map_getpeername_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_win32_map_getpeername_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_getsockopt_error(PRInt32 err);
|
||||
extern void _MD_win32_map_getsockopt_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_win32_map_getsockopt_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_setsockopt_error(PRInt32 err);
|
||||
extern void _MD_win32_map_setsockopt_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_win32_map_setsockopt_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_open_error(PRInt32 err);
|
||||
extern void _MD_win32_map_open_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_OPEN_ERROR _MD_win32_map_open_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_gethostname_error(PRInt32 err);
|
||||
extern void _MD_win32_map_gethostname_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_win32_map_gethostname_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_select_error(PRInt32 err);
|
||||
extern void _MD_win32_map_select_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SELECT_ERROR _MD_win32_map_select_error
|
||||
|
||||
PR_EXTERN(void) _MD_win32_map_lockf_error(int err);
|
||||
extern void _MD_win32_map_lockf_error(int err);
|
||||
#define _PR_MD_MAP_LOCKF_ERROR _MD_win32_map_lockf_error
|
||||
|
||||
#endif /* nspr_win32_errors_h___ */
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -74,13 +74,7 @@
|
|||
|
||||
#elif defined(WIN32)
|
||||
|
||||
/*
|
||||
* On Win NT, windows.h includes either winsock.h or winsock2.h,
|
||||
* depending on the value of the _WIN32_WINNT macro. One can't
|
||||
* include winsock2.h if winsock.h is already included. So we
|
||||
* include windows.h to stay neutral.
|
||||
*/
|
||||
#include <windows.h>
|
||||
/* Do not include any system header files. */
|
||||
|
||||
#elif defined(WIN16)
|
||||
|
||||
|
|
|
@ -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 <poll.h>
|
||||
#define PR_POLL_READ POLLIN
|
||||
|
@ -1529,7 +1584,7 @@ struct PRPollDesc {
|
|||
#define PR_POLL_ERR POLLERR /* only in out_flags */
|
||||
#define PR_POLL_NVAL POLLNVAL /* only in out_flags when fd is bad */
|
||||
|
||||
#else /* XP_UNIX, _PR_USE_POLL */
|
||||
#else /* XP_UNIX, _PR_POLL_AVAILABLE */
|
||||
|
||||
#define PR_POLL_READ 0x1
|
||||
#define PR_POLL_WRITE 0x2
|
||||
|
@ -1537,7 +1592,7 @@ struct PRPollDesc {
|
|||
#define PR_POLL_ERR 0x8 /* only in out_flags */
|
||||
#define PR_POLL_NVAL 0x10 /* only in out_flags when fd is bad */
|
||||
|
||||
#endif /* XP_UNIX, _PR_USE_POLL */
|
||||
#endif /* XP_UNIX, _PR_POLL_AVAILABLE */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -28,14 +28,6 @@
|
|||
*/
|
||||
|
||||
#if defined(_PR_PTHREADS)
|
||||
/*
|
||||
* XXX: On Linux 2.0.27 (installed on tioman.mcom.com), sched.h uses
|
||||
* this _P macro that seems to be undefined. I suspect that it is
|
||||
* a typo (should be __P).
|
||||
*/
|
||||
#if defined(LINUX)
|
||||
#define _P(x) __P(x)
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
@ -191,9 +183,14 @@ typedef struct PTDebug
|
|||
PRUintn continuationsServed;
|
||||
PRUintn recyclesNeeded;
|
||||
PRUintn quiescentIO;
|
||||
PRUintn locks_created, locks_destroyed;
|
||||
PRUintn locks_acquired, locks_released;
|
||||
PRUintn cvars_created, cvars_destroyed;
|
||||
PRUintn cvars_notified, delayed_cv_deletes;
|
||||
} PTDebug;
|
||||
|
||||
PR_EXTERN(PTDebug) PT_GetStats(void);
|
||||
PR_EXTERN(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
|
||||
|
||||
#endif /* defined(DEBUG) */
|
||||
|
||||
|
@ -524,7 +521,7 @@ extern _PRInterruptTable _pr_interruptTable[];
|
|||
#define _PR_MISSED_IO 0x2
|
||||
#define _PR_MISSED_CHILD 0x4
|
||||
|
||||
PR_EXTERN(void) _PR_IntsOn(_PRCPU *cpu);
|
||||
extern void _PR_IntsOn(_PRCPU *cpu);
|
||||
|
||||
PR_EXTERN(void) _PR_WakeupCPU(void);
|
||||
PR_EXTERN(void) _PR_PauseCPU(void);
|
||||
|
@ -536,7 +533,7 @@ PR_EXTERN(void) _PR_PauseCPU(void);
|
|||
#define _PR_LOCK_UNLOCK(_lock) \
|
||||
_PR_MD_UNLOCK(&(_lock)->ilock);
|
||||
|
||||
PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock);
|
||||
extern PRThread * _PR_AssignLock(PRLock *lock);
|
||||
|
||||
#define _PR_LOCK_PTR(_qp) \
|
||||
((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
|
||||
|
@ -548,9 +545,9 @@ PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock);
|
|||
#define _PR_CVAR_UNLOCK(_cvar) \
|
||||
_PR_MD_UNLOCK(&(_cvar)->ilock);
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_WaitCondVar(
|
||||
extern PRStatus _PR_WaitCondVar(
|
||||
PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
|
||||
PR_EXTERN(PRUint32) _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
|
||||
extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
|
||||
|
||||
PR_EXTERN(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
|
||||
|
||||
|
@ -689,20 +686,20 @@ extern PRLock *_pr_terminationCVLock;
|
|||
* code. *
|
||||
*************************************************************************/
|
||||
|
||||
PR_EXTERN(void) _PR_ClockInterrupt(void);
|
||||
extern void _PR_ClockInterrupt(void);
|
||||
|
||||
PR_EXTERN(void) _PR_Schedule(void);
|
||||
PR_EXTERN(void) _PR_SetThreadPriority(
|
||||
extern void _PR_Schedule(void);
|
||||
extern void _PR_SetThreadPriority(
|
||||
PRThread* thread, PRThreadPriority priority);
|
||||
PR_EXTERN(void) _PR_Unlock(PRLock *lock);
|
||||
|
||||
PR_EXTERN(void) _PR_SuspendThread(PRThread *t);
|
||||
PR_EXTERN(void) _PR_ResumeThread(PRThread *t);
|
||||
|
||||
PR_EXTERN(PRThreadStack *)_PR_NewStack(PRUint32 stackSize);
|
||||
PR_EXTERN(void) _PR_FreeStack(PRThreadStack *stack);
|
||||
PR_EXTERN(PRBool) NotifyThread (PRThread *thread, PRThread *me);
|
||||
PR_EXTERN(void) _PR_NotifyLockedThread (PRThread *thread);
|
||||
extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
|
||||
extern void _PR_FreeStack(PRThreadStack *stack);
|
||||
extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
|
||||
extern void _PR_NotifyLockedThread (PRThread *thread);
|
||||
|
||||
PR_EXTERN(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
|
||||
PR_EXTERN(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
|
||||
|
@ -718,8 +715,8 @@ PR_EXTERN(PRThread*) _PR_CreateThread(PRThreadType type,
|
|||
PRUint32 stackSize,
|
||||
PRUint32 flags);
|
||||
|
||||
PR_EXTERN(void) _PR_NativeDestroyThread(PRThread *thread);
|
||||
PR_EXTERN(void) _PR_UserDestroyThread(PRThread *thread);
|
||||
extern void _PR_NativeDestroyThread(PRThread *thread);
|
||||
extern void _PR_UserDestroyThread(PRThread *thread);
|
||||
|
||||
PR_EXTERN(PRThread*) _PRI_AttachThread(
|
||||
PRThreadType type, PRThreadPriority priority,
|
||||
|
@ -750,10 +747,10 @@ PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
|
|||
/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
|
||||
* awaken a thread which is waiting on a lock or cvar.
|
||||
*/
|
||||
PR_EXTERN(PRStatus) _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
|
||||
extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
|
||||
#define _PR_MD_WAIT _MD_WAIT
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_WAKEUP_WAITER(PRThread *);
|
||||
extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
|
||||
#define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
|
||||
|
||||
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
|
||||
|
@ -787,13 +784,13 @@ PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
|
|||
/*
|
||||
* Returns the number of threads awoken or 0 if a timeout occurred;
|
||||
*/
|
||||
PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
|
||||
extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
|
||||
#define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
|
||||
|
||||
extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
|
||||
#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
|
||||
|
||||
PR_EXTERN(void) _PR_MD_EXIT(PRIntn status);
|
||||
extern void _PR_MD_EXIT(PRIntn status);
|
||||
#define _PR_MD_EXIT _MD_EXIT
|
||||
|
||||
/* Locks related */
|
||||
|
@ -877,10 +874,10 @@ PR_EXTERN(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
|
|||
PR_EXTERN(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
|
||||
#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_INIT_THREAD(PRThread *thread);
|
||||
extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
|
||||
#define _PR_MD_INIT_THREAD _MD_INIT_THREAD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_EXIT_THREAD(PRThread *thread);
|
||||
extern void _PR_MD_EXIT_THREAD(PRThread *thread);
|
||||
#define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
|
||||
|
||||
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
|
||||
|
@ -888,16 +885,16 @@ PR_EXTERN(void) _PR_MD_EXIT_THREAD(PRThread *thread);
|
|||
PR_EXTERN(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
|
||||
#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_SUSPEND_THREAD(PRThread *thread);
|
||||
extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
|
||||
#define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_RESUME_THREAD(PRThread *thread);
|
||||
extern void _PR_MD_RESUME_THREAD(PRThread *thread);
|
||||
#define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_SUSPEND_CPU(_PRCPU *cpu);
|
||||
extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu);
|
||||
#define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
|
||||
|
||||
PR_EXTERN(void) _PR_MD_RESUME_CPU(_PRCPU *cpu);
|
||||
extern void _PR_MD_RESUME_CPU(_PRCPU *cpu);
|
||||
#define _PR_MD_RESUME_CPU _MD_RESUME_CPU
|
||||
|
||||
extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
|
||||
|
@ -918,24 +915,24 @@ PR_EXTERN(void) _PR_IRIX_CHILD_PROCESS(void);
|
|||
|
||||
#endif /* !_PR_LOCAL_THREADS_ONLY */
|
||||
|
||||
PR_EXTERN(void) _PR_MD_CLEAN_THREAD(PRThread *thread);
|
||||
extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
|
||||
#define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
|
||||
|
||||
#ifdef HAVE_CUSTOM_USER_THREADS
|
||||
PR_EXTERN(void) _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
|
||||
extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
|
||||
#define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
|
||||
|
||||
PR_EXTERN(PRThread*) _PR_MD_CREATE_USER_THREAD(
|
||||
extern PRThread* _PR_MD_CREATE_USER_THREAD(
|
||||
PRUint32 stacksize,
|
||||
void (*start)(void *),
|
||||
void *arg);
|
||||
#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
|
||||
#endif
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread);
|
||||
extern void _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread);
|
||||
#define _PR_MD_INIT_PRIMORDIAL_THREAD _MD_INIT_PRIMORDIAL_THREAD
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_CREATE_THREAD(
|
||||
extern PRStatus _PR_MD_CREATE_THREAD(
|
||||
PRThread *thread,
|
||||
void (*start) (void *),
|
||||
PRThreadPriority priority,
|
||||
|
@ -944,10 +941,10 @@ PR_EXTERN(PRStatus) _PR_MD_CREATE_THREAD(
|
|||
PRUint32 stackSize);
|
||||
#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_YIELD(void);
|
||||
extern void _PR_MD_YIELD(void);
|
||||
#define _PR_MD_YIELD _MD_YIELD
|
||||
|
||||
PR_EXTERN(void) _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
|
||||
extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
|
||||
#define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
|
||||
|
||||
PR_EXTERN(void) _PR_MD_SUSPENDALL(void);
|
||||
|
@ -956,14 +953,14 @@ PR_EXTERN(void) _PR_MD_SUSPENDALL(void);
|
|||
PR_EXTERN(void) _PR_MD_RESUMEALL(void);
|
||||
#define _PR_MD_RESUMEALL _MD_RESUMEALL
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INIT_CONTEXT(
|
||||
extern void _PR_MD_INIT_CONTEXT(
|
||||
PRThread *thread, char *top, void (*start) (void), PRBool *status);
|
||||
#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
|
||||
|
||||
PR_EXTERN(void) _PR_MD_SWITCH_CONTEXT(PRThread *thread);
|
||||
extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
|
||||
#define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
|
||||
|
||||
PR_EXTERN(void) _PR_MD_RESTORE_CONTEXT(PRThread *thread);
|
||||
extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
|
||||
#define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
|
||||
|
||||
/* Directory enumeration related */
|
||||
|
@ -1200,8 +1197,8 @@ PR_EXTERN(void) _PR_MD_INIT_LOCKS(void);
|
|||
|
||||
struct PRLock {
|
||||
#if defined(_PR_PTHREADS)
|
||||
pthread_mutex_t mutex; /* the underlying lock */
|
||||
_PT_Notified notified; /* array of conditions notified */
|
||||
pthread_mutex_t mutex; /* the underlying lock */
|
||||
_PT_Notified notified; /* array of conditions notified */
|
||||
pthread_t owner; /* current lock owner */
|
||||
#else /* defined(_PR_PTHREADS) */
|
||||
PRCList links; /* linkage for PRThread.lockList */
|
||||
|
@ -1213,12 +1210,13 @@ struct PRLock {
|
|||
#endif /* defined(_PR_PTHREADS) */
|
||||
};
|
||||
|
||||
PR_EXTERN(void) _PR_InitLocks(void);
|
||||
extern void _PR_InitLocks(void);
|
||||
|
||||
struct PRCondVar {
|
||||
PRLock *lock; /* associated lock that protects the condition */
|
||||
#if defined(_PR_PTHREADS)
|
||||
pthread_cond_t cv;
|
||||
pthread_cond_t cv; /* underlying pthreads condition */
|
||||
PRInt32 notify_pending; /* CV has destroy pending notification */
|
||||
#else /* defined(_PR_PTHREADS) */
|
||||
PRCList condQ; /* Condition variable wait Q */
|
||||
_MDLock ilock; /* Internal Lock to protect condQ */
|
||||
|
@ -1297,12 +1295,13 @@ struct PRThread {
|
|||
void *dumpArg; /* argument for the dump function */
|
||||
|
||||
#if defined(_PR_PTHREADS)
|
||||
pthread_t id; /* pthread identifier for the thread */
|
||||
pthread_t id; /* pthread identifier for the thread */
|
||||
PRBool okToDelete; /* ok to delete the PRThread struct? */
|
||||
PRCondVar *waiting; /* where the thread is waiting | NULL */
|
||||
void *sp; /* recorded sp for garbage collection */
|
||||
PRThread *next, *prev; /* simple linked list of all threads */
|
||||
PRUint32 suspend; /* used to store suspend and resume flags */
|
||||
PRCondVar *io_cv; /* a condition used to run i/o */
|
||||
PRCondVar *waiting; /* where the thread is waiting | NULL */
|
||||
void *sp; /* recorded sp for garbage collection */
|
||||
PRThread *next, *prev; /* simple linked list of all threads */
|
||||
PRUint32 suspend; /* used to store suspend and resume flags */
|
||||
#ifdef PT_NO_SIGTIMEDWAIT
|
||||
pthread_mutex_t suspendResumeMutex;
|
||||
pthread_cond_t suspendResumeCV;
|
||||
|
@ -1481,10 +1480,10 @@ extern PRBool _pr_ipv6_enabled; /* defined in prnetdb.c */
|
|||
*************************************************************************/
|
||||
|
||||
/* Initialization related */
|
||||
PR_EXTERN(void) _PR_MD_EARLY_INIT(void);
|
||||
extern void _PR_MD_EARLY_INIT(void);
|
||||
#define _PR_MD_EARLY_INIT _MD_EARLY_INIT
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INTERVAL_INIT(void);
|
||||
extern void _PR_MD_INTERVAL_INIT(void);
|
||||
#define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INIT_SEGS(void);
|
||||
|
@ -1516,24 +1515,24 @@ PR_EXTERN(PRTime) _PR_MD_NOW(void);
|
|||
#define _PR_MD_NOW _MD_NOW
|
||||
|
||||
/* Environment related */
|
||||
PR_EXTERN(char*) _PR_MD_GET_ENV(const char *name);
|
||||
extern char* _PR_MD_GET_ENV(const char *name);
|
||||
#define _PR_MD_GET_ENV _MD_GET_ENV
|
||||
|
||||
PR_EXTERN(PRIntn) _PR_MD_PUT_ENV(const char *name);
|
||||
extern PRIntn _PR_MD_PUT_ENV(const char *name);
|
||||
#define _PR_MD_PUT_ENV _MD_PUT_ENV
|
||||
|
||||
/* Atomic operations */
|
||||
|
||||
void _PR_MD_INIT_ATOMIC(void);
|
||||
extern void _PR_MD_INIT_ATOMIC(void);
|
||||
#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
|
||||
|
||||
PR_EXTERN(PRInt32) _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
|
||||
extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
|
||||
#define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
|
||||
|
||||
PR_EXTERN(PRInt32) _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
|
||||
extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
|
||||
#define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
|
||||
|
||||
PR_EXTERN(PRInt32) _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
|
||||
extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
|
||||
#define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
|
||||
|
||||
/* Segment related */
|
||||
|
@ -1560,29 +1559,29 @@ extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
|
|||
|
||||
/* Time intervals */
|
||||
|
||||
PR_EXTERN(PRIntervalTime) _PR_MD_GET_INTERVAL(void);
|
||||
extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
|
||||
#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
|
||||
|
||||
PR_EXTERN(PRIntervalTime) _PR_MD_INTERVAL_PER_SEC(void);
|
||||
extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
|
||||
#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
|
||||
|
||||
/* Affinity masks */
|
||||
|
||||
PR_EXTERN(PRInt32) _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
|
||||
extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
|
||||
#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
|
||||
|
||||
PR_EXTERN(PRInt32) _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
|
||||
extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
|
||||
#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
|
||||
|
||||
/* File locking */
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_LOCKFILE(PRInt32 osfd);
|
||||
extern PRStatus _PR_MD_LOCKFILE(PRInt32 osfd);
|
||||
#define _PR_MD_LOCKFILE _MD_LOCKFILE
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_TLOCKFILE(PRInt32 osfd);
|
||||
extern PRStatus _PR_MD_TLOCKFILE(PRInt32 osfd);
|
||||
#define _PR_MD_TLOCKFILE _MD_TLOCKFILE
|
||||
|
||||
PR_EXTERN(PRStatus) _PR_MD_UNLOCKFILE(PRInt32 osfd);
|
||||
extern PRStatus _PR_MD_UNLOCKFILE(PRInt32 osfd);
|
||||
#define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
|
||||
|
||||
/* Memory-mapped files */
|
||||
|
@ -1608,7 +1607,7 @@ PR_EXTERN(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
|
|||
#define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
|
||||
|
||||
/* Get name of current host */
|
||||
PR_EXTERN(PRStatus) _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
|
||||
extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
|
||||
#define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -100,12 +100,20 @@
|
|||
#define PR_CALLBACK_DECL
|
||||
#define PR_STATIC_CALLBACK(__x) static __x
|
||||
|
||||
#else /* Unix or OS/2 */
|
||||
#elif defined(XP_OS2)
|
||||
#define PR_EXTERN(__type) extern __type
|
||||
#define PR_IMPLEMENT(__type) __type
|
||||
#define PR_EXTERN_DATA(__type) extern __type
|
||||
#define PR_IMPLEMENT_DATA(__type) __type
|
||||
#define PR_CALLBACK
|
||||
#define PR_CALLBACK_DECL
|
||||
#define PR_STATIC_CALLBACK(__x) __x _Optlink
|
||||
|
||||
#else /* Unix */
|
||||
#define PR_EXTERN(__type) extern __type
|
||||
#define PR_IMPLEMENT(__type) __type
|
||||
#define PR_EXTERN_DATA(__type) extern __type
|
||||
#define PR_IMPLEMENT_DATA(__type) __type
|
||||
#define PR_CALLBACK
|
||||
#define PR_CALLBACK_DECL
|
||||
#define PR_STATIC_CALLBACK(__x) static __x
|
||||
|
@ -227,9 +235,8 @@ typedef unsigned long PRUint64;
|
|||
typedef __int64 PRInt64;
|
||||
typedef unsigned __int64 PRUint64;
|
||||
#elif defined(WIN32)
|
||||
#include <windows.h> /* For LONGLONG and DWORDLONG */
|
||||
typedef LONGLONG PRInt64;
|
||||
typedef DWORDLONG PRUint64;
|
||||
typedef __int64 PRInt64;
|
||||
typedef unsigned __int64 PRUint64;
|
||||
#else
|
||||
typedef long long PRInt64;
|
||||
typedef unsigned long long PRUint64;
|
||||
|
@ -299,7 +306,9 @@ typedef unsigned long PRUptrdiff;
|
|||
** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
|
||||
** juast as you would C int-valued conditions.
|
||||
************************************************************************/
|
||||
typedef enum { PR_FALSE = 0, PR_TRUE = 1 } PRBool;
|
||||
typedef PRIntn PRBool;
|
||||
#define PR_TRUE (PRIntn)1
|
||||
#define PR_FALSE (PRIntn)0
|
||||
|
||||
/************************************************************************
|
||||
** TYPES: PRPackedBool
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
/*
|
||||
** Condition use of this header on platform.
|
||||
*/
|
||||
#if (defined(XP_PC) && !defined(_WIN32) && defined(MOZILLA_CLIENT)) || defined(WIN16)
|
||||
#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16)
|
||||
#include <stdio.h>
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -40,106 +40,6 @@
|
|||
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Not every platform has all the socket options we want to
|
||||
* support. Some older operating systems such as SunOS 4.1.3
|
||||
* don't have the IP multicast socket options. Win32 doesn't
|
||||
* have TCP_MAXSEG.
|
||||
*
|
||||
* To deal with this problem, we define the missing socket
|
||||
* options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with
|
||||
* PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
|
||||
* available on the platform is requested.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sanity check. SO_LINGER and TCP_NODELAY should be available
|
||||
* on all platforms. Just to make sure we have included the
|
||||
* appropriate header files. Then any undefined socket options
|
||||
* are really missing.
|
||||
*/
|
||||
|
||||
#if !defined(SO_LINGER)
|
||||
#error "SO_LINGER is not defined"
|
||||
#endif
|
||||
|
||||
#if !defined(TCP_NODELAY)
|
||||
#error "TCP_NODELAY is not defined"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure the value of _PR_NO_SUCH_SOCKOPT is not
|
||||
* a valid socket option.
|
||||
*/
|
||||
#define _PR_NO_SUCH_SOCKOPT -1
|
||||
|
||||
#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */
|
||||
#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */
|
||||
#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */
|
||||
#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */
|
||||
#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */
|
||||
#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_TTL /* set/get IP Time To Live */
|
||||
#define IP_TTL _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_TOS /* set/get IP Type Of Service */
|
||||
#define IP_TOS _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef TCP_MAXSEG /* maxumum segment size for tcp */
|
||||
#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
PRStatus _PR_MapOptionName(
|
||||
PRSockOption optname, PRInt32 *level, PRInt32 *name)
|
||||
{
|
||||
static PRInt32 socketOptions[PR_SockOpt_Last] =
|
||||
{
|
||||
0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
|
||||
IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
|
||||
IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
|
||||
TCP_NODELAY, TCP_MAXSEG
|
||||
};
|
||||
static PRInt32 socketLevels[PR_SockOpt_Last] =
|
||||
{
|
||||
0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
|
||||
IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
|
||||
IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
|
||||
IPPROTO_TCP, IPPROTO_TCP
|
||||
};
|
||||
|
||||
if ((optname < PR_SockOpt_Linger)
|
||||
&& (optname > PR_SockOpt_MaxSegment))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
|
||||
{
|
||||
PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
*name = socketOptions[optname];
|
||||
*level = socketLevels[optname];
|
||||
return PR_SUCCESS;
|
||||
} /* _PR_MapOptionName */
|
||||
|
||||
#ifndef _PR_PTHREADS
|
||||
|
||||
PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
|
||||
|
@ -244,6 +144,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
data->value.mcast_ttl = ttl;
|
||||
break;
|
||||
}
|
||||
#ifdef IP_ADD_MEMBERSHIP
|
||||
case PR_SockOpt_AddMember:
|
||||
case PR_SockOpt_DropMember:
|
||||
{
|
||||
|
@ -260,6 +161,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif /* IP_ADD_MEMBERSHIP */
|
||||
case PR_SockOpt_McastInterface:
|
||||
{
|
||||
/* This option is a struct in_addr. */
|
||||
|
@ -377,6 +279,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
fd, level, name, (char*)&ttl, sizeof(ttl));
|
||||
break;
|
||||
}
|
||||
#ifdef IP_ADD_MEMBERSHIP
|
||||
case PR_SockOpt_AddMember:
|
||||
case PR_SockOpt_DropMember:
|
||||
{
|
||||
|
@ -389,6 +292,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
fd, level, name, (char*)&mreq, sizeof(mreq));
|
||||
break;
|
||||
}
|
||||
#endif /* IP_ADD_MEMBERSHIP */
|
||||
case PR_SockOpt_McastInterface:
|
||||
{
|
||||
/* This option is a struct in_addr. */
|
||||
|
@ -406,3 +310,114 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
} /* _PR_SocketSetSocketOption */
|
||||
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
*********************************************************************
|
||||
**
|
||||
** Make sure that the following is at the end of this file,
|
||||
** because we will be playing with macro redefines.
|
||||
**
|
||||
*********************************************************************
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Not every platform has all the socket options we want to
|
||||
* support. Some older operating systems such as SunOS 4.1.3
|
||||
* don't have the IP multicast socket options. Win32 doesn't
|
||||
* have TCP_MAXSEG.
|
||||
*
|
||||
* To deal with this problem, we define the missing socket
|
||||
* options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with
|
||||
* PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
|
||||
* available on the platform is requested.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Sanity check. SO_LINGER and TCP_NODELAY should be available
|
||||
* on all platforms. Just to make sure we have included the
|
||||
* appropriate header files. Then any undefined socket options
|
||||
* are really missing.
|
||||
*/
|
||||
|
||||
#if !defined(SO_LINGER)
|
||||
#error "SO_LINGER is not defined"
|
||||
#endif
|
||||
|
||||
#if !defined(TCP_NODELAY)
|
||||
#error "TCP_NODELAY is not defined"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure the value of _PR_NO_SUCH_SOCKOPT is not
|
||||
* a valid socket option.
|
||||
*/
|
||||
#define _PR_NO_SUCH_SOCKOPT -1
|
||||
|
||||
#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */
|
||||
#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */
|
||||
#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */
|
||||
#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */
|
||||
#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */
|
||||
#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_TTL /* set/get IP Time To Live */
|
||||
#define IP_TTL _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef IP_TOS /* set/get IP Type Of Service */
|
||||
#define IP_TOS _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
#ifndef TCP_MAXSEG /* maxumum segment size for tcp */
|
||||
#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
|
||||
#endif
|
||||
|
||||
PRStatus _PR_MapOptionName(
|
||||
PRSockOption optname, PRInt32 *level, PRInt32 *name)
|
||||
{
|
||||
static PRInt32 socketOptions[PR_SockOpt_Last] =
|
||||
{
|
||||
0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
|
||||
IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
|
||||
IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
|
||||
TCP_NODELAY, TCP_MAXSEG
|
||||
};
|
||||
static PRInt32 socketLevels[PR_SockOpt_Last] =
|
||||
{
|
||||
0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
|
||||
IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
|
||||
IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
|
||||
IPPROTO_TCP, IPPROTO_TCP
|
||||
};
|
||||
|
||||
if ((optname < PR_SockOpt_Linger)
|
||||
&& (optname > PR_SockOpt_MaxSegment))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
|
||||
{
|
||||
PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
*name = socketOptions[optname];
|
||||
*level = socketLevels[optname];
|
||||
return PR_SUCCESS;
|
||||
} /* _PR_MapOptionName */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -30,29 +30,53 @@
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
/* These two functions are only used in assertions. */
|
||||
#if defined(DEBUG)
|
||||
|
||||
static PRBool IsValidNetAddr(const PRNetAddr *addr)
|
||||
{
|
||||
if ((addr != NULL)
|
||||
#ifdef XP_UNIX
|
||||
&& (addr->raw.family != AF_UNIX)
|
||||
#endif
|
||||
#ifdef _PR_INET6
|
||||
&& (addr->raw.family != AF_INET6)
|
||||
#endif
|
||||
&& (addr->raw.family != AF_INET)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
|
||||
{
|
||||
/*
|
||||
* The definition of the length of a Unix domain socket address
|
||||
* is not uniform, so we don't check it.
|
||||
*/
|
||||
if ((addr != NULL)
|
||||
#ifdef XP_UNIX
|
||||
&& (addr->raw.family != AF_UNIX)
|
||||
#endif
|
||||
&& (PR_NETADDR_SIZE(addr) != addr_len)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, PRIOVec *iov, PRInt32 iov_size,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
int w = 0;
|
||||
PRIOVec *tmp_iov = NULL;
|
||||
#define LOCAL_MAXIOV 8
|
||||
PRIOVec local_iov[LOCAL_MAXIOV];
|
||||
int tmp_out;
|
||||
int index, iov_cnt;
|
||||
int count=0, sz = 0; /* 'count' is the return value. */
|
||||
#if defined(XP_UNIX)
|
||||
struct timeval tv, *tvp;
|
||||
fd_set wd;
|
||||
|
||||
FD_ZERO(&wd);
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT)
|
||||
tvp = NULL;
|
||||
else if (timeout != PR_INTERVAL_NO_WAIT) {
|
||||
tv.tv_sec = PR_IntervalToSeconds(timeout);
|
||||
tv.tv_usec = PR_IntervalToMicroseconds(
|
||||
timeout - PR_SecondsToInterval(tv.tv_sec));
|
||||
tvp = &tv;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
|
@ -64,25 +88,22 @@ PRIntervalTime timeout)
|
|||
return -1;
|
||||
}
|
||||
|
||||
tmp_iov = (PRIOVec *)PR_CALLOC(iov_size * sizeof(PRIOVec));
|
||||
if (!tmp_iov) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Assume the first writev will succeed. Copy iov's only on
|
||||
* failure.
|
||||
*/
|
||||
tmp_iov = iov;
|
||||
for (index = 0; index < iov_size; index++)
|
||||
sz += iov[index].iov_len;
|
||||
|
||||
for (index=0; index<iov_size; index++) {
|
||||
sz += iov[index].iov_len;
|
||||
tmp_iov[index].iov_base = iov[index].iov_base;
|
||||
tmp_iov[index].iov_len = iov[index].iov_len;
|
||||
}
|
||||
iov_cnt = iov_size;
|
||||
|
||||
while (sz > 0) {
|
||||
|
||||
w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout);
|
||||
if (w < 0) {
|
||||
count = -1;
|
||||
break;
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
count += w;
|
||||
if (fd->secret->nonblocking) {
|
||||
|
@ -93,9 +114,24 @@ PRIntervalTime timeout)
|
|||
if (sz > 0) {
|
||||
/* find the next unwritten vector */
|
||||
for ( index = 0, tmp_out = count;
|
||||
tmp_out >= iov[index].iov_len;
|
||||
tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
|
||||
tmp_out >= iov[index].iov_len;
|
||||
tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
|
||||
|
||||
if (tmp_iov == iov) {
|
||||
/*
|
||||
* The first writev failed so we
|
||||
* must copy iov's around.
|
||||
* Avoid calloc/free if there
|
||||
* are few enough iov's.
|
||||
*/
|
||||
if (iov_size - index <= LOCAL_MAXIOV)
|
||||
tmp_iov = local_iov;
|
||||
else if ((tmp_iov = (PRIOVec *) PR_CALLOC((iov_size - index) *
|
||||
sizeof *tmp_iov)) == NULL) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in the first partial read */
|
||||
tmp_iov[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]);
|
||||
|
@ -110,7 +146,7 @@ PRIntervalTime timeout)
|
|||
}
|
||||
}
|
||||
|
||||
if (tmp_iov)
|
||||
if (tmp_iov != iov && tmp_iov != local_iov)
|
||||
PR_DELETE(tmp_iov);
|
||||
return count;
|
||||
}
|
||||
|
@ -307,13 +343,8 @@ PRIntervalTime timeout)
|
|||
_PR_MD_MAKE_NONBLOCK(fd2);
|
||||
#endif
|
||||
|
||||
PR_ASSERT((NULL == addr) || (PR_NETADDR_SIZE(addr) == al));
|
||||
#if defined(_PR_INET6)
|
||||
PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET)
|
||||
|| (addr->raw.family == AF_INET6));
|
||||
#else
|
||||
PR_ASSERT((NULL == addr) || (addr->raw.family == AF_INET));
|
||||
#endif
|
||||
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
|
||||
PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
|
||||
|
||||
return fd2;
|
||||
}
|
||||
|
@ -367,10 +398,16 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
|
|||
PRInt32 result;
|
||||
int one = 1;
|
||||
|
||||
#if defined(_PR_INET6)
|
||||
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
|
||||
#else
|
||||
PR_ASSERT(addr->raw.family == AF_INET);
|
||||
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
|
||||
|
||||
#ifdef XP_UNIX
|
||||
if (addr->raw.family == AF_UNIX) {
|
||||
/* Disallow relative pathnames */
|
||||
if (addr->local.path[0] != '/') {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOCKET_REUSEADDR
|
||||
|
@ -380,6 +417,10 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
}
|
||||
#endif
|
||||
|
||||
result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
|
||||
if (result < 0) {
|
||||
return PR_FAILURE;
|
||||
|
@ -541,11 +582,7 @@ static PRInt32 PR_CALLBACK SocketSendTo(
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined(_PR_INET6)
|
||||
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
|
||||
#else
|
||||
PR_ASSERT(addr->raw.family == AF_INET);
|
||||
#endif
|
||||
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
|
||||
|
||||
count = 0;
|
||||
while (amount > 0) {
|
||||
|
@ -797,12 +834,8 @@ static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
|
|||
if (result < 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr));
|
||||
#if defined(_PR_INET6)
|
||||
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
|
||||
#else
|
||||
PR_ASSERT(addr->raw.family == AF_INET);
|
||||
#endif
|
||||
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
|
||||
PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -816,12 +849,8 @@ static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
|
|||
if (result < 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr));
|
||||
#if defined(_PR_INET6)
|
||||
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
|
||||
#else
|
||||
PR_ASSERT(addr->raw.family == AF_INET);
|
||||
#endif
|
||||
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
|
||||
PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -925,6 +954,13 @@ static PRStatus PR_CALLBACK SocketSetSockOpt(
|
|||
return rv;
|
||||
}
|
||||
|
||||
static PRInt16 PR_CALLBACK SocketPoll(
|
||||
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
|
||||
{
|
||||
*out_flags = 0;
|
||||
return in_flags;
|
||||
} /* SocketPoll */
|
||||
|
||||
static PRIOMethods tcpMethods = {
|
||||
PR_DESC_SOCKET_TCP,
|
||||
SocketClose,
|
||||
|
@ -947,7 +983,7 @@ static PRIOMethods tcpMethods = {
|
|||
SocketSend,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
(PRPollFN)0,
|
||||
SocketPoll,
|
||||
SocketAcceptRead,
|
||||
SocketTransmitFile,
|
||||
SocketGetName,
|
||||
|
@ -980,7 +1016,7 @@ static PRIOMethods udpMethods = {
|
|||
SocketSend,
|
||||
SocketRecvFrom,
|
||||
SocketSendTo,
|
||||
(PRPollFN)0,
|
||||
SocketPoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
SocketGetName,
|
||||
|
@ -991,12 +1027,12 @@ static PRIOMethods udpMethods = {
|
|||
_PR_SocketSetSocketOption
|
||||
};
|
||||
|
||||
PR_IMPLEMENT(PRIOMethods*) PR_GetTCPMethods()
|
||||
PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
|
||||
{
|
||||
return &tcpMethods;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRIOMethods*) PR_GetUDPMethods()
|
||||
PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
|
||||
{
|
||||
return &udpMethods;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "primpl.h"
|
||||
#include <process.h> /* for _beginthread() */
|
||||
|
||||
APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
|
||||
APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
|
||||
|
||||
/* --- globals ------------------------------------------------ */
|
||||
_NSPR_TLS* pThreadLocalStorage = 0;
|
||||
|
@ -83,7 +83,7 @@ _PR_MD_CREATE_THREAD(PRThread *thread,
|
|||
PRThreadState state,
|
||||
PRUint32 stackSize)
|
||||
{
|
||||
thread->md.handle = thread->id = (TID) _beginthread(
|
||||
thread->md.handle = thread->id = (OS2TID) _beginthread(
|
||||
(void(* _Optlink)(void*))start,
|
||||
NULL,
|
||||
thread->stack->stackSize,
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
|
||||
/*
|
||||
* NSPR 2.0 overrides the system select() and poll() functions.
|
||||
* On AIX 4.2, we use dlopen("/unix", 0) and dlsym() to get to the
|
||||
* original system select() and poll() functions.
|
||||
* On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get
|
||||
* at the original system select() and poll() functions.
|
||||
*/
|
||||
|
||||
#ifndef AIX4_1
|
||||
|
||||
#include <sys/atomic_op.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/poll.h>
|
||||
#include <dlfcn.h>
|
||||
|
@ -34,13 +35,25 @@ static void *aix_handle = NULL;
|
|||
static int (*aix_select_fcn)() = NULL;
|
||||
static int (*aix_poll_fcn)() = NULL;
|
||||
|
||||
PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval)
|
||||
{
|
||||
PRIntn oldval;
|
||||
boolean_t stored;
|
||||
oldval = fetch_and_add((atomic_p)val, 0);
|
||||
do
|
||||
{
|
||||
stored = compare_and_swap((atomic_p)val, &oldval, newval);
|
||||
} while (!stored);
|
||||
return oldval;
|
||||
} /* _AIX_AtomicSet */
|
||||
|
||||
int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (!aix_select_fcn) {
|
||||
if (!aix_handle) {
|
||||
aix_handle = dlopen("/unix",0);
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
|
@ -62,7 +75,7 @@ int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
|
|||
|
||||
if (!aix_poll_fcn) {
|
||||
if (!aix_handle) {
|
||||
aix_handle = dlopen("/unix",0);
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
|
@ -95,10 +108,38 @@ void _pr_aix_dummy()
|
|||
|
||||
#if !defined(PTHREADS_USER)
|
||||
|
||||
#ifdef _PR_PTHREADS
|
||||
|
||||
/*
|
||||
* AIX 4.3 has sched_yield(). AIX 4.2 has pthread_yield().
|
||||
* So we look up the appropriate function pointer at run time.
|
||||
*/
|
||||
|
||||
int (*_PT_aix_yield_fcn)() = NULL;
|
||||
|
||||
void _MD_EarlyInit(void)
|
||||
{
|
||||
void *main_app_handle = NULL;
|
||||
|
||||
main_app_handle = dlopen(NULL, RTLD_NOW);
|
||||
PR_ASSERT(NULL != main_app_handle);
|
||||
|
||||
_PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield");
|
||||
if (!_PT_aix_yield_fcn) {
|
||||
_PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield");
|
||||
PR_ASSERT(NULL != _PT_aix_yield_fcn);
|
||||
}
|
||||
dlclose(main_app_handle);
|
||||
}
|
||||
|
||||
#else /* _PR_PTHREADS */
|
||||
|
||||
void _MD_EarlyInit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* _PR_PTHREADS */
|
||||
|
||||
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
||||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
|
|
|
@ -98,135 +98,3 @@ _MD_CREATE_THREAD(
|
|||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
||||
#if defined(_PR_NEED_FAKE_POLL)
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
|
||||
{
|
||||
int i;
|
||||
int rv;
|
||||
int maxfd;
|
||||
fd_set rd, wr, ex;
|
||||
struct timeval tv, *tvp;
|
||||
|
||||
if (timeout < 0 && timeout != -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
tvp = NULL;
|
||||
} else {
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
maxfd = -1;
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&ex);
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
int osfd = filedes[i].fd;
|
||||
int events = filedes[i].events;
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
if (osfd < 0) {
|
||||
continue; /* Skip this osfd. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the native poll flags to nspr poll flags.
|
||||
* POLLIN, POLLRDNORM ===> PR_POLL_READ
|
||||
* POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
|
||||
* POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
|
||||
* POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
|
||||
* are ignored.
|
||||
*
|
||||
* The output events POLLERR and POLLHUP are never turned on.
|
||||
* POLLNVAL may be turned on.
|
||||
*/
|
||||
|
||||
if (events & (POLLIN | POLLRDNORM)) {
|
||||
FD_SET(osfd, &rd);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLOUT | POLLWRNORM)) {
|
||||
FD_SET(osfd, &wr);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLPRI | POLLRDBAND)) {
|
||||
FD_SET(osfd, &ex);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent && osfd > maxfd) {
|
||||
maxfd = osfd;
|
||||
}
|
||||
}
|
||||
|
||||
rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
|
||||
|
||||
/* Compute poll results */
|
||||
if (rv > 0) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &rd)) {
|
||||
if (filedes[i].events & POLLIN) {
|
||||
filedes[i].revents |= POLLIN;
|
||||
}
|
||||
if (filedes[i].events & POLLRDNORM) {
|
||||
filedes[i].revents |= POLLRDNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &wr)) {
|
||||
if (filedes[i].events & POLLOUT) {
|
||||
filedes[i].revents |= POLLOUT;
|
||||
}
|
||||
if (filedes[i].events & POLLWRNORM) {
|
||||
filedes[i].revents |= POLLWRNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &ex)) {
|
||||
if (filedes[i].events & POLLPRI) {
|
||||
filedes[i].revents |= POLLPRI;
|
||||
}
|
||||
if (filedes[i].events & POLLRDBAND) {
|
||||
filedes[i].revents |= POLLRDBAND;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent) {
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
} else if (rv == -1 && errno == EBADF) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
|
||||
filedes[i].revents = POLLNVAL;
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
}
|
||||
PR_ASSERT(-1 != timeout || rv != 0);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif /* _PR_NEED_FAKE_POLL */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,135 +96,3 @@ _MD_CREATE_THREAD(
|
|||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
||||
#if defined(_PR_NEED_FAKE_POLL)
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
|
||||
{
|
||||
int i;
|
||||
int rv;
|
||||
int maxfd;
|
||||
fd_set rd, wr, ex;
|
||||
struct timeval tv, *tvp;
|
||||
|
||||
if (timeout < 0 && timeout != -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
tvp = NULL;
|
||||
} else {
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
maxfd = -1;
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&ex);
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
int osfd = filedes[i].fd;
|
||||
int events = filedes[i].events;
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
if (osfd < 0) {
|
||||
continue; /* Skip this osfd. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the native poll flags to nspr poll flags.
|
||||
* POLLIN, POLLRDNORM ===> PR_POLL_READ
|
||||
* POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
|
||||
* POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
|
||||
* POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
|
||||
* are ignored.
|
||||
*
|
||||
* The output events POLLERR and POLLHUP are never turned on.
|
||||
* POLLNVAL may be turned on.
|
||||
*/
|
||||
|
||||
if (events & (POLLIN | POLLRDNORM)) {
|
||||
FD_SET(osfd, &rd);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLOUT | POLLWRNORM)) {
|
||||
FD_SET(osfd, &wr);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLPRI | POLLRDBAND)) {
|
||||
FD_SET(osfd, &ex);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent && osfd > maxfd) {
|
||||
maxfd = osfd;
|
||||
}
|
||||
}
|
||||
|
||||
rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
|
||||
|
||||
/* Compute poll results */
|
||||
if (rv > 0) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &rd)) {
|
||||
if (filedes[i].events & POLLIN) {
|
||||
filedes[i].revents |= POLLIN;
|
||||
}
|
||||
if (filedes[i].events & POLLRDNORM) {
|
||||
filedes[i].revents |= POLLRDNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &wr)) {
|
||||
if (filedes[i].events & POLLOUT) {
|
||||
filedes[i].revents |= POLLOUT;
|
||||
}
|
||||
if (filedes[i].events & POLLWRNORM) {
|
||||
filedes[i].revents |= POLLWRNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &ex)) {
|
||||
if (filedes[i].events & POLLPRI) {
|
||||
filedes[i].revents |= POLLPRI;
|
||||
}
|
||||
if (filedes[i].events & POLLRDBAND) {
|
||||
filedes[i].revents |= POLLRDBAND;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent) {
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
} else if (rv == -1 && errno == EBADF) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
|
||||
filedes[i].revents = POLLNVAL;
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
}
|
||||
PR_ASSERT(-1 != timeout || rv != 0);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif /* _PR_NEED_FAKE_POLL */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* We want position independent code */
|
||||
#define PIC
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef _PR_POLL_AVAILABLE
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
/* To get FIONREAD */
|
||||
#if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
|
||||
|| defined(SONY)
|
||||
|
@ -41,7 +45,7 @@
|
|||
#if defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
|
||||
|| defined(AIX4_1) || defined(LINUX) || defined(SONY) \
|
||||
|| defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
|
||||
|| defined(SUNOS4)
|
||||
|| defined(SUNOS4) || defined(NCR)
|
||||
#define _PRSockLen_t int
|
||||
#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
|
||||
|| defined(UNIXWARE)
|
||||
|
@ -89,7 +93,7 @@ static sigset_t empty_set;
|
|||
/*
|
||||
* _nspr_noclock - if set clock interrupts are disabled
|
||||
*/
|
||||
int _nspr_noclock = 0;
|
||||
int _nspr_noclock = 1;
|
||||
|
||||
#ifdef IRIX
|
||||
extern PRInt32 _nspr_terminate_on_error;
|
||||
|
@ -380,11 +384,20 @@ PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount)
|
|||
{
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRInt32 rv, err;
|
||||
#ifndef _PR_USE_POLL
|
||||
fd_set rd;
|
||||
#else
|
||||
struct pollfd pfd;
|
||||
#endif /* _PR_USE_POLL */
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
||||
#ifndef _PR_USE_POLL
|
||||
FD_ZERO(&rd);
|
||||
FD_SET(osfd, &rd);
|
||||
#else
|
||||
pfd.fd = osfd;
|
||||
pfd.events = POLLIN;
|
||||
#endif /* _PR_USE_POLL */
|
||||
while ((rv = read(osfd,buf,amount)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
|
@ -394,10 +407,17 @@ PRInt32 osfd = fd->secret->md.osfd;
|
|||
if (!_PR_IS_NATIVE_THREAD(me)) {
|
||||
_PR_WaitForFD(osfd, PR_POLL_READ, PR_INTERVAL_NO_TIMEOUT);
|
||||
} else {
|
||||
#ifndef _PR_USE_POLL
|
||||
while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
|
||||
== -1 && (err = _MD_ERRNO()) == EINTR) {
|
||||
/* retry _MD_SELECT() if it is interrupted */
|
||||
}
|
||||
#else /* _PR_USE_POLL */
|
||||
while ((rv = _MD_POLL(&pfd, 1, -1))
|
||||
== -1 && (err = _MD_ERRNO()) == EINTR) {
|
||||
/* retry _MD_POLL() if it is interrupted */
|
||||
}
|
||||
#endif /* _PR_USE_POLL */
|
||||
if (rv == -1) {
|
||||
break;
|
||||
}
|
||||
|
@ -425,11 +445,20 @@ PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
|
|||
{
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRInt32 rv, err;
|
||||
#ifndef _PR_USE_POLL
|
||||
fd_set wd;
|
||||
#else
|
||||
struct pollfd pfd;
|
||||
#endif /* _PR_USE_POLL */
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
||||
#ifndef _PR_USE_POLL
|
||||
FD_ZERO(&wd);
|
||||
FD_SET(osfd, &wd);
|
||||
#else
|
||||
pfd.fd = osfd;
|
||||
pfd.events = POLLOUT;
|
||||
#endif /* _PR_USE_POLL */
|
||||
while ((rv = write(osfd,buf,amount)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
|
@ -439,10 +468,17 @@ PRInt32 osfd = fd->secret->md.osfd;
|
|||
if (!_PR_IS_NATIVE_THREAD(me)) {
|
||||
_PR_WaitForFD(osfd, PR_POLL_WRITE, PR_INTERVAL_NO_TIMEOUT);
|
||||
} else {
|
||||
#ifndef _PR_USE_POLL
|
||||
while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
|
||||
== -1 && (err = _MD_ERRNO()) == EINTR) {
|
||||
/* retry _MD_SELECT() if it is interrupted */
|
||||
}
|
||||
#else /* _PR_USE_POLL */
|
||||
while ((rv = _MD_POLL(&pfd, 1, -1))
|
||||
== -1 && (err = _MD_ERRNO()) == EINTR) {
|
||||
/* retry _MD_POLL() if it is interrupted */
|
||||
}
|
||||
#endif /* _PR_USE_POLL */
|
||||
if (rv == -1) {
|
||||
break;
|
||||
}
|
||||
|
@ -570,11 +606,18 @@ PRInt64 _MD_socketavailable64(PRFileDesc *fd)
|
|||
#define WRITE_FD 2
|
||||
|
||||
/*
|
||||
* socket_io_wait --
|
||||
*
|
||||
* wait for socket i/o, periodically checking for interrupt
|
||||
*
|
||||
* The first implementation uses select(), for platforms without
|
||||
* poll(). The second (preferred) implementation uses poll().
|
||||
*/
|
||||
|
||||
#ifndef _PR_USE_POLL
|
||||
|
||||
static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
|
||||
PRIntervalTime timeout)
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv = -1;
|
||||
struct timeval tv, *tvp;
|
||||
|
@ -692,6 +735,114 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
|
|||
return(rv);
|
||||
}
|
||||
|
||||
#else /* _PR_USE_POLL */
|
||||
|
||||
static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv = -1;
|
||||
int msecs;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRIntervalTime epoch, now, elapsed, remaining;
|
||||
PRInt32 syserror;
|
||||
struct pollfd pfd;
|
||||
|
||||
switch (timeout) {
|
||||
case PR_INTERVAL_NO_WAIT:
|
||||
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
|
||||
break;
|
||||
case PR_INTERVAL_NO_TIMEOUT:
|
||||
/*
|
||||
* This is a special case of the 'default' case below.
|
||||
* Please see the comments there.
|
||||
*/
|
||||
msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
|
||||
pfd.fd = osfd;
|
||||
if (fd_type == READ_FD) {
|
||||
pfd.events = POLLIN;
|
||||
} else {
|
||||
pfd.events = POLLOUT;
|
||||
}
|
||||
do {
|
||||
rv = _MD_POLL(&pfd, 1, msecs);
|
||||
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
|
||||
_PR_MD_MAP_POLL_ERROR(syserror);
|
||||
break;
|
||||
}
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
} while (rv == 0 || (rv == -1 && syserror == EINTR));
|
||||
break;
|
||||
default:
|
||||
now = epoch = PR_IntervalNow();
|
||||
remaining = timeout;
|
||||
pfd.fd = osfd;
|
||||
if (fd_type == READ_FD) {
|
||||
pfd.events = POLLIN;
|
||||
} else {
|
||||
pfd.events = POLLOUT;
|
||||
}
|
||||
do {
|
||||
/*
|
||||
* We block in _MD_POLL for at most
|
||||
* _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
|
||||
* so that there is an upper limit on the delay
|
||||
* before the interrupt bit is checked.
|
||||
*/
|
||||
msecs = PR_IntervalToMilliseconds(remaining);
|
||||
if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
|
||||
msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
|
||||
}
|
||||
rv = _MD_POLL(&pfd, 1, msecs);
|
||||
/*
|
||||
* we don't consider EINTR a real error
|
||||
*/
|
||||
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
|
||||
_PR_MD_MAP_POLL_ERROR(syserror);
|
||||
break;
|
||||
}
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* We loop again if _MD_POLL timed out or got interrupted
|
||||
* by a signal, and the timeout deadline has not passed yet.
|
||||
*/
|
||||
if (rv == 0 || (rv == -1 && syserror == EINTR)) {
|
||||
/*
|
||||
* If _MD_POLL timed out, we know how much time
|
||||
* we spent in blocking, so we can avoid a
|
||||
* PR_IntervalNow() call.
|
||||
*/
|
||||
if (rv == 0) {
|
||||
now += PR_MillisecondsToInterval(msecs);
|
||||
} else {
|
||||
now = PR_IntervalNow();
|
||||
}
|
||||
elapsed = (PRIntervalTime) (now - epoch);
|
||||
if (elapsed >= timeout) {
|
||||
PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
|
||||
rv = -1;
|
||||
break;
|
||||
} else {
|
||||
remaining = timeout - elapsed;
|
||||
}
|
||||
}
|
||||
} while (rv == 0 || (rv == -1 && syserror == EINTR));
|
||||
break;
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
#endif /* _PR_USE_POLL */
|
||||
|
||||
PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||
PRInt32 flags, PRIntervalTime timeout)
|
||||
{
|
||||
|
@ -794,14 +945,17 @@ PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
|
|||
_PR_MD_MAP_RECVFROM_ERROR(err);
|
||||
}
|
||||
done:
|
||||
#ifdef AIX
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv != -1) {
|
||||
/* mask off the first byte of struct sockaddr (the length field) */
|
||||
if (addr) {
|
||||
addr->inet.family &= 0x00ff;
|
||||
*((unsigned char *) addr) = 0;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
addr->raw.family = ntohs(addr->raw.family);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
return(rv);
|
||||
}
|
||||
|
||||
|
@ -1043,14 +1197,17 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
|
|||
_PR_MD_MAP_ACCEPT_ERROR(err);
|
||||
}
|
||||
done:
|
||||
#ifdef AIX
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv != -1) {
|
||||
/* mask off the first byte of struct sockaddr (the length field) */
|
||||
if (addr) {
|
||||
addr->inet.family &= 0x00ff;
|
||||
*((unsigned char *) addr) = 0;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
addr->raw.family = ntohs(addr->raw.family);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
return(rv);
|
||||
}
|
||||
|
||||
|
@ -1198,14 +1355,17 @@ PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
|
|||
|
||||
rv = getsockname(fd->secret->md.osfd,
|
||||
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
|
||||
#ifdef AIX
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv == 0) {
|
||||
/* mask off the first byte of struct sockaddr (the length field) */
|
||||
if (addr) {
|
||||
addr->inet.family &= 0x00ff;
|
||||
*((unsigned char *) addr) = 0;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
addr->raw.family = ntohs(addr->raw.family);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETSOCKNAME_ERROR(err);
|
||||
|
@ -1220,14 +1380,17 @@ PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
|
|||
|
||||
rv = getpeername(fd->secret->md.osfd,
|
||||
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
|
||||
#ifdef AIX
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv == 0) {
|
||||
/* mask off the first byte of struct sockaddr (the length field) */
|
||||
if (addr) {
|
||||
addr->inet.family &= 0x00ff;
|
||||
*((unsigned char *) addr) = 0;
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
addr->raw.family = ntohs(addr->raw.family);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETPEERNAME_ERROR(err);
|
||||
|
@ -1272,7 +1435,16 @@ PR_IMPLEMENT(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
|
|||
_PRCPU *io_cpu;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
if (0 == npds) {
|
||||
PR_Sleep(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_PR_IS_NATIVE_THREAD(me)) {
|
||||
#ifndef _PR_USE_POLL
|
||||
/*
|
||||
* On platforms that don't have poll(), we call select().
|
||||
*/
|
||||
fd_set rd, wt, ex;
|
||||
struct timeval tv, *tvp = NULL;
|
||||
int maxfd = -1;
|
||||
|
@ -1398,6 +1570,105 @@ retry:
|
|||
}
|
||||
|
||||
return n;
|
||||
#else /* _PR_USE_POLL */
|
||||
/*
|
||||
* For restarting _MD_POLL() if it is interrupted by a signal.
|
||||
* We use these variables to figure out how much time has elapsed
|
||||
* and how much of the timeout still remains.
|
||||
*/
|
||||
PRIntervalTime start, elapsed, remaining;
|
||||
int index, msecs;
|
||||
struct pollfd *syspoll;
|
||||
|
||||
syspoll = (struct pollfd *) PR_MALLOC(npds * sizeof(struct pollfd));
|
||||
if (NULL == syspoll) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
for (index = 0; index < npds; index++) {
|
||||
PRFileDesc *bottom = pds[index].fd;
|
||||
|
||||
if (NULL == bottom) {
|
||||
/* make poll() ignore this entry */
|
||||
syspoll[index].fd = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (bottom->lower != NULL) {
|
||||
bottom = bottom->lower;
|
||||
}
|
||||
syspoll[index].fd = bottom->secret->md.osfd;
|
||||
|
||||
syspoll[index].events = 0;
|
||||
if (pds[index].in_flags & PR_POLL_READ) {
|
||||
syspoll[index].events |= POLLIN;
|
||||
}
|
||||
if (pds[index].in_flags & PR_POLL_WRITE) {
|
||||
syspoll[index].events |= POLLOUT;
|
||||
}
|
||||
if (pds[index].in_flags & PR_POLL_EXCEPT) {
|
||||
syspoll[index].events |= POLLPRI;
|
||||
}
|
||||
pds[index].out_flags = 0; /* init the result */
|
||||
}
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
|
||||
msecs = -1;
|
||||
} else {
|
||||
msecs = PR_IntervalToMilliseconds(timeout);
|
||||
start = PR_IntervalNow();
|
||||
}
|
||||
|
||||
retry:
|
||||
n = _MD_POLL(syspoll, npds, msecs);
|
||||
if (n == -1) {
|
||||
err = _MD_ERRNO();
|
||||
if (err == EINTR) {
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
|
||||
goto retry;
|
||||
} else if (timeout == PR_INTERVAL_NO_WAIT) {
|
||||
n = 0; /* don't retry, just time out */
|
||||
} else {
|
||||
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
|
||||
if (elapsed > timeout) {
|
||||
n = 0; /* timed out */
|
||||
} else {
|
||||
remaining = timeout - elapsed;
|
||||
msecs = PR_IntervalToMilliseconds(remaining);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_PR_MD_MAP_POLL_ERROR(err);
|
||||
}
|
||||
} else if (n > 0) {
|
||||
for (index = 0; index < npds; index++) {
|
||||
if (NULL == pds[index].fd) {
|
||||
continue;
|
||||
}
|
||||
PR_ASSERT(0 == pds[index].out_flags);
|
||||
if (0 != syspoll[index].revents) {
|
||||
if (syspoll[index].revents & POLLIN) {
|
||||
pds[index].out_flags |= PR_POLL_READ;
|
||||
}
|
||||
if (syspoll[index].revents & POLLOUT) {
|
||||
pds[index].out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (syspoll[index].revents & POLLPRI) {
|
||||
pds[index].out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
if (syspoll[index].revents & POLLERR) {
|
||||
pds[index].out_flags |= PR_POLL_ERR;
|
||||
}
|
||||
if (syspoll[index].revents & POLLNVAL) {
|
||||
pds[index].out_flags |= PR_POLL_NVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_DELETE(syspoll);
|
||||
return n;
|
||||
#endif /* _PR_USE_POLL */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1455,6 +1726,7 @@ retry:
|
|||
unixpd++;
|
||||
pdcnt++;
|
||||
|
||||
#ifndef _PR_USE_POLL
|
||||
if (in_flags & PR_POLL_READ) {
|
||||
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
_PR_FD_READ_CNT(me->cpu)[osfd]++;
|
||||
|
@ -1467,12 +1739,14 @@ retry:
|
|||
FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
|
||||
}
|
||||
#endif /* _PR_USE_POLL */
|
||||
if (osfd > _PR_IOQ_MAX_OSFD(me->cpu))
|
||||
_PR_IOQ_MAX_OSFD(me->cpu) = osfd;
|
||||
}
|
||||
if (timeout < _PR_IOQ_TIMEOUT(me->cpu))
|
||||
_PR_IOQ_TIMEOUT(me->cpu) = timeout;
|
||||
|
||||
_PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
|
||||
|
||||
pq.pds = unixpds;
|
||||
pq.npds = pdcnt;
|
||||
|
@ -1541,6 +1815,7 @@ retry:
|
|||
}
|
||||
osfd = bottom->secret->md.osfd;
|
||||
PR_ASSERT(osfd >= 0 || in_flags == 0);
|
||||
#ifndef _PR_USE_POLL
|
||||
if (in_flags & PR_POLL_READ) {
|
||||
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
|
||||
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
|
@ -1553,7 +1828,10 @@ retry:
|
|||
if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
|
||||
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt;
|
||||
PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
|
||||
}
|
||||
_PR_MD_IOQ_UNLOCK();
|
||||
}
|
||||
|
@ -1637,6 +1915,7 @@ static void FindBadFDs(void)
|
|||
PRInt32 osfd = pds->osfd;
|
||||
PRInt16 in_flags = pds->in_flags;
|
||||
PR_ASSERT(osfd >= 0 || in_flags == 0);
|
||||
#ifndef _PR_USE_POLL
|
||||
if (in_flags & PR_POLL_READ) {
|
||||
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
|
||||
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
|
@ -1649,6 +1928,7 @@ static void FindBadFDs(void)
|
|||
if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
|
||||
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
}
|
||||
#endif /* !_PR_USE_POLL */
|
||||
}
|
||||
|
||||
_PR_THREAD_LOCK(pq->thr);
|
||||
|
@ -1700,6 +1980,7 @@ void _MD_PauseCPU(PRIntervalTime ticks)
|
|||
struct pollfd *pollfds; /* an array of pollfd structures */
|
||||
struct pollfd *pollfdPtr; /* a pointer that steps through the array */
|
||||
unsigned long npollfds; /* number of pollfd structures in array */
|
||||
unsigned long pollfds_size;
|
||||
int nfd; /* to hold the return value of poll() */
|
||||
#else
|
||||
struct timeval timeout, *tvp;
|
||||
|
@ -1723,12 +2004,9 @@ extern sigset_t ints_off;
|
|||
/* Build up the pollfd structure array to wait on */
|
||||
|
||||
/* Find out how many pollfd structures are needed */
|
||||
npollfds = 0;
|
||||
for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
|
||||
PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
|
||||
npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
|
||||
PR_ASSERT(npollfds >= 0);
|
||||
|
||||
npollfds += pq->npds;
|
||||
}
|
||||
/*
|
||||
* We use a pipe to wake up a native thread. An fd is needed
|
||||
* for the pipe and we poll it for reading.
|
||||
|
@ -1736,8 +2014,21 @@ extern sigset_t ints_off;
|
|||
if (_PR_IS_NATIVE_THREAD_SUPPORTED())
|
||||
npollfds++;
|
||||
|
||||
pollfds = (struct pollfd *) PR_MALLOC(npollfds * sizeof(struct pollfd));
|
||||
pollfdPtr = pollfds;
|
||||
/*
|
||||
* if the cpu's pollfd array is not big enough, release it and allocate a new one
|
||||
*/
|
||||
if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
|
||||
if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
|
||||
PR_DELETE(pollfds);
|
||||
pollfds_size = PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
|
||||
pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
|
||||
_PR_IOQ_POLLFDS(me->cpu) = pollfds;
|
||||
_PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
|
||||
pollfdPtr = pollfds;
|
||||
} else {
|
||||
pollfds = _PR_IOQ_POLLFDS(me->cpu);
|
||||
pollfdPtr = pollfds;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we need to poll the pipe for waking up a native thread,
|
||||
|
@ -1769,6 +2060,7 @@ extern sigset_t ints_off;
|
|||
pollfdPtr->events = pds->in_flags;
|
||||
}
|
||||
}
|
||||
_PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
|
||||
#else
|
||||
/*
|
||||
* assigment of fd_sets
|
||||
|
@ -1897,16 +2189,16 @@ extern sigset_t ints_off;
|
|||
|
||||
for (; pds < epds; pds++, pollfdPtr++) {
|
||||
/*
|
||||
* Assert that the pollfdPtr pointer does not go beyond
|
||||
* the end of the pollfds array.
|
||||
*/
|
||||
* Assert that the pollfdPtr pointer does not go beyond
|
||||
* the end of the pollfds array.
|
||||
*/
|
||||
PR_ASSERT(pollfdPtr < pollfds + npollfds);
|
||||
/*
|
||||
* Assert that the fd's in the pollfds array (stepped
|
||||
* through by pollfdPtr) are in the same order as
|
||||
* the fd's in _PR_IOQ() (stepped through by q and pds).
|
||||
* This is how the pollfds array was created earlier.
|
||||
*/
|
||||
* Assert that the fd's in the pollfds array (stepped
|
||||
* through by pollfdPtr) are in the same order as
|
||||
* the fd's in _PR_IOQ() (stepped through by q and pds).
|
||||
* This is how the pollfds array was created earlier.
|
||||
*/
|
||||
PR_ASSERT(pollfdPtr->fd == pds->osfd);
|
||||
pds->out_flags = pollfdPtr->revents;
|
||||
/* Negative fd's are ignored by poll() */
|
||||
|
@ -1921,12 +2213,7 @@ extern sigset_t ints_off;
|
|||
PR_REMOVE_LINK(&pq->links);
|
||||
pq->on_ioq = PR_FALSE;
|
||||
|
||||
/*
|
||||
* Because this thread can run on a different cpu right
|
||||
* after being added to the run queue, do not dereference
|
||||
* pq
|
||||
*/
|
||||
thred = pq->thr;
|
||||
thred = pq->thr;
|
||||
_PR_THREAD_LOCK(thred);
|
||||
if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
|
||||
_PRCPU *cpu = pq->thr->cpu;
|
||||
|
@ -1944,14 +2231,14 @@ extern sigset_t ints_off;
|
|||
_PR_MD_WAKEUP_WAITER(thred);
|
||||
}
|
||||
_PR_THREAD_UNLOCK(thred);
|
||||
_PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;
|
||||
PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
|
||||
}
|
||||
}
|
||||
} else if (nfd == -1) {
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
|
||||
}
|
||||
|
||||
/* done with pollfds */
|
||||
PR_DELETE(pollfds);
|
||||
#else
|
||||
if (nfd > 0) {
|
||||
q = _PR_IOQ(me->cpu).next;
|
||||
|
@ -2136,7 +2423,9 @@ void _MD_InitCPUS()
|
|||
rv = pipe(_pr_md_pipefd);
|
||||
PR_ASSERT(rv == 0);
|
||||
_PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
|
||||
#ifndef _PR_USE_POLL
|
||||
FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
|
||||
#endif
|
||||
|
||||
flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
|
||||
fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);
|
||||
|
@ -2897,6 +3186,8 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
|
|||
pq.on_ioq = PR_TRUE;
|
||||
pq.timeout = timeout;
|
||||
_PR_ADD_TO_IOQ(pq, me->cpu);
|
||||
|
||||
#ifndef _PR_USE_POLL
|
||||
if (how == PR_POLL_READ) {
|
||||
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
(_PR_FD_READ_CNT(me->cpu))[osfd]++;
|
||||
|
@ -2907,12 +3198,15 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
|
|||
FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
|
||||
}
|
||||
#endif /* _PR_USE_POLL */
|
||||
|
||||
if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd)
|
||||
_PR_IOQ_MAX_OSFD(me->cpu) = osfd;
|
||||
if (_PR_IOQ_TIMEOUT(me->cpu) > timeout)
|
||||
_PR_IOQ_TIMEOUT(me->cpu) = timeout;
|
||||
|
||||
|
||||
_PR_IOQ_OSFD_CNT(me->cpu) += 1;
|
||||
|
||||
_PR_SLEEPQ_LOCK(me->cpu);
|
||||
_PR_ADD_SLEEPQ(me, timeout);
|
||||
me->state = _PR_IO_WAIT;
|
||||
|
@ -2944,17 +3238,21 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
|
|||
*/
|
||||
if (pq.on_ioq) {
|
||||
PR_REMOVE_LINK(&pq.links);
|
||||
if (how == PR_POLL_READ) {
|
||||
if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
|
||||
} else if (how == PR_POLL_WRITE) {
|
||||
if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
|
||||
} else {
|
||||
if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
}
|
||||
#ifndef _PR_USE_POLL
|
||||
if (how == PR_POLL_READ) {
|
||||
if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
|
||||
|
||||
} else if (how == PR_POLL_WRITE) {
|
||||
if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
|
||||
} else {
|
||||
if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0)
|
||||
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
|
||||
}
|
||||
#endif /* _PR_USE_POLL */
|
||||
PR_ASSERT(pq.npds == 1);
|
||||
_PR_IOQ_OSFD_CNT(me->cpu) -= 1;
|
||||
}
|
||||
_PR_MD_IOQ_UNLOCK();
|
||||
rv = 0;
|
||||
|
@ -3238,3 +3536,140 @@ PRStatus _MD_CloseFileMap(PRFileMap *fmap)
|
|||
PR_DELETE(fmap);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(_PR_NEED_FAKE_POLL)
|
||||
|
||||
/*
|
||||
* Some platforms don't have poll(). For easier porting of code
|
||||
* that calls poll(), we emulate poll() using select().
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
|
||||
{
|
||||
int i;
|
||||
int rv;
|
||||
int maxfd;
|
||||
fd_set rd, wr, ex;
|
||||
struct timeval tv, *tvp;
|
||||
|
||||
if (timeout < 0 && timeout != -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
tvp = NULL;
|
||||
} else {
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
maxfd = -1;
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&ex);
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
int osfd = filedes[i].fd;
|
||||
int events = filedes[i].events;
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
if (osfd < 0) {
|
||||
continue; /* Skip this osfd. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the native poll flags to nspr poll flags.
|
||||
* POLLIN, POLLRDNORM ===> PR_POLL_READ
|
||||
* POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
|
||||
* POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
|
||||
* POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
|
||||
* are ignored.
|
||||
*
|
||||
* The output events POLLERR and POLLHUP are never turned on.
|
||||
* POLLNVAL may be turned on.
|
||||
*/
|
||||
|
||||
if (events & (POLLIN | POLLRDNORM)) {
|
||||
FD_SET(osfd, &rd);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLOUT | POLLWRNORM)) {
|
||||
FD_SET(osfd, &wr);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (events & (POLLPRI | POLLRDBAND)) {
|
||||
FD_SET(osfd, &ex);
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent && osfd > maxfd) {
|
||||
maxfd = osfd;
|
||||
}
|
||||
}
|
||||
|
||||
rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
|
||||
|
||||
/* Compute poll results */
|
||||
if (rv > 0) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
PRBool fdHasEvent = PR_FALSE;
|
||||
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &rd)) {
|
||||
if (filedes[i].events & POLLIN) {
|
||||
filedes[i].revents |= POLLIN;
|
||||
}
|
||||
if (filedes[i].events & POLLRDNORM) {
|
||||
filedes[i].revents |= POLLRDNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &wr)) {
|
||||
if (filedes[i].events & POLLOUT) {
|
||||
filedes[i].revents |= POLLOUT;
|
||||
}
|
||||
if (filedes[i].events & POLLWRNORM) {
|
||||
filedes[i].revents |= POLLWRNORM;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (FD_ISSET(filedes[i].fd, &ex)) {
|
||||
if (filedes[i].events & POLLPRI) {
|
||||
filedes[i].revents |= POLLPRI;
|
||||
}
|
||||
if (filedes[i].events & POLLRDBAND) {
|
||||
filedes[i].revents |= POLLRDBAND;
|
||||
}
|
||||
fdHasEvent = PR_TRUE;
|
||||
}
|
||||
if (fdHasEvent) {
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
} else if (rv == -1 && errno == EBADF) {
|
||||
rv = 0;
|
||||
for (i = 0; i < nfds; i++) {
|
||||
filedes[i].revents = 0;
|
||||
if (filedes[i].fd < 0) {
|
||||
continue;
|
||||
}
|
||||
if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
|
||||
filedes[i].revents = POLLNVAL;
|
||||
rv++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(rv > 0);
|
||||
}
|
||||
PR_ASSERT(-1 != timeout || rv != 0);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif /* _PR_NEED_FAKE_POLL */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "prerror.h"
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
|
||||
void _MD_win32_map_opendir_error(PRInt32 err)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++ = '.';
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -48,16 +48,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "process.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#elif defined(_PR_PTHREADS)
|
||||
/*
|
||||
* XXX: On Linux 2.0.27 (installed on tioman.mcom.com), sched.h uses
|
||||
* this _P macro that seems to be undefined. I suspect that it is
|
||||
* a typo (should be __P).
|
||||
*/
|
||||
#if defined(LINUX)
|
||||
#define _P(x) __P(x)
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include "md/_pth.h"
|
||||
#elif defined(IRIX)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -24,10 +24,18 @@
|
|||
#include "prlog.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include "plgetopt.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static PRInt32 Random(void)
|
||||
{
|
||||
PRInt32 ran = rand() >> 16;
|
||||
return ran;
|
||||
} /* Random */
|
||||
|
||||
static void Help(void)
|
||||
{
|
||||
PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
|
||||
|
@ -43,15 +51,19 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
|
|||
PRIntn index, nl;
|
||||
PRLock *ml = NULL;
|
||||
PRCondVar **cv = NULL;
|
||||
PRIntn loops = 1, cvs = 10;
|
||||
PRBool stats = PR_FALSE;
|
||||
PRIntn nc, loops = 1, cvs = 10;
|
||||
PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:");
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:");
|
||||
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
{
|
||||
if (PL_OPT_BAD == os) continue;
|
||||
switch (opt->option)
|
||||
{
|
||||
case 's': /* number of CVs to association with lock */
|
||||
stats = PR_TRUE;
|
||||
break;
|
||||
case 'c': /* number of CVs to association with lock */
|
||||
cvs = atoi(opt->value);
|
||||
break;
|
||||
|
@ -86,7 +98,12 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
|
|||
{
|
||||
PR_Lock(ml);
|
||||
for (nl = 0; nl < cvs; ++nl)
|
||||
PR_NotifyCondVar(cv[nl]);
|
||||
{
|
||||
PRInt32 ran = Random() % 8;
|
||||
if (0 == ran) PR_NotifyAllCondVar(cv[nl]);
|
||||
else for (nc = 0; nc < ran; ++nc)
|
||||
PR_NotifyCondVar(cv[nl]);
|
||||
}
|
||||
PR_Unlock(ml);
|
||||
}
|
||||
|
||||
|
@ -97,6 +114,9 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
|
|||
|
||||
printf("PASS\n");
|
||||
|
||||
#if defined(DEBUG) && defined(_PR_PTHREADS)
|
||||
PT_FPrintStats(err, "\nPThread Statistics\n");
|
||||
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
* Purpose: testing priorities
|
||||
*/
|
||||
|
||||
#ifdef XP_MAC
|
||||
#error "This test does not run on Macintosh"
|
||||
#else
|
||||
|
||||
|
||||
#include "prcmon.h"
|
||||
#include "prinit.h"
|
||||
#include "prinrval.h"
|
||||
|
@ -37,22 +42,12 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "prlog.h"
|
||||
unsigned int PR_fprintf(PRFileDesc *fd, const char *fmt, ...)
|
||||
{
|
||||
PR_LogPrint(fmt);
|
||||
return 0;
|
||||
}
|
||||
#define printf PR_LogPrint
|
||||
extern void SetupMacPrintfLog(char *logFile);
|
||||
#endif
|
||||
|
||||
#define DEFAULT_DURATION 20
|
||||
|
||||
static PRBool failed = PR_FALSE;
|
||||
static PRIntervalTime oneSecond;
|
||||
static PRFileDesc *debug_out = NULL;
|
||||
static PRBool debug_mode = PR_FALSE;
|
||||
|
||||
static PRUint32 PerSecond(PRIntervalTime timein)
|
||||
{
|
||||
|
@ -96,22 +91,63 @@ static void Help(void)
|
|||
debug_out, "-d\tturn on debugging output (default: FALSE)\n");
|
||||
} /* Help */
|
||||
|
||||
static void RudimentaryTests(void)
|
||||
{
|
||||
/*
|
||||
** Try some rudimentary tests like setting valid priority and
|
||||
** getting it back, or setting invalid priorities and getting
|
||||
** back a valid answer.
|
||||
*/
|
||||
PRThreadPriority priority;
|
||||
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_URGENT != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
|
||||
}
|
||||
|
||||
|
||||
PR_SetThreadPriority(
|
||||
PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_FIRST != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
|
||||
}
|
||||
|
||||
PR_SetThreadPriority(
|
||||
PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_LAST != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
|
||||
}
|
||||
|
||||
} /* RudimentataryTests */
|
||||
|
||||
static void CreateThreads(PRInt32 *lowCount, PRInt32 *highCount)
|
||||
{
|
||||
(void)PR_CreateThread(
|
||||
PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
(void)PR_CreateThread(
|
||||
PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
} /* CreateThreads */
|
||||
|
||||
PRIntn main(PRIntn argc, char **argv)
|
||||
{
|
||||
PLOptStatus os;
|
||||
PRThread *low, *high;
|
||||
PRThreadPriority priority;
|
||||
PRBool debug_mode = PR_FALSE;
|
||||
PRIntn duration = DEFAULT_DURATION;
|
||||
PRUint32 totalCount, highCount = 0, lowCount = 0;
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
SetupMacPrintfLog("priotest.log");
|
||||
debug_mode = PR_TRUE;
|
||||
#endif
|
||||
|
||||
debug_out = PR_STDOUT;
|
||||
oneSecond = PR_SecondsToInterval(1);
|
||||
|
||||
|
@ -137,53 +173,13 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
|
||||
if (duration == 0) duration = DEFAULT_DURATION;
|
||||
|
||||
RudimentaryTests();
|
||||
|
||||
printf("Priority test: running for %d seconds\n\n", duration);
|
||||
|
||||
(void)PerSecond(PR_IntervalNow());
|
||||
totalCount = PerSecond(PR_IntervalNow());
|
||||
|
||||
/*
|
||||
** Try some rudimentary tests like setting valid priority and
|
||||
** getting it back, or setting invalid priorities and getting
|
||||
** back a valid answer.
|
||||
*/
|
||||
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_URGENT != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
|
||||
}
|
||||
|
||||
/*
|
||||
The following test is bogus. PRThreadPriority is enum and (PR_PRIORITY_FIRST - 1)
|
||||
evaluates to 255 (at least on Mac). This causes the pinning test in PR_SetThreadPriority
|
||||
to fail. That test in PR_SetThreadPriority should be looked at.
|
||||
*/
|
||||
#if 0
|
||||
PR_SetThreadPriority(
|
||||
PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_FIRST != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_SetThreadPriority(
|
||||
PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
|
||||
priority = PR_GetThreadPriority(PR_GetCurrentThread());
|
||||
failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
|
||||
? PR_TRUE : PR_FALSE;
|
||||
if (debug_mode && (PR_PRIORITY_LAST != priority))
|
||||
{
|
||||
PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
|
||||
}
|
||||
|
||||
|
||||
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
|
||||
|
||||
if (debug_mode)
|
||||
|
@ -195,27 +191,8 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount);
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
if (debug_mode)
|
||||
{
|
||||
PR_fprintf(debug_out,
|
||||
"On Mac, this test should hang indefinitely \n");
|
||||
PR_fprintf( debug_out,
|
||||
"because low priority task never gives up time \n");
|
||||
PR_fprintf( debug_out, "and the program will hang there.\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
low = PR_CreateThread(
|
||||
PR_USER_THREAD, Low, &lowCount, PR_PRIORITY_LOW,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
|
||||
high = PR_CreateThread(
|
||||
PR_USER_THREAD, High, &highCount, PR_PRIORITY_HIGH,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
|
||||
duration = (duration + 4) / 5;
|
||||
CreateThreads(&lowCount, &highCount);
|
||||
while (duration--)
|
||||
{
|
||||
PRIntn loop = 5;
|
||||
|
@ -224,11 +201,14 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
|
||||
}
|
||||
|
||||
|
||||
PR_ProcessExit((failed) ? 1 : 0);
|
||||
|
||||
PR_ASSERT(!"Can't get here");
|
||||
PR_ASSERT(!"You can't get here -- but you did!");
|
||||
return 1; /* or here */
|
||||
|
||||
} /* main */
|
||||
|
||||
#endif /* ifdef XP_MAC */
|
||||
|
||||
/* priotest.c */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
PRIntn failed_already=0;
|
||||
PRIntn debug_mode;
|
||||
|
||||
|
@ -63,9 +64,9 @@ clientThreadFunc(void *arg)
|
|||
char buf[128];
|
||||
int i;
|
||||
|
||||
addr.inet.family = AF_INET;
|
||||
addr.inet.family = PR_AF_INET;
|
||||
addr.inet.port = PR_htons((PRUint16)port);
|
||||
addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
|
||||
addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
|
||||
PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
|
@ -127,8 +128,8 @@ int main(int argc, char **argv)
|
|||
failed_already=1;
|
||||
goto exit_now;
|
||||
}
|
||||
addr.inet.family = AF_INET;
|
||||
addr.inet.ip = PR_htonl(INADDR_ANY);
|
||||
addr.inet.family = PR_AF_INET;
|
||||
addr.inet.ip = PR_htonl(PR_INADDR_ANY);
|
||||
addr.inet.port = PR_htons(0);
|
||||
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
|
||||
fprintf(stderr, "Can't bind socket\n");
|
||||
|
@ -152,8 +153,8 @@ int main(int argc, char **argv)
|
|||
failed_already=1;
|
||||
goto exit_now;
|
||||
}
|
||||
addr.inet.family = AF_INET;
|
||||
addr.inet.ip = PR_htonl(INADDR_ANY);
|
||||
addr.inet.family = PR_AF_INET;
|
||||
addr.inet.ip = PR_htonl(PR_INADDR_ANY);
|
||||
addr.inet.port = PR_htons(0);
|
||||
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
|
||||
fprintf(stderr, "Can't bind socket\n");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче