Merged NSPRPUB_19980421_BRANCH to the main trunk.

This commit is contained in:
wtc 1998-04-28 22:43:48 +00:00
Родитель e6dc748005
Коммит 74f75ec4ba
109 изменённых файлов: 2498 добавлений и 2527 удалений

Просмотреть файл

@ -15,9 +15,6 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights * Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved. * Reserved.
*/ */
#if defined(WIN16)
#include <windows.h>
#endif
#include "plevent.h" #include "plevent.h"
#include "prmem.h" #include "prmem.h"
#include "prcmon.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 "prthread.h"
#include "prmon.h" #include "prmon.h"
/* For HWND */
#ifdef _WIN32
#include <windef.h>
#elif defined(WIN16)
#include <windows.h>
#endif
PR_BEGIN_EXTERN_C PR_BEGIN_EXTERN_C
/* Typedefs */ /* Typedefs */

Просмотреть файл

@ -21,6 +21,11 @@
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>
#ifdef WIN32
#include <windef.h>
#include <winbase.h>
#endif
#include "prclist.h" #include "prclist.h"
#include "prbit.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) static void DumpApplicationHeap(FILE *out, HANDLE heap)
{ {
PROCESS_HEAP_ENTRY entry; PROCESS_HEAP_ENTRY entry;

Просмотреть файл

@ -21,9 +21,7 @@
*/ */
#include "prstrms.h" #include "prstrms.h"
#ifdef SVR4
#include <string.h> // memmove #include <string.h> // memmove
#endif
// //
// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C. // Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.

Просмотреть файл

@ -38,14 +38,14 @@
*/ */
#define PR_LINKER_ARCH "aix" #define PR_LINKER_ARCH "aix"
#define _PR_SI_SYSNAME "AIX" #define _PR_SI_SYSNAME "AIX"
#define _PR_SI_ARCHITECTURE "rs6000" #define _PR_SI_ARCHITECTURE "rs6000"
#define PR_DLL_SUFFIX ".so" #define PR_DLL_SUFFIX ".so"
#define _PR_VMBASE 0x30000000 #define _PR_VMBASE 0x30000000
#define _PR_STACK_VMBASE 0x50000000 #define _PR_STACK_VMBASE 0x50000000
#define _MD_DEFAULT_STACK_SIZE 65536L #define _MD_DEFAULT_STACK_SIZE 65536L
#define _MD_MMAP_FLAGS MAP_PRIVATE #define _MD_MMAP_FLAGS MAP_PRIVATE
#define NEED_TIME_R #define NEED_TIME_R
#undef HAVE_STACK_GROWING_UP #undef HAVE_STACK_GROWING_UP
@ -53,11 +53,18 @@
#undef HAVE_WEAK_MALLOC_SYMBOLS #undef HAVE_WEAK_MALLOC_SYMBOLS
#define HAVE_DLL #define HAVE_DLL
#define USE_DLFCN #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 /* The atomic operations */
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond #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 #define USE_SETJMP

Просмотреть файл

@ -36,6 +36,7 @@
#undef HAVE_STACK_GROWING_UP #undef HAVE_STACK_GROWING_UP
#define HAVE_DLL #define HAVE_DLL
#define USE_DLFCN #define USE_DLFCN
#define _PR_HAVE_SOCKADDR_LEN
#define USE_SETJMP #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) #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 /* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't
want to be including that.. */ want to be including that.. */
#ifndef INADDR_LOOPBACK #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_ATTACH_THREAD(threadp)
#define _MD_SAVE_ERRNO(_thread) #define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno;
#define _MD_RESTORE_ERRNO(_thread) #define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode;
extern struct _PRCPU *_pr_primordialCPU; extern struct _PRCPU *_pr_primordialCPU;
extern usema_t *_pr_irix_exit_sem; extern usema_t *_pr_irix_exit_sem;
@ -216,6 +216,9 @@ struct _MDThread {
PRInt32 id; PRInt32 id;
PRInt32 suspending_id; PRInt32 suspending_id;
int errcode; int errcode;
PRStatus *creation_status; /* points to the variable in which
* a newly created child thread is
* to store its creation status */
}; };
struct _MDThreadStack { struct _MDThreadStack {

Просмотреть файл

@ -56,14 +56,10 @@
#undef USE_DLFCN #undef USE_DLFCN
#endif #endif
#if !defined(MACLINUX) && !defined(NEED_TIME_R) #if !defined(MKLINUX) && !defined(NEED_TIME_R)
#define NEED_TIME_R #define NEED_TIME_R
#endif #endif
#if defined(_PR_PTHREADS) && !(defined(__GLIBC__) && __GLIBC__ >= 2)
#define _PR_NEED_FAKE_POLL
#endif
#define USE_SETJMP #define USE_SETJMP
#ifdef _PR_PTHREADS #ifdef _PR_PTHREADS
@ -250,40 +246,12 @@ extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
*/ */
#define _MD_SELECT __select #define _MD_SELECT __select
#if defined(_PR_NEED_FAKE_POLL) #ifdef _PR_POLL_AVAILABLE
#include <poll.h>
/* extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
* XXX: Linux doesn't have poll(), but our pthreads code calls poll(). int timeout);
* As a temporary measure, I implemented a fake poll() using select(). #define _MD_POLL __syscall_poll
* Here are the struct and macro definitions copied from sys/poll.h #endif
* 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 */
/* For writev() */ /* For writev() */
#include <sys/uio.h> #include <sys/uio.h>

Просмотреть файл

@ -330,11 +330,11 @@ typedef enum IOOperation {
#define _MD_DELETE _MD_Delete #define _MD_DELETE _MD_Delete
PR_EXTERN(PRStatus) _MD_LockFile(PRInt32 osfd); extern PRStatus _MD_LockFile(PRInt32 osfd);
#define _MD_LOCKFILE _MD_LockFile #define _MD_LOCKFILE _MD_LockFile
PR_EXTERN(PRStatus) _MD_TLockFile(PRInt32 osfd); extern PRStatus _MD_TLockFile(PRInt32 osfd);
#define _MD_TLOCKFILE _MD_TLockFile #define _MD_TLOCKFILE _MD_TLockFile
PR_EXTERN(PRStatus) _MD_UnlockFile(PRInt32 osfd); extern PRStatus _MD_UnlockFile(PRInt32 osfd);
#define _MD_UNLOCKFILE _MD_UnlockFile #define _MD_UNLOCKFILE _MD_UnlockFile
/* /*
@ -384,7 +384,7 @@ extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, c
/* /*
** Netdb Related definitions ** 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 #define _MD_GETHOSTNAME _MD_gethostname
/* /*

Просмотреть файл

@ -71,6 +71,7 @@
#define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_DOUBLE 4
#define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_POINTER 4
#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL #define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT #ifndef NO_NSPR_10_SUPPORT

Просмотреть файл

@ -76,6 +76,9 @@
#define PR_ALIGN_OF_DWORD 8 #define PR_ALIGN_OF_DWORD 8
#define PR_ALIGN_OF_POINTER 4 #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 #ifndef NO_NSPR_10_SUPPORT
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE #define BYTES_PER_BYTE PR_BYTES_PER_BYTE

Просмотреть файл

@ -23,7 +23,9 @@
#define INCL_DOSERRORS #define INCL_DOSERRORS
#define INCL_WIN #define INCL_WIN
#define INCL_WPS #define INCL_WPS
#define TID OS2TID /* global rename in OS2 H's! */
#include <os2.h> #include <os2.h>
#undef TID /* and restore */
#include <sys/select.h> #include <sys/select.h>
#include "prio.h" #include "prio.h"
@ -42,7 +44,11 @@
#undef HAVE_THREAD_AFFINITY #undef HAVE_THREAD_AFFINITY
#define HAVE_SOCKET_REUSEADDR #define HAVE_SOCKET_REUSEADDR
#define HAVE_SOCKET_KEEPALIVE #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 HANDLE unsigned long
#define HINSTANCE HMODULE #define HINSTANCE HMODULE
@ -59,6 +65,7 @@ typedef void (*FiberFunc)(void *);
typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS];
#define GC_VMBASE 0x40000000 #define GC_VMBASE 0x40000000
#define GC_VMLIMIT 0x00FFFFFF #define GC_VMLIMIT 0x00FFFFFF
typedef int (*FARPROC)();
#define _MD_MAGIC_THREAD 0x22222222 #define _MD_MAGIC_THREAD 0x22222222
#define _MD_MAGIC_THREADSTACK 0x33333333 #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_DIR 0x55555555
#define _MD_MAGIC_CV 0x66666666 #define _MD_MAGIC_CV 0x66666666
#define CALLBACK
typedef struct _MDSemaphore typedef struct _MDSemaphore
{ {
HEV sem; HEV sem;
@ -82,7 +91,7 @@ struct _MDThread {
PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the
* wait queue of some cond var. * wait queue of some cond var.
* PR_FALSE otherwise. */ * PR_FALSE otherwise. */
TID handle; /* OS/2 thread handle */ OS2TID handle; /* OS/2 thread handle */
void *sp; /* only valid when suspended */ void *sp; /* only valid when suspended */
PRUint32 magic; /* for debugging */ PRUint32 magic; /* for debugging */
PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ PR_CONTEXT_TYPE gcContext; /* Thread context for GC */
@ -133,7 +142,7 @@ struct _MDNotified {
}; };
struct _MDLock { 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 * 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 #define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE
/* --- Socket IO stuff --- */ /* --- 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_EACCES EACCES
#define _MD_EADDRINUSE EADDRINUSE #define _MD_EADDRINUSE EADDRINUSE
#define _MD_EADDRNOTAVAIL EADDRNOTAVAIL #define _MD_EADDRNOTAVAIL EADDRNOTAVAIL
@ -230,14 +243,10 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
#define _MD_SELECT select #define _MD_SELECT select
#define _MD_FSYNC _PR_MD_FSYNC #define _MD_FSYNC _PR_MD_FSYNC
long _System InterlockedIncrement(PLONG); #define _MD_INIT_ATOMIC _PR_MD_INIT_ATOMIC
long _System InterlockedDecrement(PLONG); #define _MD_ATOMIC_INCREMENT(x) _PR_MD_ATOMIC_INCREMENT(x)
long _System InterlockedExchange(PLONG, LONG); #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_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_IO _PR_MD_INIT_IO #define _MD_INIT_IO _PR_MD_INIT_IO
#define _MD_TRANSMITFILE _PR_MD_TRANSMITFILE #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_LOCK _MD_LOCK
#define _PR_UNLOCK _MD_UNLOCK #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_NEW_LOCK(lock) (DosCreateMutexSem(0, &((lock)->mutex), 0, 0),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex)) #define _MD_FREE_LOCK(lock) DosCloseMutexSem(((lock)->mutex))
#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex)) #define _MD_LOCK(lock) DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT)
#define _MD_TEST_AND_LOCK(lock) (EnterCriticalSection(&((lock)->mutex)),PR_SUCCESS) #define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT),PR_SUCCESS)
#define _MD_UNLOCK _PR_MD_UNLOCK #define _MD_UNLOCK _PR_MD_UNLOCK
/* --- lock and cv waiting --- */ /* --- lock and cv waiting --- */
@ -376,8 +385,8 @@ extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
typedef struct __NSPR_TLS typedef struct __NSPR_TLS
{ {
PRThread *_pr_thread_last_run; struct PRThread *_pr_thread_last_run;
PRThread *_pr_currentThread; struct PRThread *_pr_currentThread;
struct _PRCPU *_pr_currentCPU; struct _PRCPU *_pr_currentCPU;
} _NSPR_TLS; } _NSPR_TLS;
@ -431,7 +440,10 @@ extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
/* Some stuff for setting up thread contexts */ /* 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. /* The following definitions and two structures are new in OS/2 Warp 4.0.
*/ */
@ -472,7 +484,7 @@ typedef struct _CONTEXTRECORD {
#pragma pack() #pragma pack()
#endif #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) #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. * not emulating anything. Just mapping.
*/ */
#define FreeLibrary(x) DosFreeModule(x) #define FreeLibrary(x) DosFreeModule(x)
#define OutputDebugString(str) ;
#endif /* nspr_os2_defs_h___ */ #endif /* nspr_os2_defs_h___ */

Просмотреть файл

@ -20,7 +20,9 @@
#define nspr_os2_errors_h___ #define nspr_os2_errors_h___
#include "md/_os2.h" #include "md/_os2.h"
#include <assert.h> #ifndef assert
#include <assert.h>
#endif
#include <nerrno.h> #include <nerrno.h>
PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err); PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err);

Просмотреть файл

@ -75,6 +75,7 @@
#define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_DOUBLE 8
#define PR_ALIGN_OF_POINTER 8 #define PR_ALIGN_OF_POINTER 8
#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL #define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT #ifndef NO_NSPR_10_SUPPORT

Просмотреть файл

@ -69,15 +69,17 @@ typedef int PROSFD;
/* /*
** Undo the macro define in the Microsoft header files... ** 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 #ifdef _stat
#undef _stat #undef _stat
#endif #endif
#endif
#ifdef OS2 #ifdef OS2
PR_EXTERN(PRStatus) _MD_OS2GetHostName(char *name, PRUint32 namelen); extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_OS2GetHostName #define _MD_GETHOSTNAME _MD_OS2GetHostName
#else #else
PR_EXTERN(PRStatus) _MD_WindowsGetHostName(char *name, PRUint32 namelen); extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_WindowsGetHostName #define _MD_GETHOSTNAME _MD_WindowsGetHostName
#endif #endif

Просмотреть файл

@ -194,10 +194,13 @@ PR_EXTERN(PRIntn) pt_hpux_privcheck(void);
/* Needed for garbage collection -- Look at PR_Suspend/PR_Resume implementation */ /* Needed for garbage collection -- Look at PR_Suspend/PR_Resume implementation */
#if defined(OSF1) #if defined(OSF1)
#define PTHREAD_YIELD() pthread_yield_np() #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() #define PTHREAD_YIELD() sched_yield()
#elif (defined(AIX) && !defined(AIX4_3)) || defined(HPUX) #elif defined(HPUX)
#define PTHREAD_YIELD() pthread_yield() #define PTHREAD_YIELD() pthread_yield()
#elif defined(AIX)
extern int (*_PT_aix_yield_fcn)();
#define PTHREAD_YIELD() (*_PT_aix_yield_fcn)()
#elif defined(IRIX) #elif defined(IRIX)
#include <time.h> #include <time.h>
#define PTHREAD_YIELD() \ #define PTHREAD_YIELD() \

Просмотреть файл

@ -76,6 +76,7 @@
#define PR_ALIGN_OF_DOUBLE 8 #define PR_ALIGN_OF_DOUBLE 8
#define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_POINTER 4
#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL #define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT #ifndef NO_NSPR_10_SUPPORT

Просмотреть файл

@ -71,6 +71,7 @@
#define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_DOUBLE 4
#define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_POINTER 4
#define _PR_POLL_AVAILABLE
#define _PR_USE_POLL #define _PR_USE_POLL
#ifndef NO_NSPR_10_SUPPORT #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); PR_EXTERN(void) _MD_unix_map_select_error(int err);
#define _PR_MD_MAP_SELECT_ERROR _MD_unix_map_select_error #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); PR_EXTERN(void) _MD_unix_map_flock_error(int err);
#define _PR_MD_MAP_FLOCK_ERROR _MD_unix_map_flock_error #define _PR_MD_MAP_FLOCK_ERROR _MD_unix_map_flock_error

Просмотреть файл

@ -118,11 +118,17 @@ struct _MDDir {
struct _MDCPU_Unix { struct _MDCPU_Unix {
PRCList ioQ; 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; 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], PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
fd_exception_cnt[_PR_MD_MAX_OSFD]; fd_exception_cnt[_PR_MD_MAX_OSFD];
PRUint32 ioq_timeout; #else
PRInt32 ioq_max_osfd; struct pollfd *ioq_pollfds;
int ioq_pollfds_size;
#endif /* _PR_USE_POLL */
}; };
struct _PRCPU; struct _PRCPU;
extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu); 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_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_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout)
#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) #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); extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap #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___ */ #endif /* prunixos_h___ */

Просмотреть файл

@ -72,6 +72,7 @@
#define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_POINTER 4
#define _PR_USE_POLL #define _PR_USE_POLL
#define _PR_POLL_AVAILABLE
#ifndef NO_NSPR_10_SUPPORT #ifndef NO_NSPR_10_SUPPORT

Просмотреть файл

@ -24,109 +24,109 @@
#include <errno.h> #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #define _PR_MD_MAP_LOCKF_ERROR _MD_win32_map_lockf_error
#endif /* nspr_win32_errors_h___ */ #endif /* nspr_win32_errors_h___ */

Просмотреть файл

@ -169,10 +169,13 @@ struct _MDProcess {
#define _MD_WRITE _PR_MD_WRITE #define _MD_WRITE _PR_MD_WRITE
#define _MD_WRITEV _PR_MD_WRITEV #define _MD_WRITEV _PR_MD_WRITEV
#define _MD_LSEEK _PR_MD_LSEEK #define _MD_LSEEK _PR_MD_LSEEK
#define _MD_LSEEK64 _PR_MD_LSEEK64
extern PRInt32 _MD_CloseFile(PRInt32 osfd); extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#define _MD_CLOSE_FILE _MD_CloseFile #define _MD_CLOSE_FILE _MD_CloseFile
#define _MD_GETFILEINFO _PR_MD_GETFILEINFO #define _MD_GETFILEINFO _PR_MD_GETFILEINFO
#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64
#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO #define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO
#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64
#define _MD_STAT _PR_MD_STAT #define _MD_STAT _PR_MD_STAT
#define _MD_RENAME _PR_MD_RENAME #define _MD_RENAME _PR_MD_RENAME
#define _MD_ACCESS _PR_MD_ACCESS #define _MD_ACCESS _PR_MD_ACCESS
@ -224,8 +227,13 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
#define _MD_FSYNC _PR_MD_FSYNC #define _MD_FSYNC _PR_MD_FSYNC
#define _MD_INIT_ATOMIC() #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_INCREMENT(x) InterlockedIncrement((PLONG)x)
#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((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_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
#define _MD_INIT_IO _PR_MD_INIT_IO #define _MD_INIT_IO _PR_MD_INIT_IO
@ -363,6 +371,7 @@ extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
/* --- Native-Thread Specific Definitions ------------------------------- */ /* --- Native-Thread Specific Definitions ------------------------------- */
#ifdef _PR_USE_STATIC_TLS
extern __declspec(thread) struct PRThread *_pr_currentThread; extern __declspec(thread) struct PRThread *_pr_currentThread;
#define _MD_CURRENT_THREAD() _pr_currentThread #define _MD_CURRENT_THREAD() _pr_currentThread
#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) #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; extern __declspec(thread) struct _PRCPU *_pr_currentCPU;
#define _MD_CURRENT_CPU() _pr_currentCPU #define _MD_CURRENT_CPU() _pr_currentCPU
#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (0)) #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; // wtc. extern __declspec(thread) PRUintn _pr_ints_off;
// lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) // 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_WRITE _PR_MD_WRITE
#define _MD_WRITEV _PR_MD_WRITEV #define _MD_WRITEV _PR_MD_WRITEV
#define _MD_LSEEK _PR_MD_LSEEK #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_CLOSE_FILE(f) _PR_MD_CLOSE(f, PR_FALSE)
#define _MD_GETFILEINFO _PR_MD_GETFILEINFO #define _MD_GETFILEINFO _PR_MD_GETFILEINFO
#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64
#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO #define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO
#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64
#define _MD_STAT _PR_MD_STAT #define _MD_STAT _PR_MD_STAT
#define _MD_RENAME _PR_MD_RENAME #define _MD_RENAME _PR_MD_RENAME
#define _MD_ACCESS _PR_MD_ACCESS #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_SOCKETAVAILABLE _PR_MD_SOCKETAVAILABLE
#define _MD_INIT_ATOMIC() #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_INCREMENT(x) InterlockedIncrement((PLONG)x)
#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((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_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
#define _MD_INIT_IO _PR_MD_INIT_IO #define _MD_INIT_IO _PR_MD_INIT_IO

Просмотреть файл

@ -33,7 +33,7 @@ typedef PRUintn uint;
typedef PRUintn uintn; typedef PRUintn uintn;
typedef PRUint64 uint64; typedef PRUint64 uint64;
#if !defined(XP_MAC) && !defined(_WIN32) #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2)
typedef PRUint32 uint32; typedef PRUint32 uint32;
#else #else
typedef unsigned long uint32; typedef unsigned long uint32;
@ -59,7 +59,7 @@ typedef PRInt64 int64;
/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */ /* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
#if !defined(HPUX) || !defined(_MODEL_INCLUDED) #if !defined(HPUX) || !defined(_MODEL_INCLUDED)
#if !defined(WIN32) || !defined(_WINSOCK2API_) /* defines its own "int32" */ #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; typedef PRInt32 int32;
#else #else
typedef long int32; typedef long int32;

Просмотреть файл

@ -49,18 +49,19 @@ PR_EXTERN(PRIntn) PR_FloorLog2(PRUint32 i);
*/ */
#define PR_CEILING_LOG2(_log2,_n) \ #define PR_CEILING_LOG2(_log2,_n) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
PRUint32 j_ = (PRUint32)(_n); \
(_log2) = 0; \ (_log2) = 0; \
if ((_n) & ((_n)-1)) \ if ((j_) & ((j_)-1)) \
(_log2) += 1; \ (_log2) += 1; \
if ((_n) >> 16) \ if ((j_) >> 16) \
(_log2) += 16, (_n) >>= 16; \ (_log2) += 16, (j_) >>= 16; \
if ((_n) >> 8) \ if ((j_) >> 8) \
(_log2) += 8, (_n) >>= 8; \ (_log2) += 8, (j_) >>= 8; \
if ((_n) >> 4) \ if ((j_) >> 4) \
(_log2) += 4, (_n) >>= 4; \ (_log2) += 4, (j_) >>= 4; \
if ((_n) >> 2) \ if ((j_) >> 2) \
(_log2) += 2, (_n) >>= 2; \ (_log2) += 2, (j_) >>= 2; \
if ((_n) >> 1) \ if ((j_) >> 1) \
(_log2) += 1; \ (_log2) += 1; \
PR_END_MACRO PR_END_MACRO
@ -72,16 +73,17 @@ PR_EXTERN(PRIntn) PR_FloorLog2(PRUint32 i);
*/ */
#define PR_FLOOR_LOG2(_log2,_n) \ #define PR_FLOOR_LOG2(_log2,_n) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
PRUint32 j_ = (PRUint32)(_n); \
(_log2) = 0; \ (_log2) = 0; \
if ((_n) >> 16) \ if ((j_) >> 16) \
(_log2) += 16, (_n) >>= 16; \ (_log2) += 16, (j_) >>= 16; \
if ((_n) >> 8) \ if ((j_) >> 8) \
(_log2) += 8, (_n) >>= 8; \ (_log2) += 8, (j_) >>= 8; \
if ((_n) >> 4) \ if ((j_) >> 4) \
(_log2) += 4, (_n) >>= 4; \ (_log2) += 4, (j_) >>= 4; \
if ((_n) >> 2) \ if ((j_) >> 2) \
(_log2) += 2, (_n) >>= 2; \ (_log2) += 2, (j_) >>= 2; \
if ((_n) >> 1) \ if ((j_) >> 1) \
(_log2) += 1; \ (_log2) += 1; \
PR_END_MACRO 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 ** 0 ==> shortest string that yields d when read in
** and rounded to nearest. ** and rounded to nearest.
*/ */
PR_EXTERN(char *) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, PR_EXTERN(PRStatus) 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,
PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize); PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize);
PR_END_EXTERN_C PR_END_EXTERN_C

Просмотреть файл

@ -74,13 +74,7 @@
#elif defined(WIN32) #elif defined(WIN32)
/* /* Do not include any system header files. */
* 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>
#elif defined(WIN16) #elif defined(WIN16)

Просмотреть файл

@ -82,6 +82,36 @@ typedef enum PRTransmitFileFlags {
* is transmitted. */ * is transmitted. */
} PRTransmitFileFlags; } 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 ** A network address
@ -99,12 +129,6 @@ typedef enum PRTransmitFileFlags {
typedef struct in6_addr PRIPv6Addr; 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) */ #endif /* defined(_PR_INET6) */
union PRNetAddr { union PRNetAddr {
@ -120,14 +144,43 @@ union PRNetAddr {
} inet; } inet;
#if defined(_PR_INET6) #if defined(_PR_INET6)
struct { struct {
PRUint16 family; /* address family (AF_INET | AF_INET6) */ PRUint16 family; /* address family (AF_INET6) */
PRUint16 port; /* port number */ PRUint16 port; /* port number */
PRUint32 flowinfo; /* routing information */ PRUint32 flowinfo; /* routing information */
PRIPv6Addr ip; /* the actual 128 bits of address */ PRIPv6Addr ip; /* the actual 128 bits of address */
} ipv6; } ipv6;
#endif /* defined(_PR_INET6) */ #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 ** PRSockOption
@ -275,7 +328,7 @@ typedef PRInt32 (PR_CALLBACK *PRSendtoFN)(
PRFileDesc *fd, const void *buf, PRInt32 amount, PRFileDesc *fd, const void *buf, PRInt32 amount,
PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout); PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout);
typedef PRInt16 (PR_CALLBACK *PRPollFN)( typedef PRInt16 (PR_CALLBACK *PRPollFN)(
PRFileDesc *fd, PRInt16 how_flags); PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)( typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
void *buf, PRInt32 amount, PRIntervalTime t); 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 * that one recongizes and therefore predict that it will implement
* a desired protocol. * 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_TOP_IO_LAYER => the identity of the top of the stack
* PR_NSPR_IO_LAYER => the identity used by NSPR proper * PR_NSPR_IO_LAYER => the identity used by NSPR proper
* The latter may be used as a shorthand for identifying the topmost layer * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
* of an existing stack. Ie., the following two constructs are equivalent. * 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_TOP_IO_LAYER, my_layer);
* rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), 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. * 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( 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 ** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
** these together to produce the desired poll request. ** 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. ** 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> #include <poll.h>
#define PR_POLL_READ POLLIN #define PR_POLL_READ POLLIN
@ -1529,7 +1584,7 @@ struct PRPollDesc {
#define PR_POLL_ERR POLLERR /* only in out_flags */ #define PR_POLL_ERR POLLERR /* only in out_flags */
#define PR_POLL_NVAL POLLNVAL /* only in out_flags when fd is bad */ #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_READ 0x1
#define PR_POLL_WRITE 0x2 #define PR_POLL_WRITE 0x2
@ -1537,7 +1592,7 @@ struct PRPollDesc {
#define PR_POLL_ERR 0x8 /* only in out_flags */ #define PR_POLL_ERR 0x8 /* only in out_flags */
#define PR_POLL_NVAL 0x10 /* only in out_flags when fd is bad */ #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 */ /* Return the method tables for files, tcp sockets and udp sockets */
PR_EXTERN(PRIOMethods*) PR_GetFileMethods(void); PR_EXTERN(const PRIOMethods*) PR_GetFileMethods(void);
PR_EXTERN(PRIOMethods*) PR_GetTCPMethods(void); PR_EXTERN(const PRIOMethods*) PR_GetTCPMethods(void);
PR_EXTERN(PRIOMethods*) PR_GetUDPMethods(void); PR_EXTERN(const PRIOMethods*) PR_GetUDPMethods(void);
/* /*
** Convert a NSPR Socket Handle to a Native Socket handle. ** 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(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *);
PR_EXTERN(void) PR_ChangeFileDescNativeHandle(PRFileDesc *, PRInt32); 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); PR_EXTERN(void) PR_FreeFileDesc(PRFileDesc *fd);
/* /*
** Import an existing OS file to NSPR. ** 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_ImportTCPSocket(PRInt32 osfd);
PR_EXTERN(PRFileDesc*) PR_ImportUDPSocket(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. ** Create a new Socket; this function is obsolete.
*/ */

Просмотреть файл

@ -28,14 +28,6 @@
*/ */
#if defined(_PR_PTHREADS) #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> #include <pthread.h>
#endif #endif
@ -191,9 +183,14 @@ typedef struct PTDebug
PRUintn continuationsServed; PRUintn continuationsServed;
PRUintn recyclesNeeded; PRUintn recyclesNeeded;
PRUintn quiescentIO; PRUintn quiescentIO;
PRUintn locks_created, locks_destroyed;
PRUintn locks_acquired, locks_released;
PRUintn cvars_created, cvars_destroyed;
PRUintn cvars_notified, delayed_cv_deletes;
} PTDebug; } PTDebug;
PR_EXTERN(PTDebug) PT_GetStats(void); PR_EXTERN(PTDebug) PT_GetStats(void);
PR_EXTERN(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
#endif /* defined(DEBUG) */ #endif /* defined(DEBUG) */
@ -524,7 +521,7 @@ extern _PRInterruptTable _pr_interruptTable[];
#define _PR_MISSED_IO 0x2 #define _PR_MISSED_IO 0x2
#define _PR_MISSED_CHILD 0x4 #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_WakeupCPU(void);
PR_EXTERN(void) _PR_PauseCPU(void); PR_EXTERN(void) _PR_PauseCPU(void);
@ -536,7 +533,7 @@ PR_EXTERN(void) _PR_PauseCPU(void);
#define _PR_LOCK_UNLOCK(_lock) \ #define _PR_LOCK_UNLOCK(_lock) \
_PR_MD_UNLOCK(&(_lock)->ilock); _PR_MD_UNLOCK(&(_lock)->ilock);
PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock); extern PRThread * _PR_AssignLock(PRLock *lock);
#define _PR_LOCK_PTR(_qp) \ #define _PR_LOCK_PTR(_qp) \
((PRLock*) ((char*) (_qp) - offsetof(PRLock,links))) ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
@ -548,9 +545,9 @@ PR_EXTERN(PRThread *) _PR_AssignLock(PRLock *lock);
#define _PR_CVAR_UNLOCK(_cvar) \ #define _PR_CVAR_UNLOCK(_cvar) \
_PR_MD_UNLOCK(&(_cvar)->ilock); _PR_MD_UNLOCK(&(_cvar)->ilock);
PR_EXTERN(PRStatus) _PR_WaitCondVar( extern PRStatus _PR_WaitCondVar(
PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); 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); PR_EXTERN(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
@ -689,20 +686,20 @@ extern PRLock *_pr_terminationCVLock;
* code. * * code. *
*************************************************************************/ *************************************************************************/
PR_EXTERN(void) _PR_ClockInterrupt(void); extern void _PR_ClockInterrupt(void);
PR_EXTERN(void) _PR_Schedule(void); extern void _PR_Schedule(void);
PR_EXTERN(void) _PR_SetThreadPriority( extern void _PR_SetThreadPriority(
PRThread* thread, PRThreadPriority priority); PRThread* thread, PRThreadPriority priority);
PR_EXTERN(void) _PR_Unlock(PRLock *lock); PR_EXTERN(void) _PR_Unlock(PRLock *lock);
PR_EXTERN(void) _PR_SuspendThread(PRThread *t); PR_EXTERN(void) _PR_SuspendThread(PRThread *t);
PR_EXTERN(void) _PR_ResumeThread(PRThread *t); PR_EXTERN(void) _PR_ResumeThread(PRThread *t);
PR_EXTERN(PRThreadStack *)_PR_NewStack(PRUint32 stackSize); extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
PR_EXTERN(void) _PR_FreeStack(PRThreadStack *stack); extern void _PR_FreeStack(PRThreadStack *stack);
PR_EXTERN(PRBool) NotifyThread (PRThread *thread, PRThread *me); extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
PR_EXTERN(void) _PR_NotifyLockedThread (PRThread *thread); extern void _PR_NotifyLockedThread (PRThread *thread);
PR_EXTERN(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout); PR_EXTERN(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
PR_EXTERN(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time); PR_EXTERN(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
@ -718,8 +715,8 @@ PR_EXTERN(PRThread*) _PR_CreateThread(PRThreadType type,
PRUint32 stackSize, PRUint32 stackSize,
PRUint32 flags); PRUint32 flags);
PR_EXTERN(void) _PR_NativeDestroyThread(PRThread *thread); extern void _PR_NativeDestroyThread(PRThread *thread);
PR_EXTERN(void) _PR_UserDestroyThread(PRThread *thread); extern void _PR_UserDestroyThread(PRThread *thread);
PR_EXTERN(PRThread*) _PRI_AttachThread( PR_EXTERN(PRThread*) _PRI_AttachThread(
PRThreadType type, PRThreadPriority priority, 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 /* 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. * 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 #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 #define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ #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; * 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 #define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
extern void _PR_MD_CLEANUP_BEFORE_EXIT(void); extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT #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 #define _PR_MD_EXIT _MD_EXIT
/* Locks related */ /* 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); PR_EXTERN(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_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 #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 #define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ #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); PR_EXTERN(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_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 #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 #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 #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 #define _PR_MD_RESUME_CPU _MD_RESUME_CPU
extern void _PR_MD_BEGIN_SUSPEND_ALL(void); 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 */ #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 #define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
#ifdef HAVE_CUSTOM_USER_THREADS #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 #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, PRUint32 stacksize,
void (*start)(void *), void (*start)(void *),
void *arg); void *arg);
#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD #define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
#endif #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 #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, PRThread *thread,
void (*start) (void *), void (*start) (void *),
PRThreadPriority priority, PRThreadPriority priority,
@ -944,10 +941,10 @@ PR_EXTERN(PRStatus) _PR_MD_CREATE_THREAD(
PRUint32 stackSize); PRUint32 stackSize);
#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD #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 #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 #define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
PR_EXTERN(void) _PR_MD_SUSPENDALL(void); 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); PR_EXTERN(void) _PR_MD_RESUMEALL(void);
#define _PR_MD_RESUMEALL _MD_RESUMEALL #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); PRThread *thread, char *top, void (*start) (void), PRBool *status);
#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT #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 #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 #define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
/* Directory enumeration related */ /* Directory enumeration related */
@ -1200,8 +1197,8 @@ PR_EXTERN(void) _PR_MD_INIT_LOCKS(void);
struct PRLock { struct PRLock {
#if defined(_PR_PTHREADS) #if defined(_PR_PTHREADS)
pthread_mutex_t mutex; /* the underlying lock */ pthread_mutex_t mutex; /* the underlying lock */
_PT_Notified notified; /* array of conditions notified */ _PT_Notified notified; /* array of conditions notified */
pthread_t owner; /* current lock owner */ pthread_t owner; /* current lock owner */
#else /* defined(_PR_PTHREADS) */ #else /* defined(_PR_PTHREADS) */
PRCList links; /* linkage for PRThread.lockList */ PRCList links; /* linkage for PRThread.lockList */
@ -1213,12 +1210,13 @@ struct PRLock {
#endif /* defined(_PR_PTHREADS) */ #endif /* defined(_PR_PTHREADS) */
}; };
PR_EXTERN(void) _PR_InitLocks(void); extern void _PR_InitLocks(void);
struct PRCondVar { struct PRCondVar {
PRLock *lock; /* associated lock that protects the condition */ PRLock *lock; /* associated lock that protects the condition */
#if defined(_PR_PTHREADS) #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) */ #else /* defined(_PR_PTHREADS) */
PRCList condQ; /* Condition variable wait Q */ PRCList condQ; /* Condition variable wait Q */
_MDLock ilock; /* Internal Lock to protect condQ */ _MDLock ilock; /* Internal Lock to protect condQ */
@ -1297,12 +1295,13 @@ struct PRThread {
void *dumpArg; /* argument for the dump function */ void *dumpArg; /* argument for the dump function */
#if defined(_PR_PTHREADS) #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? */ PRBool okToDelete; /* ok to delete the PRThread struct? */
PRCondVar *waiting; /* where the thread is waiting | NULL */ PRCondVar *io_cv; /* a condition used to run i/o */
void *sp; /* recorded sp for garbage collection */ PRCondVar *waiting; /* where the thread is waiting | NULL */
PRThread *next, *prev; /* simple linked list of all threads */ void *sp; /* recorded sp for garbage collection */
PRUint32 suspend; /* used to store suspend and resume flags */ PRThread *next, *prev; /* simple linked list of all threads */
PRUint32 suspend; /* used to store suspend and resume flags */
#ifdef PT_NO_SIGTIMEDWAIT #ifdef PT_NO_SIGTIMEDWAIT
pthread_mutex_t suspendResumeMutex; pthread_mutex_t suspendResumeMutex;
pthread_cond_t suspendResumeCV; pthread_cond_t suspendResumeCV;
@ -1481,10 +1480,10 @@ extern PRBool _pr_ipv6_enabled; /* defined in prnetdb.c */
*************************************************************************/ *************************************************************************/
/* Initialization related */ /* 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 #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 #define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
PR_EXTERN(void) _PR_MD_INIT_SEGS(void); 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 #define _PR_MD_NOW _MD_NOW
/* Environment related */ /* 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 #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 #define _PR_MD_PUT_ENV _MD_PUT_ENV
/* Atomic operations */ /* Atomic operations */
void _PR_MD_INIT_ATOMIC(void); extern void _PR_MD_INIT_ATOMIC(void);
#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC #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 #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 #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 #define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
/* Segment related */ /* Segment related */
@ -1560,29 +1559,29 @@ extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
/* Time intervals */ /* 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 #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 #define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
/* Affinity masks */ /* 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 #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 #define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
/* File locking */ /* File locking */
PR_EXTERN(PRStatus) _PR_MD_LOCKFILE(PRInt32 osfd); extern PRStatus _PR_MD_LOCKFILE(PRInt32 osfd);
#define _PR_MD_LOCKFILE _MD_LOCKFILE #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 #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 #define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
/* Memory-mapped files */ /* 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 #define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
/* Get name of current host */ /* 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 #define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
PR_END_EXTERN_C PR_END_EXTERN_C

Просмотреть файл

@ -24,6 +24,8 @@
#include "prtypes.h" #include "prtypes.h"
#include "prclist.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_EXTERN(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
PR_END_EXTERN_C
#endif /* defined(_PRMWAIT_H) */ #endif /* defined(_PRMWAIT_H) */
/* prmwait.h */ /* prmwait.h */

Просмотреть файл

@ -100,12 +100,20 @@
#define PR_CALLBACK_DECL #define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x #define PR_STATIC_CALLBACK(__x) static __x
#else /* Unix or OS/2 */ #elif defined(XP_OS2)
#define PR_EXTERN(__type) extern __type #define PR_EXTERN(__type) extern __type
#define PR_IMPLEMENT(__type) __type #define PR_IMPLEMENT(__type) __type
#define PR_EXTERN_DATA(__type) extern __type #define PR_EXTERN_DATA(__type) extern __type
#define PR_IMPLEMENT_DATA(__type) __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
#define PR_CALLBACK_DECL #define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x #define PR_STATIC_CALLBACK(__x) static __x
@ -227,9 +235,8 @@ typedef unsigned long PRUint64;
typedef __int64 PRInt64; typedef __int64 PRInt64;
typedef unsigned __int64 PRUint64; typedef unsigned __int64 PRUint64;
#elif defined(WIN32) #elif defined(WIN32)
#include <windows.h> /* For LONGLONG and DWORDLONG */ typedef __int64 PRInt64;
typedef LONGLONG PRInt64; typedef unsigned __int64 PRUint64;
typedef DWORDLONG PRUint64;
#else #else
typedef long long PRInt64; typedef long long PRInt64;
typedef unsigned long long PRUint64; typedef unsigned long long PRUint64;
@ -299,7 +306,9 @@ typedef unsigned long PRUptrdiff;
** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans ** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
** juast as you would C int-valued conditions. ** 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 ** TYPES: PRPackedBool

Просмотреть файл

@ -22,7 +22,7 @@
/* /*
** Condition use of this header on platform. ** 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> #include <stdio.h>
PR_BEGIN_EXTERN_C 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 = { PRIOMethods _pr_fileMethods = {
PR_DESC_FILE, PR_DESC_FILE,
FileClose, FileClose,
@ -222,7 +229,7 @@ PRIOMethods _pr_fileMethods = {
(PRSendFN)_PR_InvalidInt, (PRSendFN)_PR_InvalidInt,
(PRRecvfromFN)_PR_InvalidInt, (PRRecvfromFN)_PR_InvalidInt,
(PRSendtoFN)_PR_InvalidInt, (PRSendtoFN)_PR_InvalidInt,
(PRPollFN)0, FilePoll,
(PRAcceptreadFN)_PR_InvalidInt, (PRAcceptreadFN)_PR_InvalidInt,
(PRTransmitfileFN)_PR_InvalidInt, (PRTransmitfileFN)_PR_InvalidInt,
(PRGetsocknameFN)_PR_InvalidStatus, (PRGetsocknameFN)_PR_InvalidStatus,
@ -233,7 +240,7 @@ PRIOMethods _pr_fileMethods = {
(PRSetsocketoptionFN)_PR_InvalidStatus, (PRSetsocketoptionFN)_PR_InvalidStatus,
}; };
PR_IMPLEMENT(PRIOMethods*) PR_GetFileMethods(void) PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
{ {
return &_pr_fileMethods; return &_pr_fileMethods;
} }

Просмотреть файл

@ -30,7 +30,7 @@ PRLock *_pr_filedesc_freelist_lock;
void _PR_InitIO(void) void _PR_InitIO(void)
{ {
PRIOMethods *methods = PR_GetFileMethods(); const PRIOMethods *methods = PR_GetFileMethods();
_pr_filedesc_freelist = NULL; _pr_filedesc_freelist = NULL;
_pr_filedesc_freelist_lock = PR_NewLock(); _pr_filedesc_freelist_lock = PR_NewLock();
@ -75,7 +75,8 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
return result; return result;
} }
PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd, PRIOMethods *methods) PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
PRInt32 osfd, const PRIOMethods *methods)
{ {
PRFileDesc *fd; PRFileDesc *fd;
@ -147,7 +148,7 @@ PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds,
PRIntervalTime timeout) PRIntervalTime timeout)
{ {
PRPollDesc *pd, *epd; PRPollDesc *pd, *epd;
PRInt32 n; PRInt32 ready;
PRThread *me = _PR_MD_CURRENT_THREAD(); PRThread *me = _PR_MD_CURRENT_THREAD();
if (_PR_PENDING_INTERRUPT(me)) { 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. ** proc to check for data before blocking.
*/ */
pd = pds; pd = pds;
n = 0; ready = 0;
for (pd = pds, epd = pd + npds; pd < epd; pd++) { for (pd = pds, epd = pd + npds; pd < epd; pd++) {
PRFileDesc *fd = pd->fd; PRFileDesc *fd = pd->fd;
PRInt16 in_flags; PRInt16 in_flags = pd->in_flags;
if (NULL == fd) { if (NULL != fd)
continue; {
} if (in_flags && fd->methods->poll) {
in_flags = pd->in_flags; PRInt16 out_flags;
if (in_flags && fd->methods->poll) { in_flags = (*fd->methods->poll)(fd, in_flags, &out_flags);
PRInt16 out_flags = (*fd->methods->poll)(fd, in_flags); if (0 != (in_flags & out_flags)) {
if (out_flags) { pd->out_flags = out_flags; /* ready already */
pd->out_flags = out_flags; ready++;
n++; }
} }
} }
} }
if (n != 0) { if (ready != 0) {
return n; return ready; /* don't need to block */
} }
return(_PR_MD_PR_POLL(pds, npds, timeout)); 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); 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) PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
{ {
PRStatus rv;
PRFileDesc *newfd; PRFileDesc *newfd;
PR_ASSERT(fd != NULL); PR_ASSERT(fd != NULL);
@ -159,13 +160,16 @@ static PRFileDesc * PR_CALLBACK pl_TopAccept (
newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout); newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
if (newfd != NULL) if (newfd != NULL)
{ {
if (PR_FAILURE == PR_PushIOLayer(fd, fd->identity, newfd)) PRFileDesc *newstack = PR_NEW(PRFileDesc);
if (NULL != newstack)
{ {
PR_Close(newfd); *newstack = *fd; /* make a copy of the accepting layer */
newfd = NULL; 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) 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); 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 != NULL);
PR_ASSERT(fd->lower != 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 ( 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. */ /* 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, PR_DESC_LAYERED,
pl_TopClose, pl_TopClose,
pl_DefRead, pl_DefRead,
@ -350,13 +355,13 @@ static struct PRIOMethods pl_methods = {
pl_DefSetsocketoption pl_DefSetsocketoption
}; };
PR_IMPLEMENT(PRIOMethods const*) PR_GetDefaultIOMethods() PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods()
{ {
return &pl_methods; return &pl_methods;
} /* PR_GetDefaultIOMethods */ } /* PR_GetDefaultIOMethods */
PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub( PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
PRDescIdentity ident, PRIOMethods const *methods) PRDescIdentity ident, const PRIOMethods *methods)
{ {
PRFileDesc *fd = NULL; PRFileDesc *fd = NULL;
PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident)); PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
@ -399,6 +404,7 @@ PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
*fd = copy; *fd = copy;
fd->higher = stack; fd->higher = stack;
stack->lower = fd; stack->lower = fd;
stack->higher = NULL;
} }
else else
{ {

Просмотреть файл

@ -40,106 +40,6 @@
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
#endif #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 #ifndef _PR_PTHREADS
PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) 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; data->value.mcast_ttl = ttl;
break; break;
} }
#ifdef IP_ADD_MEMBERSHIP
case PR_SockOpt_AddMember: case PR_SockOpt_AddMember:
case PR_SockOpt_DropMember: case PR_SockOpt_DropMember:
{ {
@ -260,6 +161,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
} }
break; break;
} }
#endif /* IP_ADD_MEMBERSHIP */
case PR_SockOpt_McastInterface: case PR_SockOpt_McastInterface:
{ {
/* This option is a struct in_addr. */ /* 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)); fd, level, name, (char*)&ttl, sizeof(ttl));
break; break;
} }
#ifdef IP_ADD_MEMBERSHIP
case PR_SockOpt_AddMember: case PR_SockOpt_AddMember:
case PR_SockOpt_DropMember: case PR_SockOpt_DropMember:
{ {
@ -389,6 +292,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
fd, level, name, (char*)&mreq, sizeof(mreq)); fd, level, name, (char*)&mreq, sizeof(mreq));
break; break;
} }
#endif /* IP_ADD_MEMBERSHIP */
case PR_SockOpt_McastInterface: case PR_SockOpt_McastInterface:
{ {
/* This option is a struct in_addr. */ /* This option is a struct in_addr. */
@ -406,3 +310,114 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
} /* _PR_SocketSetSocketOption */ } /* _PR_SocketSetSocketOption */
#endif /* ! _PR_PTHREADS */ #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, ** Note: on some platforms va_list is defined as an array,
** and requires array notation. ** and requires array notation.
*/ */
#if defined(MACLINUX) || defined(WIN16) #if defined(MKLINUX) || defined(WIN16)
#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0] #define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
#else #else
#define VARARGS_ASSIGN(foo, bar) (foo) = (bar) #define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
#endif /*MACLINUX*/ #endif /*MKLINUX*/
/* /*
** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it) ** 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; *va_arg(state->ap, long double *) = dval;
#endif #endif
} else { } else {
*va_arg(state->ap, float *) = dval; *va_arg(state->ap, float *) = (float) dval;
} }
} }
return PR_SUCCESS; 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, static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, PRIOVec *iov, PRInt32 iov_size,
PRIntervalTime timeout) PRIntervalTime timeout)
{ {
PRThread *me = _PR_MD_CURRENT_THREAD(); PRThread *me = _PR_MD_CURRENT_THREAD();
int w = 0; int w = 0;
PRIOVec *tmp_iov = NULL; PRIOVec *tmp_iov = NULL;
#define LOCAL_MAXIOV 8
PRIOVec local_iov[LOCAL_MAXIOV];
int tmp_out; int tmp_out;
int index, iov_cnt; int index, iov_cnt;
int count=0, sz = 0; /* 'count' is the return value. */ 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)) { if (_PR_PENDING_INTERRUPT(me)) {
me->flags &= ~_PR_INTERRUPT; me->flags &= ~_PR_INTERRUPT;
@ -64,25 +88,22 @@ PRIntervalTime timeout)
return -1; return -1;
} }
tmp_iov = (PRIOVec *)PR_CALLOC(iov_size * sizeof(PRIOVec)); /*
if (!tmp_iov) { * Assume the first writev will succeed. Copy iov's only on
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); * failure.
return -1; */
} 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; iov_cnt = iov_size;
while (sz > 0) { while (sz > 0) {
w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout); w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout);
if (w < 0) { if (w < 0) {
count = -1; count = -1;
break; break;
} }
count += w; count += w;
if (fd->secret->nonblocking) { if (fd->secret->nonblocking) {
@ -93,9 +114,24 @@ PRIntervalTime timeout)
if (sz > 0) { if (sz > 0) {
/* find the next unwritten vector */ /* find the next unwritten vector */
for ( index = 0, tmp_out = count; for ( index = 0, tmp_out = count;
tmp_out >= iov[index].iov_len; tmp_out >= iov[index].iov_len;
tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */ 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 */ /* fill in the first partial read */
tmp_iov[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]); 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); PR_DELETE(tmp_iov);
return count; return count;
} }
@ -307,13 +343,8 @@ PRIntervalTime timeout)
_PR_MD_MAKE_NONBLOCK(fd2); _PR_MD_MAKE_NONBLOCK(fd2);
#endif #endif
PR_ASSERT((NULL == addr) || (PR_NETADDR_SIZE(addr) == al)); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
#if defined(_PR_INET6) PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
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
return fd2; return fd2;
} }
@ -367,10 +398,16 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
PRInt32 result; PRInt32 result;
int one = 1; int one = 1;
#if defined(_PR_INET6) PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
#else #ifdef XP_UNIX
PR_ASSERT(addr->raw.family == AF_INET); 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 #endif
#ifdef HAVE_SOCKET_REUSEADDR #ifdef HAVE_SOCKET_REUSEADDR
@ -380,6 +417,10 @@ static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
} }
#endif #endif
#ifdef XP_UNIX
}
#endif
result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr)); result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
if (result < 0) { if (result < 0) {
return PR_FAILURE; return PR_FAILURE;
@ -541,11 +582,7 @@ static PRInt32 PR_CALLBACK SocketSendTo(
return -1; return -1;
} }
#if defined(_PR_INET6) PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
#else
PR_ASSERT(addr->raw.family == AF_INET);
#endif
count = 0; count = 0;
while (amount > 0) { while (amount > 0) {
@ -797,12 +834,8 @@ static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
if (result < 0) { if (result < 0) {
return PR_FAILURE; return PR_FAILURE;
} }
PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr)); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
#if defined(_PR_INET6) PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
#else
PR_ASSERT(addr->raw.family == AF_INET);
#endif
return PR_SUCCESS; return PR_SUCCESS;
} }
@ -816,12 +849,8 @@ static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
if (result < 0) { if (result < 0) {
return PR_FAILURE; return PR_FAILURE;
} }
PR_ASSERT(addrlen == PR_NETADDR_SIZE(addr)); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
#if defined(_PR_INET6) PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
PR_ASSERT(addr->raw.family == AF_INET || addr->raw.family == AF_INET6);
#else
PR_ASSERT(addr->raw.family == AF_INET);
#endif
return PR_SUCCESS; return PR_SUCCESS;
} }
@ -925,6 +954,13 @@ static PRStatus PR_CALLBACK SocketSetSockOpt(
return rv; 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 = { static PRIOMethods tcpMethods = {
PR_DESC_SOCKET_TCP, PR_DESC_SOCKET_TCP,
SocketClose, SocketClose,
@ -947,7 +983,7 @@ static PRIOMethods tcpMethods = {
SocketSend, SocketSend,
(PRRecvfromFN)_PR_InvalidInt, (PRRecvfromFN)_PR_InvalidInt,
(PRSendtoFN)_PR_InvalidInt, (PRSendtoFN)_PR_InvalidInt,
(PRPollFN)0, SocketPoll,
SocketAcceptRead, SocketAcceptRead,
SocketTransmitFile, SocketTransmitFile,
SocketGetName, SocketGetName,
@ -980,7 +1016,7 @@ static PRIOMethods udpMethods = {
SocketSend, SocketSend,
SocketRecvFrom, SocketRecvFrom,
SocketSendTo, SocketSendTo,
(PRPollFN)0, SocketPoll,
(PRAcceptreadFN)_PR_InvalidInt, (PRAcceptreadFN)_PR_InvalidInt,
(PRTransmitfileFN)_PR_InvalidInt, (PRTransmitfileFN)_PR_InvalidInt,
SocketGetName, SocketGetName,
@ -991,12 +1027,12 @@ static PRIOMethods udpMethods = {
_PR_SocketSetSocketOption _PR_SocketSetSocketOption
}; };
PR_IMPLEMENT(PRIOMethods*) PR_GetTCPMethods() PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
{ {
return &tcpMethods; return &tcpMethods;
} }
PR_IMPLEMENT(PRIOMethods*) PR_GetUDPMethods() PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
{ {
return &udpMethods; return &udpMethods;
} }
@ -1011,6 +1047,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
if (AF_INET != domain if (AF_INET != domain
#if defined(_PR_INET6) #if defined(_PR_INET6)
&& AF_INET6 != domain && AF_INET6 != domain
#endif
#if defined(XP_UNIX)
&& AF_UNIX != domain
#endif #endif
) { ) {
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
@ -1243,13 +1282,13 @@ PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
{ {
PRInt32 rv; PRInt32 rv;
PRFileDesc *newsockfd; PRFileDesc *newsockfd;
PRNetAddr remote;
PRIntervalTime start, elapsed; PRIntervalTime start, elapsed;
if (PR_INTERVAL_NO_TIMEOUT != timeout) { if (PR_INTERVAL_NO_TIMEOUT != timeout) {
start = PR_IntervalNow(); 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; return -1;
} }
@ -1266,8 +1305,6 @@ PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
rv = PR_Recv(newsockfd, buf, amount, 0, timeout); rv = PR_Recv(newsockfd, buf, amount, 0, timeout);
if (rv >= 0) { if (rv >= 0) {
*nd = newsockfd; *nd = newsockfd;
*raddr = (PRNetAddr *)((char *) buf + amount);
memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));
return rv; 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; OSStatus err;
InetInterfaceInfo info; InetInterfaceInfo info;

Просмотреть файл

@ -147,7 +147,7 @@ md_UnlockAndPostNotifies(
} }
/* Release the lock before notifying */ /* Release the lock before notifying */
LeaveCriticalSection(&lock->mutex); DosReleaseMutexSem(lock->mutex);
notified = &post; /* this is where we start */ notified = &post; /* this is where we start */
do { do {
@ -254,14 +254,14 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
md_UnlockAndPostNotifies(lock, thred, cv); md_UnlockAndPostNotifies(lock, thred, cv);
} else { } else {
AddThreadToCVWaitQueueInternal(thred, cv); AddThreadToCVWaitQueueInternal(thred, cv);
LeaveCriticalSection(&lock->mutex); DosReleaseMutexSem(lock->mutex);
} }
/* Wait for notification or timeout; don't really care which */ /* Wait for notification or timeout; don't really care which */
rv = DosWaitEventSem(thred->md.blocked_sema.sem, msecs); rv = DosWaitEventSem(thred->md.blocked_sema.sem, msecs);
DosResetEventSem(thred->md.blocked_sema.sem, &count); DosResetEventSem(thred->md.blocked_sema.sem, &count);
EnterCriticalSection(&(lock->mutex)); _MD_LOCK(lock);
PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT); PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
@ -326,7 +326,7 @@ _PR_MD_UNLOCK(_MDLock *lock)
if (0 != lock->notified.length) { if (0 != lock->notified.length) {
md_UnlockAndPostNotifies(lock, NULL, NULL); md_UnlockAndPostNotifies(lock, NULL, NULL);
} else { } else {
LeaveCriticalSection(&lock->mutex); DosReleaseMutexSem(lock->mutex);
} }
return; return;
} }

Просмотреть файл

@ -22,7 +22,7 @@
*/ */
#include "primpl.h" #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) PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{ {

Просмотреть файл

@ -27,7 +27,7 @@
struct _MDLock _pr_ioq_lock; struct _MDLock _pr_ioq_lock;
PR_IMPLEMENT(PRStatus) PRStatus
_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
{ {
PRInt32 rv; PRInt32 rv;
@ -68,7 +68,7 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
} }
return PR_FAILURE; return PR_FAILURE;
} }
PR_IMPLEMENT(PRStatus) PRStatus
_PR_MD_WAKEUP_WAITER(PRThread *thread) _PR_MD_WAKEUP_WAITER(PRThread *thread)
{ {
if ( _PR_IS_NATIVE_THREAD(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) _PR_MD_LOCKFILE(PRInt32 f)
{ {
PRInt32 rv; PRInt32 rv;
@ -586,14 +586,14 @@ _PR_MD_LOCKFILE(PRInt32 f)
return PR_SUCCESS; return PR_SUCCESS;
} /* end _PR_MD_LOCKFILE() */ } /* end _PR_MD_LOCKFILE() */
PR_IMPLEMENT(PRStatus) PRStatus
_PR_MD_TLOCKFILE(PRInt32 f) _PR_MD_TLOCKFILE(PRInt32 f)
{ {
return _PR_MD_LOCKFILE(f); return _PR_MD_LOCKFILE(f);
} /* end _PR_MD_TLOCKFILE() */ } /* end _PR_MD_TLOCKFILE() */
PR_IMPLEMENT(PRStatus) PRStatus
_PR_MD_UNLOCKFILE(PRInt32 f) _PR_MD_UNLOCKFILE(PRInt32 f)
{ {
PRInt32 rv; PRInt32 rv;

Просмотреть файл

@ -22,13 +22,13 @@
*/ */
#include "primpl.h" #include "primpl.h"
PR_IMPLEMENT(char *) char *
_PR_MD_GET_ENV(const char *name) _PR_MD_GET_ENV(const char *name)
{ {
return getenv(name); return getenv(name);
} }
PR_IMPLEMENT(PRIntn) PRIntn
_PR_MD_PUT_ENV(const char *name) _PR_MD_PUT_ENV(const char *name)
{ {
return putenv(name); return putenv(name);
@ -452,7 +452,7 @@ PRStatus _PR_KillOS2Process(PRProcess *process)
return PR_FAILURE; return PR_FAILURE;
} }
PR_IMPLEMENT(PRStatus) _MD_OS2GetHostName(char *name, PRUint32 namelen) PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
{ {
PRIntn rv; PRIntn rv;
PRInt32 syserror; PRInt32 syserror;

Просмотреть файл

@ -19,7 +19,7 @@
#include "primpl.h" #include "primpl.h"
#include <process.h> /* for _beginthread() */ #include <process.h> /* for _beginthread() */
APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
/* --- globals ------------------------------------------------ */ /* --- globals ------------------------------------------------ */
_NSPR_TLS* pThreadLocalStorage = 0; _NSPR_TLS* pThreadLocalStorage = 0;
@ -83,7 +83,7 @@ _PR_MD_CREATE_THREAD(PRThread *thread,
PRThreadState state, PRThreadState state,
PRUint32 stackSize) PRUint32 stackSize)
{ {
thread->md.handle = thread->id = (TID) _beginthread( thread->md.handle = thread->id = (OS2TID) _beginthread(
(void(* _Optlink)(void*))start, (void(* _Optlink)(void*))start,
NULL, NULL,
thread->stack->stackSize, thread->stack->stackSize,

Просмотреть файл

@ -20,12 +20,13 @@
/* /*
* NSPR 2.0 overrides the system select() and poll() functions. * 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 * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get
* original system select() and poll() functions. * at the original system select() and poll() functions.
*/ */
#ifndef AIX4_1 #ifndef AIX4_1
#include <sys/atomic_op.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <dlfcn.h> #include <dlfcn.h>
@ -34,13 +35,25 @@ static void *aix_handle = NULL;
static int (*aix_select_fcn)() = NULL; static int (*aix_select_fcn)() = NULL;
static int (*aix_poll_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 _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
{ {
int rv; int rv;
if (!aix_select_fcn) { if (!aix_select_fcn) {
if (!aix_handle) { if (!aix_handle) {
aix_handle = dlopen("/unix",0); aix_handle = dlopen("/unix", RTLD_NOW);
if (!aix_handle) { if (!aix_handle) {
PR_SetError(PR_UNKNOWN_ERROR, 0); PR_SetError(PR_UNKNOWN_ERROR, 0);
return -1; return -1;
@ -62,7 +75,7 @@ int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
if (!aix_poll_fcn) { if (!aix_poll_fcn) {
if (!aix_handle) { if (!aix_handle) {
aix_handle = dlopen("/unix",0); aix_handle = dlopen("/unix", RTLD_NOW);
if (!aix_handle) { if (!aix_handle) {
PR_SetError(PR_UNKNOWN_ERROR, 0); PR_SetError(PR_UNKNOWN_ERROR, 0);
return -1; return -1;
@ -95,10 +108,38 @@ void _pr_aix_dummy()
#if !defined(PTHREADS_USER) #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) void _MD_EarlyInit(void)
{ {
} }
#endif /* _PR_PTHREADS */
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{ {
#ifndef _PR_PTHREADS #ifndef _PR_PTHREADS

Просмотреть файл

@ -98,135 +98,3 @@ _MD_CREATE_THREAD(
return PR_FAILURE; return PR_FAILURE;
} }
#endif /* ! _PR_PTHREADS */ #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) || if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) ||
(WTERMSIG(status) == SIGBUS) || (WTERMSIG(status) == SIGBUS) ||
(WTERMSIG(status) == SIGABRT) || (WTERMSIG(status) == SIGABRT) ||
(WTERMSIG(status) == SIGILL))) (WTERMSIG(status) == SIGILL))) {
prctl(PR_SETEXITSIG, SIGKILL); prctl(PR_SETEXITSIG, SIGKILL);
exit(status); exit(status);
}
} }
} }
@ -437,19 +438,32 @@ void _PR_IRIX_CHILD_PROCESS()
static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout) static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
{ {
struct timeval tv, *tvp;
fd_set rd;
int rv; int rv;
if(timeout == PR_INTERVAL_NO_TIMEOUT) tvp = NULL; #ifdef _PR_USE_POLL
else { struct pollfd pfd;
tv.tv_sec = PR_IntervalToSeconds(timeout); int msecs;
tv.tv_usec = PR_IntervalToMicroseconds(
timeout - PR_SecondsToInterval(tv.tv_sec)); if (timeout == PR_INTERVAL_NO_TIMEOUT)
tvp = &tv; msecs = -1;
} else
FD_ZERO(&rd); msecs = PR_IntervalToMilliseconds(timeout);
FD_SET(thread->md.cvar_pollsemfd, &rd); #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 * call uspsema only if a previous select call on this semaphore
* did not timeout * did not timeout
@ -461,8 +475,13 @@ static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
rv = 0; rv = 0;
again: again:
if(!rv) { if(!rv) {
rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, #ifdef _PR_USE_POLL
NULL,NULL,tvp); 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)) { if ((rv == -1) && (errno == EINTR)) {
rv = 0; rv = 0;
goto again; goto again;
@ -559,10 +578,12 @@ PRUint32 stackSize)
PRThread *me = _PR_MD_CURRENT_THREAD(); PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 pid; PRInt32 pid;
PRStatus rv; PRStatus rv;
PRStatus creation_status;
if (!_PR_IS_NATIVE_THREAD(me)) if (!_PR_IS_NATIVE_THREAD(me))
_PR_INTSOFF(is); _PR_INTSOFF(is);
thread->md.cvar_pollsem_select = 0; thread->md.cvar_pollsem_select = 0;
thread->md.creation_status = &creation_status;
thread->flags |= _PR_GLOBAL_SCOPE; thread->flags |= _PR_GLOBAL_SCOPE;
pid = sprocsp( pid = sprocsp(
spentry, /* startup func */ spentry, /* startup func */
@ -579,7 +600,7 @@ PRUint32 stackSize)
blockproc(me->cpu->md.id); blockproc(me->cpu->md.id);
else else
blockproc(me->md.id); 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 * 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.id = getpid();
thread->md.cvar_pollsemfd = -1; thread->md.cvar_pollsemfd = -1;
if (new_poll_sem(&thread->md,0) == PR_FAILURE) { 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()); unblockproc(getppid());
rv = PR_FAILURE; }
return PR_FAILURE;
} }
thread->md.cvar_pollsemfd = thread->md.cvar_pollsemfd =
_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem); _PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
if ((thread->md.cvar_pollsemfd < 0)) { if ((thread->md.cvar_pollsemfd < 0)) {
free_poll_sem(&thread->md); free_poll_sem(&thread->md);
if (wakeup_parent == PR_TRUE) if (wakeup_parent == PR_TRUE) {
*thread->md.creation_status = PR_FAILURE;
unblockproc(getppid()); unblockproc(getppid());
rv = PR_FAILURE; }
return PR_FAILURE;
} }
setblockproccnt(thread->md.id, 0); setblockproccnt(thread->md.id, 0);
_MD_SET_SPROC_PID(getpid()); _MD_SET_SPROC_PID(getpid());
@ -744,8 +769,10 @@ _MD_InitThread(PRThread *thread, PRBool wakeup_parent)
/* /*
* unblock the parent sproc * unblock the parent sproc
*/ */
if (wakeup_parent == PR_TRUE) if (wakeup_parent == PR_TRUE) {
*thread->md.creation_status = PR_SUCCESS;
unblockproc(getppid()); unblockproc(getppid());
}
} }
return rv; return rv;
} }
@ -769,7 +796,9 @@ _MD_InitRunningCPU(_PRCPU *cpu)
_MD_SET_SPROC_PID(getpid()); _MD_SET_SPROC_PID(getpid());
if (_pr_md_pipefd[0] >= 0) { if (_pr_md_pipefd[0] >= 0) {
_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[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)); FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
#endif
} }
} }

Просмотреть файл

@ -96,135 +96,3 @@ _MD_CREATE_THREAD(
return PR_FAILURE; return PR_FAILURE;
} }
#endif /* ! _PR_PTHREADS */ #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 # Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved. # Reserved.
# #
.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4 .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 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 .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 * Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved. * Reserved.
*/ */
/* /*
* os_BSD_386_2.s * os_BSD_386_2.s
* We need to define our own setjmp/longjmp on BSDI 2.x because libc'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 * Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved. * Reserved.
*/ */
/* We want position independent code */ /* We want position independent code */
#define PIC #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 ! 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 ! Version 1.0 (the "NPL"); you may not use this file except in

Просмотреть файл

@ -28,6 +28,10 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#ifdef _PR_POLL_AVAILABLE
#include <poll.h>
#endif
/* To get FIONREAD */ /* To get FIONREAD */
#if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \ #if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
|| defined(SONY) || defined(SONY)
@ -41,7 +45,7 @@
#if defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \ #if defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
|| defined(AIX4_1) || defined(LINUX) || defined(SONY) \ || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
|| defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \ || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
|| defined(SUNOS4) || defined(SUNOS4) || defined(NCR)
#define _PRSockLen_t int #define _PRSockLen_t int
#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \ #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
|| defined(UNIXWARE) || defined(UNIXWARE)
@ -89,7 +93,7 @@ static sigset_t empty_set;
/* /*
* _nspr_noclock - if set clock interrupts are disabled * _nspr_noclock - if set clock interrupts are disabled
*/ */
int _nspr_noclock = 0; int _nspr_noclock = 1;
#ifdef IRIX #ifdef IRIX
extern PRInt32 _nspr_terminate_on_error; 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(); PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 rv, err; PRInt32 rv, err;
#ifndef _PR_USE_POLL
fd_set rd; fd_set rd;
#else
struct pollfd pfd;
#endif /* _PR_USE_POLL */
PRInt32 osfd = fd->secret->md.osfd; PRInt32 osfd = fd->secret->md.osfd;
#ifndef _PR_USE_POLL
FD_ZERO(&rd); FD_ZERO(&rd);
FD_SET(osfd, &rd); FD_SET(osfd, &rd);
#else
pfd.fd = osfd;
pfd.events = POLLIN;
#endif /* _PR_USE_POLL */
while ((rv = read(osfd,buf,amount)) == -1) { while ((rv = read(osfd,buf,amount)) == -1) {
err = _MD_ERRNO(); err = _MD_ERRNO();
if ((err == EAGAIN) || (err == EWOULDBLOCK)) { if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
@ -394,10 +407,17 @@ PRInt32 osfd = fd->secret->md.osfd;
if (!_PR_IS_NATIVE_THREAD(me)) { if (!_PR_IS_NATIVE_THREAD(me)) {
_PR_WaitForFD(osfd, PR_POLL_READ, PR_INTERVAL_NO_TIMEOUT); _PR_WaitForFD(osfd, PR_POLL_READ, PR_INTERVAL_NO_TIMEOUT);
} else { } else {
#ifndef _PR_USE_POLL
while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL)) while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
== -1 && (err = _MD_ERRNO()) == EINTR) { == -1 && (err = _MD_ERRNO()) == EINTR) {
/* retry _MD_SELECT() if it is interrupted */ /* 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) { if (rv == -1) {
break; break;
} }
@ -425,11 +445,20 @@ PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
{ {
PRThread *me = _PR_MD_CURRENT_THREAD(); PRThread *me = _PR_MD_CURRENT_THREAD();
PRInt32 rv, err; PRInt32 rv, err;
#ifndef _PR_USE_POLL
fd_set wd; fd_set wd;
#else
struct pollfd pfd;
#endif /* _PR_USE_POLL */
PRInt32 osfd = fd->secret->md.osfd; PRInt32 osfd = fd->secret->md.osfd;
#ifndef _PR_USE_POLL
FD_ZERO(&wd); FD_ZERO(&wd);
FD_SET(osfd, &wd); FD_SET(osfd, &wd);
#else
pfd.fd = osfd;
pfd.events = POLLOUT;
#endif /* _PR_USE_POLL */
while ((rv = write(osfd,buf,amount)) == -1) { while ((rv = write(osfd,buf,amount)) == -1) {
err = _MD_ERRNO(); err = _MD_ERRNO();
if ((err == EAGAIN) || (err == EWOULDBLOCK)) { if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
@ -439,10 +468,17 @@ PRInt32 osfd = fd->secret->md.osfd;
if (!_PR_IS_NATIVE_THREAD(me)) { if (!_PR_IS_NATIVE_THREAD(me)) {
_PR_WaitForFD(osfd, PR_POLL_WRITE, PR_INTERVAL_NO_TIMEOUT); _PR_WaitForFD(osfd, PR_POLL_WRITE, PR_INTERVAL_NO_TIMEOUT);
} else { } else {
#ifndef _PR_USE_POLL
while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL)) while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
== -1 && (err = _MD_ERRNO()) == EINTR) { == -1 && (err = _MD_ERRNO()) == EINTR) {
/* retry _MD_SELECT() if it is interrupted */ /* 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) { if (rv == -1) {
break; break;
} }
@ -570,11 +606,18 @@ PRInt64 _MD_socketavailable64(PRFileDesc *fd)
#define WRITE_FD 2 #define WRITE_FD 2
/* /*
* socket_io_wait --
*
* wait for socket i/o, periodically checking for interrupt * 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, static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
PRIntervalTime timeout) PRIntervalTime timeout)
{ {
PRInt32 rv = -1; PRInt32 rv = -1;
struct timeval tv, *tvp; struct timeval tv, *tvp;
@ -692,6 +735,114 @@ static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
return(rv); 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 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
PRInt32 flags, PRIntervalTime timeout) PRInt32 flags, PRIntervalTime timeout)
{ {
@ -794,14 +945,17 @@ PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
_PR_MD_MAP_RECVFROM_ERROR(err); _PR_MD_MAP_RECVFROM_ERROR(err);
} }
done: done:
#ifdef AIX #ifdef _PR_HAVE_SOCKADDR_LEN
if (rv != -1) { if (rv != -1) {
/* mask off the first byte of struct sockaddr (the length field) */ /* mask off the first byte of struct sockaddr (the length field) */
if (addr) { 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); return(rv);
} }
@ -1043,14 +1197,17 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
_PR_MD_MAP_ACCEPT_ERROR(err); _PR_MD_MAP_ACCEPT_ERROR(err);
} }
done: done:
#ifdef AIX #ifdef _PR_HAVE_SOCKADDR_LEN
if (rv != -1) { if (rv != -1) {
/* mask off the first byte of struct sockaddr (the length field) */ /* mask off the first byte of struct sockaddr (the length field) */
if (addr) { 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); return(rv);
} }
@ -1198,14 +1355,17 @@ PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
rv = getsockname(fd->secret->md.osfd, rv = getsockname(fd->secret->md.osfd,
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen); (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
#ifdef AIX #ifdef _PR_HAVE_SOCKADDR_LEN
if (rv == 0) { if (rv == 0) {
/* mask off the first byte of struct sockaddr (the length field) */ /* mask off the first byte of struct sockaddr (the length field) */
if (addr) { 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) { if (rv < 0) {
err = _MD_ERRNO(); err = _MD_ERRNO();
_PR_MD_MAP_GETSOCKNAME_ERROR(err); _PR_MD_MAP_GETSOCKNAME_ERROR(err);
@ -1220,14 +1380,17 @@ PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
rv = getpeername(fd->secret->md.osfd, rv = getpeername(fd->secret->md.osfd,
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen); (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
#ifdef AIX #ifdef _PR_HAVE_SOCKADDR_LEN
if (rv == 0) { if (rv == 0) {
/* mask off the first byte of struct sockaddr (the length field) */ /* mask off the first byte of struct sockaddr (the length field) */
if (addr) { 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) { if (rv < 0) {
err = _MD_ERRNO(); err = _MD_ERRNO();
_PR_MD_MAP_GETPEERNAME_ERROR(err); _PR_MD_MAP_GETPEERNAME_ERROR(err);
@ -1272,7 +1435,16 @@ PR_IMPLEMENT(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
_PRCPU *io_cpu; _PRCPU *io_cpu;
PRThread *me = _PR_MD_CURRENT_THREAD(); PRThread *me = _PR_MD_CURRENT_THREAD();
if (0 == npds) {
PR_Sleep(timeout);
return 0;
}
if (_PR_IS_NATIVE_THREAD(me)) { 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; fd_set rd, wt, ex;
struct timeval tv, *tvp = NULL; struct timeval tv, *tvp = NULL;
int maxfd = -1; int maxfd = -1;
@ -1398,6 +1570,105 @@ retry:
} }
return n; 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++; unixpd++;
pdcnt++; pdcnt++;
#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) { if (in_flags & PR_POLL_READ) {
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu)); FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
_PR_FD_READ_CNT(me->cpu)[osfd]++; _PR_FD_READ_CNT(me->cpu)[osfd]++;
@ -1467,12 +1739,14 @@ retry:
FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++; (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
} }
#endif /* _PR_USE_POLL */
if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) if (osfd > _PR_IOQ_MAX_OSFD(me->cpu))
_PR_IOQ_MAX_OSFD(me->cpu) = osfd; _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
} }
if (timeout < _PR_IOQ_TIMEOUT(me->cpu)) if (timeout < _PR_IOQ_TIMEOUT(me->cpu))
_PR_IOQ_TIMEOUT(me->cpu) = timeout; _PR_IOQ_TIMEOUT(me->cpu) = timeout;
_PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
pq.pds = unixpds; pq.pds = unixpds;
pq.npds = pdcnt; pq.npds = pdcnt;
@ -1541,6 +1815,7 @@ retry:
} }
osfd = bottom->secret->md.osfd; osfd = bottom->secret->md.osfd;
PR_ASSERT(osfd >= 0 || in_flags == 0); PR_ASSERT(osfd >= 0 || in_flags == 0);
#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) { if (in_flags & PR_POLL_READ) {
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
@ -1553,7 +1828,10 @@ retry:
if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); 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(); _PR_MD_IOQ_UNLOCK();
} }
@ -1637,6 +1915,7 @@ static void FindBadFDs(void)
PRInt32 osfd = pds->osfd; PRInt32 osfd = pds->osfd;
PRInt16 in_flags = pds->in_flags; PRInt16 in_flags = pds->in_flags;
PR_ASSERT(osfd >= 0 || in_flags == 0); PR_ASSERT(osfd >= 0 || in_flags == 0);
#ifndef _PR_USE_POLL
if (in_flags & PR_POLL_READ) { if (in_flags & PR_POLL_READ) {
if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); 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) if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
} }
#endif /* !_PR_USE_POLL */
} }
_PR_THREAD_LOCK(pq->thr); _PR_THREAD_LOCK(pq->thr);
@ -1700,6 +1980,7 @@ void _MD_PauseCPU(PRIntervalTime ticks)
struct pollfd *pollfds; /* an array of pollfd structures */ struct pollfd *pollfds; /* an array of pollfd structures */
struct pollfd *pollfdPtr; /* a pointer that steps through the array */ struct pollfd *pollfdPtr; /* a pointer that steps through the array */
unsigned long npollfds; /* number of pollfd structures in array */ unsigned long npollfds; /* number of pollfd structures in array */
unsigned long pollfds_size;
int nfd; /* to hold the return value of poll() */ int nfd; /* to hold the return value of poll() */
#else #else
struct timeval timeout, *tvp; struct timeval timeout, *tvp;
@ -1723,12 +2004,9 @@ extern sigset_t ints_off;
/* Build up the pollfd structure array to wait on */ /* Build up the pollfd structure array to wait on */
/* Find out how many pollfd structures are needed */ /* Find out how many pollfd structures are needed */
npollfds = 0; npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) { PR_ASSERT(npollfds >= 0);
PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
npollfds += pq->npds;
}
/* /*
* We use a pipe to wake up a native thread. An fd is needed * We use a pipe to wake up a native thread. An fd is needed
* for the pipe and we poll it for reading. * for the pipe and we poll it for reading.
@ -1736,8 +2014,21 @@ extern sigset_t ints_off;
if (_PR_IS_NATIVE_THREAD_SUPPORTED()) if (_PR_IS_NATIVE_THREAD_SUPPORTED())
npollfds++; 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, * 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; pollfdPtr->events = pds->in_flags;
} }
} }
_PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
#else #else
/* /*
* assigment of fd_sets * assigment of fd_sets
@ -1897,16 +2189,16 @@ extern sigset_t ints_off;
for (; pds < epds; pds++, pollfdPtr++) { for (; pds < epds; pds++, pollfdPtr++) {
/* /*
* Assert that the pollfdPtr pointer does not go beyond * Assert that the pollfdPtr pointer does not go beyond
* the end of the pollfds array. * the end of the pollfds array.
*/ */
PR_ASSERT(pollfdPtr < pollfds + npollfds); PR_ASSERT(pollfdPtr < pollfds + npollfds);
/* /*
* Assert that the fd's in the pollfds array (stepped * Assert that the fd's in the pollfds array (stepped
* through by pollfdPtr) are in the same order as * through by pollfdPtr) are in the same order as
* the fd's in _PR_IOQ() (stepped through by q and pds). * the fd's in _PR_IOQ() (stepped through by q and pds).
* This is how the pollfds array was created earlier. * This is how the pollfds array was created earlier.
*/ */
PR_ASSERT(pollfdPtr->fd == pds->osfd); PR_ASSERT(pollfdPtr->fd == pds->osfd);
pds->out_flags = pollfdPtr->revents; pds->out_flags = pollfdPtr->revents;
/* Negative fd's are ignored by poll() */ /* Negative fd's are ignored by poll() */
@ -1921,12 +2213,7 @@ extern sigset_t ints_off;
PR_REMOVE_LINK(&pq->links); PR_REMOVE_LINK(&pq->links);
pq->on_ioq = PR_FALSE; pq->on_ioq = PR_FALSE;
/* thred = pq->thr;
* Because this thread can run on a different cpu right
* after being added to the run queue, do not dereference
* pq
*/
thred = pq->thr;
_PR_THREAD_LOCK(thred); _PR_THREAD_LOCK(thred);
if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
_PRCPU *cpu = pq->thr->cpu; _PRCPU *cpu = pq->thr->cpu;
@ -1944,14 +2231,14 @@ extern sigset_t ints_off;
_PR_MD_WAKEUP_WAITER(thred); _PR_MD_WAKEUP_WAITER(thred);
} }
_PR_THREAD_UNLOCK(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) { } else if (nfd == -1) {
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno)); PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
} }
/* done with pollfds */
PR_DELETE(pollfds);
#else #else
if (nfd > 0) { if (nfd > 0) {
q = _PR_IOQ(me->cpu).next; q = _PR_IOQ(me->cpu).next;
@ -2136,7 +2423,9 @@ void _MD_InitCPUS()
rv = pipe(_pr_md_pipefd); rv = pipe(_pr_md_pipefd);
PR_ASSERT(rv == 0); PR_ASSERT(rv == 0);
_PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[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)); FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
#endif
flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0); flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK); 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.on_ioq = PR_TRUE;
pq.timeout = timeout; pq.timeout = timeout;
_PR_ADD_TO_IOQ(pq, me->cpu); _PR_ADD_TO_IOQ(pq, me->cpu);
#ifndef _PR_USE_POLL
if (how == PR_POLL_READ) { if (how == PR_POLL_READ) {
FD_SET(osfd, &_PR_FD_READ_SET(me->cpu)); FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
(_PR_FD_READ_CNT(me->cpu))[osfd]++; (_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)); FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++; (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
} }
#endif /* _PR_USE_POLL */
if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd) if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd)
_PR_IOQ_MAX_OSFD(me->cpu) = osfd; _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) if (_PR_IOQ_TIMEOUT(me->cpu) > timeout)
_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_SLEEPQ_LOCK(me->cpu);
_PR_ADD_SLEEPQ(me, timeout); _PR_ADD_SLEEPQ(me, timeout);
me->state = _PR_IO_WAIT; me->state = _PR_IO_WAIT;
@ -2944,17 +3238,21 @@ PRInt32 _PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
*/ */
if (pq.on_ioq) { if (pq.on_ioq) {
PR_REMOVE_LINK(&pq.links); PR_REMOVE_LINK(&pq.links);
if (how == PR_POLL_READ) { #ifndef _PR_USE_POLL
if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0) if (how == PR_POLL_READ) {
FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); 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) } else if (how == PR_POLL_WRITE) {
FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
} else { FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0) } else {
FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); 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(); _PR_MD_IOQ_UNLOCK();
rv = 0; rv = 0;
@ -3238,3 +3536,140 @@ PRStatus _MD_CloseFileMap(PRFileMap *fmap)
PR_DELETE(fmap); PR_DELETE(fmap);
return PR_SUCCESS; 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) void _MD_unix_map_flock_error(int err)
{ {
switch (err) { switch (err) {

Просмотреть файл

@ -2945,7 +2945,7 @@ PRInt32 IsFileLocal(HANDLE hFile)
} }
#endif /* _NEED_351_FILE_LOCKING_HACK */ #endif /* _NEED_351_FILE_LOCKING_HACK */
void PR_NT_UseNonblock() PR_IMPLEMENT(void) PR_NT_UseNonblock()
{ {
_nt_use_async = 0; _nt_use_async = 0;
} }

Просмотреть файл

@ -60,7 +60,7 @@ PRIntn _PR_MD_PUT_ENV(const char *name)
*----------------------------------------------------------------------- *-----------------------------------------------------------------------
*/ */
PRTime PR_IMPLEMENT(PRTime)
PR_Now(void) PR_Now(void)
{ {
PRInt64 s, ms, ms2us, s2us; PRInt64 s, ms, ms2us, s2us;
@ -601,3 +601,51 @@ PRStatus _MD_CloseFileMap(PRFileMap *fmap)
PR_DELETE(fmap); PR_DELETE(fmap);
return PR_SUCCESS; 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 void
_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
{ {
#if 0 int nativePri;
/* XXXMB - does this work? Should we really set the priorities of BOOL rv;
* native threads? */
if( newPri < 4 ) {
newPri = (PRUintn)THREAD_PRIORITY_IDLE;
} else if( newPri < 8 ) {
newPri = (PRUintn)THREAD_PRIORITY_LOWEST;
} else if( newPri < 12 ) {
newPri = (PRUintn)THREAD_PRIORITY_BELOW_NORMAL;
} else if( newPri < 16 ) {
newPri = (PRUintn)THREAD_PRIORITY_NORMAL;
} else if( newPri < 24 ) {
newPri = (PRUintn)THREAD_PRIORITY_ABOVE_NORMAL;
} else if( newPri < 28 ) {
newPri = (PRUintn)THREAD_PRIORITY_HIGHEST;
} else if( newPri < 32 ) {
newPri = (PRUintn)THREAD_PRIORITY_TIME_CRITICAL;
}
if( ! SetThreadPriority( thread->handle, newPri ) ) { if (newPri < PR_PRIORITY_FIRST) {
PR_LOG(_pr_thread_lm, PR_LOG_MIN, newPri = PR_PRIORITY_FIRST;
("PR_SetThreadPriority: can't set thread priority\n")); } 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; return;
} }

Просмотреть файл

@ -42,7 +42,7 @@ _PRInterruptTable _pr_interruptTable[] = { { 0 } };
#if defined(HAVE_WATCOM_BUG_2) #if defined(HAVE_WATCOM_BUG_2)
PRTime __pascal __export __loadds PRTime __pascal __export __loadds
#else #else
PRTime PR_IMPLEMENT(PRTime)
#endif #endif
PR_Now(void) PR_Now(void)
{ {

Просмотреть файл

@ -22,9 +22,15 @@
extern void _PR_Win32InitTimeZone(void); /* defined in ntmisc.c */ extern void _PR_Win32InitTimeZone(void); /* defined in ntmisc.c */
/* --- globals ------------------------------------------------ */ /* --- globals ------------------------------------------------ */
#ifdef _PR_USE_STATIC_TLS
__declspec(thread) struct PRThread *_pr_thread_last_run; __declspec(thread) struct PRThread *_pr_thread_last_run;
__declspec(thread) struct PRThread *_pr_currentThread; __declspec(thread) struct PRThread *_pr_currentThread;
__declspec(thread) struct _PRCPU *_pr_currentCPU; __declspec(thread) struct _PRCPU *_pr_currentCPU;
#else
DWORD _pr_currentThreadIndex;
DWORD _pr_lastThreadIndex;
DWORD _pr_currentCPUIndex;
#endif
int _pr_intsOff = 0; int _pr_intsOff = 0;
_PRInterruptTable _pr_interruptTable[] = { { 0 } }; _PRInterruptTable _pr_interruptTable[] = { { 0 } };
@ -32,11 +38,23 @@ void
_PR_MD_EARLY_INIT() _PR_MD_EARLY_INIT()
{ {
_PR_Win32InitTimeZone(); _PR_Win32InitTimeZone();
#ifndef _PR_USE_STATIC_TLS
_pr_currentThreadIndex = TlsAlloc();
_pr_lastThreadIndex = TlsAlloc();
_pr_currentCPUIndex = TlsAlloc();
#endif
} }
void _PR_MD_CLEANUP_BEFORE_EXIT(void) void _PR_MD_CLEANUP_BEFORE_EXIT(void)
{ {
WSACleanup(); WSACleanup();
#ifndef _PR_USE_STATIC_TLS
TlsFree(_pr_currentThreadIndex);
TlsFree(_pr_lastThreadIndex);
TlsFree(_pr_currentCPUIndex);
#endif
} }
void void

Просмотреть файл

@ -18,6 +18,7 @@
#include "prerror.h" #include "prerror.h"
#include <errno.h> #include <errno.h>
#include <windows.h>
void _MD_win32_map_opendir_error(PRInt32 err) 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) _PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
{ {
PRInt32 rv; PRInt32 rv;
if (!_pr_initialized) {
_PR_ImplicitInitialization();
}
PR_Lock(monitor); PR_Lock(monitor);
rv = ++(*val); rv = ++(*val);
PR_Unlock(monitor); PR_Unlock(monitor);
return rv; return rv;
} }
PR_IMPLEMENT(PRInt32) PRInt32
_PR_MD_ATOMIC_DECREMENT(PRInt32 *val) _PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
{ {
PRInt32 rv; PRInt32 rv;
if (!_pr_initialized) {
_PR_ImplicitInitialization();
}
PR_Lock(monitor); PR_Lock(monitor);
rv = --(*val); rv = --(*val);
PR_Unlock(monitor); PR_Unlock(monitor);
return rv; return rv;
} }
PR_IMPLEMENT(PRInt32) PRInt32
_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) _PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
{ {
PRInt32 rv; PRInt32 rv;
if (!_pr_initialized) {
_PR_ImplicitInitialization();
}
PR_Lock(monitor); PR_Lock(monitor);
rv = *val; rv = *val;
*val = newval; *val = newval;

Просмотреть файл

@ -1,4 +1,20 @@
/* -*- 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
* 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" #include "primpl.h"
@ -30,12 +46,12 @@
dmg@research.att.com or research!dmg 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 * This PR_strtod returns a nearest machine number to the input decimal
* string (or sets errno to ERANGE). With IEEE arithmetic, ties are * string (or sets the error code to PR_RANGE_ERROR). With IEEE
* broken by the IEEE round-even rule. Otherwise ties are broken by * arithmetic, ties are broken by the IEEE round-even rule. Otherwise
* biased rounding (add half and chop). * ties are broken by biased rounding (add half and chop).
* *
* Inspired loosely by William D. Clinger's paper "How to Read Floating * Inspired loosely by William D. Clinger's paper "How to Read Floating
* Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
@ -124,7 +140,6 @@ extern void *MALLOC(size_t);
#define MALLOC PR_MALLOC #define MALLOC PR_MALLOC
#endif #endif
#include "errno.h"
#ifdef Bad_float_h #ifdef Bad_float_h
#undef __STDC__ #undef __STDC__
#ifdef IEEE_MC68k #ifdef IEEE_MC68k
@ -1351,7 +1366,7 @@ dig_done:
if (e1 &= ~15) { if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) { if (e1 > DBL_MAX_10_EXP) {
ovfl: ovfl:
errno = ERANGE; PR_SetError(PR_RANGE_ERROR, 0);
#ifdef __STDC__ #ifdef __STDC__
rv = HUGE_VAL; rv = HUGE_VAL;
#else #else
@ -1410,7 +1425,7 @@ dig_done:
if (!rv) { if (!rv) {
undfl: undfl:
rv = 0.; rv = 0.;
errno = ERANGE; PR_SetError(PR_RANGE_ERROR, 0);
if (bd0) if (bd0)
goto retfree; goto retfree;
goto ret; goto ret;
@ -1792,647 +1807,7 @@ quorem(Bigint *b, Bigint *S)
return (int)q; return (int)q;
} }
/* 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].
*
* 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.
* *
* Inspired by "How to Print Floating-Point Numbers Accurately" by * 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]. * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
@ -2467,7 +1842,7 @@ ret1:
*/ */
PR_IMPLEMENT(PRStatus) 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) int *decpt, int *sign, char **rve, char *buf, PRSize bufsize)
{ {
/* Arguments ndigits, decpt, sign are similar to those /* Arguments ndigits, decpt, sign are similar to those
@ -3123,7 +2498,7 @@ PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
return; return;
} }
/* XXX Why use mode 1? */ /* 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) { == PR_FAILURE) {
buf[0] = '\0'; buf[0] = '\0';
goto done; 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); PR_snprintf(bufp,bufsz - (bufp - buf), "%+d",decpt-1);
} }
else if(decpt >= 0){ else if(decpt >= 0){
while(decpt--){ if(decpt == 0){
*bufp++ = '0';
}
else {
while(decpt--){
if(*nump != '\0'){ if(*nump != '\0'){
*bufp++ = *nump++; *bufp++ = *nump++;
} }
else { else {
*bufp++ = '0'; *bufp++ = '0';
} }
}
} }
if(*nump != '\0'){ if(*nump != '\0'){
*bufp++ = '.'; *bufp++ = '.';

Просмотреть файл

@ -63,6 +63,8 @@ PRLock *_pr_terminationCVLock;
#endif /* !defined(_PR_PTHREADS) */ #endif /* !defined(_PR_PTHREADS) */
PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */
static void _PR_InitCallOnce(void); static void _PR_InitCallOnce(void);
static void _PR_InitStuff(void); static void _PR_InitStuff(void);
@ -114,6 +116,9 @@ static void _PR_InitStuff()
_PR_InitEnv(); _PR_InitEnv();
_PR_InitLayerCache(); _PR_InitLayerCache();
_pr_sleeplock = PR_NewLock();
PR_ASSERT(NULL != _pr_sleeplock);
_PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
#ifdef WIN16 #ifdef WIN16

Просмотреть файл

@ -78,7 +78,8 @@ static sigset_t timer_set;
#define _PR_HAVE_GETPROTO_R_POINTER #define _PR_HAVE_GETPROTO_R_POINTER
#endif #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_10) && defined(_REENTRANT)) \
|| (defined(HPUX10_20) && defined(_REENTRANT)) || (defined(HPUX10_20) && defined(_REENTRANT))
#define _PR_HAVE_GETPROTO_R #define _PR_HAVE_GETPROTO_R
@ -558,25 +559,17 @@ PR_IMPLEMENT(PRUintn) PR_NetAddrSize(const PRNetAddr* addr)
{ {
PRUintn addrsize; PRUintn addrsize;
if (AF_INET == addr->raw.family)
addrsize = sizeof(addr->inet);
#if defined(_PR_INET6) #if defined(_PR_INET6)
else if (AF_INET6 == addr->raw.family)
if ((AF_INET == (0x00ff & addr->raw.family)) addrsize = sizeof(addr->ipv6);
|| (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)
#endif #endif
#if defined(XP_UNIX)
addrsize = sizeof(struct sockaddr_in); else if (AF_UNIX == addr->raw.family)
addrsize = sizeof(addr->local);
#endif /* defined(_PR_INET6) */ #endif
else addrsize = 0;
return addrsize; return addrsize;
} /* PR_NetAddrSize */ } /* PR_NetAddrSize */

Просмотреть файл

@ -1142,7 +1142,7 @@ PR_ParseTimeString(
{ {
const char *end; const char *end;
int sign; int sign;
if (zone_offset >= 0) if (zone_offset != -1)
{ {
/* already got one... */ /* already got one... */
rest++; rest++;
@ -1196,17 +1196,13 @@ PR_ParseTimeString(
if (*end == ':') if (*end == ':')
{ {
if (hour > 0 && min > 0) /* already got it */ if (hour >= 0 && min >= 0) /* already got it */
break; break;
/* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */ /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */
if ((end - rest) > 2) if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */ /* it is [0-9][0-9][0-9]+: */
break; break;
else if (rest[1] != ':' &&
rest[2] != ':')
/* it is not [0-9]: or [0-9][0-9]: */
break;
else if ((end - rest) == 2) else if ((end - rest) == 2)
tmp_hour = ((rest[0]-'0')*10 + tmp_hour = ((rest[0]-'0')*10 +
(rest[1]-'0')); (rest[1]-'0'));
@ -1341,26 +1337,31 @@ PR_ParseTimeString(
(DD/MM/YY or MM/DD/YY or YY/MM/DD.) (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 (n2 > 12) break;
if (n3 > 31) break; if (n3 > 31) break;
year = n1; 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); month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
date = n3; date = n3;
rest = s; rest = s;
break; break;
} }
if (n3 < 70 || /* before epoch - can't represent it. */ if (n1 > 12 && n2 > 12) /* illegal */
(n1 > 12 && n2 > 12)) /* illegal */
{ {
rest = s; rest = s;
break; 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 */ 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. * these two fields.
*/ */
#if defined(SUNOS4) || defined(MACLINUX) || (__GLIBC__ >= 2) #if defined(SUNOS4) || defined(MKLINUX) || (__GLIBC__ >= 2)
if (mktime(&a) == -1) { if (mktime(&a) == -1) {
PR_snprintf(buf, buflen, "can't get timezone"); PR_snprintf(buf, buflen, "can't get timezone");
return 0; return 0;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -33,10 +33,14 @@
static pthread_condattr_t _pt_cvar_attr; 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 static pthread_t pt_zero_tid; /* a null pthread_t (pthread_t is a struct
* in DCE threads) to compare with */ * 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) 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); PR_ASSERT(0 != notified->cv[index].times);
if (-1 == notified->cv[index].times) if (-1 == notified->cv[index].times)
{ {
rv = pthread_cond_broadcast(&notified->cv[index].cv->cv); rv = pthread_cond_broadcast(&cv->cv);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
} }
else else
{ {
while (notified->cv[index].times-- > 0) while (notified->cv[index].times-- > 0)
{ {
rv = pthread_cond_signal(&notified->cv[index].cv->cv); rv = pthread_cond_signal(&cv->cv);
PR_ASSERT(0 == rv); 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; prev = notified;
notified = notified->link; notified = notified->link;
@ -123,6 +139,9 @@ PR_IMPLEMENT(PRLock*) PR_NewLock(void)
rv = PTHREAD_MUTEXATTR_DESTROY(&mattr); rv = PTHREAD_MUTEXATTR_DESTROY(&mattr);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
} }
#if defined(DEBUG)
pt_debug.locks_created += 1;
#endif
return lock; return lock;
} /* PR_NewLock */ } /* PR_NewLock */
@ -137,6 +156,7 @@ PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
#if defined(DEBUG) #if defined(DEBUG)
memset(lock, 0xaf, sizeof(PRLock)); memset(lock, 0xaf, sizeof(PRLock));
pt_debug.locks_destroyed += 1;
#endif #endif
PR_DELETE(lock); PR_DELETE(lock);
} /* PR_DestroyLock */ } /* PR_DestroyLock */
@ -151,6 +171,9 @@ PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
PR_ASSERT(NULL == lock->notified.link); PR_ASSERT(NULL == lock->notified.link);
PR_ASSERT(PTHREAD_THR_HANDLE_IS_ZERO(lock->owner)); PR_ASSERT(PTHREAD_THR_HANDLE_IS_ZERO(lock->owner));
PTHREAD_COPY_THR_HANDLE(pthread_self(), lock->owner); PTHREAD_COPY_THR_HANDLE(pthread_self(), lock->owner);
#if defined(DEBUG)
pt_debug.locks_acquired += 1;
#endif
} /* PR_Lock */ } /* PR_Lock */
PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *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); else pt_PostNotifies(lock, PR_TRUE);
#if defined(DEBUG)
pt_debug.locks_released += 1;
#endif
return PR_SUCCESS; return PR_SUCCESS;
} /* PR_Unlock */ } /* PR_Unlock */
@ -262,6 +288,7 @@ static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast)
} }
/* A brand new entry in the array */ /* A brand new entry in the array */
(void)PR_AtomicIncrement(&cvar->notify_pending);
notified->cv[index].times = (broadcast) ? -1 : 1; notified->cv[index].times = (broadcast) ? -1 : 1;
notified->cv[index].cv = cvar; notified->cv[index].cv = cvar;
notified->length += 1; notified->length += 1;
@ -279,18 +306,25 @@ PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
int rv = PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); int rv = PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
cv->lock = lock; cv->lock = lock;
cv->notify_pending = 0;
#if defined(DEBUG)
pt_debug.cvars_created += 1;
#endif
} }
return cv; return cv;
} /* PR_NewCondVar */ } /* PR_NewCondVar */
PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
{ {
int rv; if (0 > PR_AtomicDecrement(&cvar->notify_pending))
rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv); {
PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
#if defined(DEBUG) #if defined(DEBUG)
memset(cvar, 0xaf, sizeof(PRCondVar)); memset(cvar, 0xaf, sizeof(PRCondVar));
pt_debug.cvars_destroyed += 1;
#endif #endif
PR_DELETE(cvar); PR_DELETE(cvar);
}
} /* PR_DestroyCondVar */ } /* PR_DestroyCondVar */
PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)

Просмотреть файл

@ -39,6 +39,7 @@
*/ */
PRIntn pt_schedpriv; PRIntn pt_schedpriv;
extern PRLock *_pr_sleeplock;
struct _PT_Bookeeping pt_book = {0}; 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 */ /* last chance to delete this puppy if the thread is detached */
if (detached) if (detached)
{ {
if (NULL != thred->io_cv)
PR_DestroyCondVar(thred->io_cv);
PR_DELETE(thred->stack); PR_DELETE(thred->stack);
#if defined(DEBUG) #if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread)); memset(thred, 0xaf, sizeof(PRThread));
@ -448,11 +451,15 @@ PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred)
{ {
pthread_t id = thred->id; pthread_t id = thred->id;
rv = pthread_join(id, &result); rv = pthread_join(id, &result);
PR_ASSERT(rv == 0 && result == NULL);
if (0 != rv) if (0 != rv)
PR_SetError(PR_UNKNOWN_ERROR, errno); PR_SetError(PR_UNKNOWN_ERROR, errno);
if (NULL != thred->io_cv)
PR_DestroyCondVar(thred->io_cv);
PR_DELETE(thred->stack); PR_DELETE(thred->stack);
#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread)); memset(thred, 0xaf, sizeof(PRThread));
PR_ASSERT(result == NULL); #endif
PR_DELETE(thred); PR_DELETE(thred);
} }
return (0 == rv) ? PR_SUCCESS : PR_FAILURE; return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
@ -481,10 +488,14 @@ PR_IMPLEMENT(void) PR_DetachThread()
thred->next->prev = thred->prev; thred->next->prev = thred->prev;
PR_Unlock(pt_book.ml); PR_Unlock(pt_book.ml);
if (NULL != thred->io_cv)
PR_DestroyCondVar(thred->io_cv);
rv = pthread_setspecific(pt_book.key, NULL); rv = pthread_setspecific(pt_book.key, NULL);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
PR_DELETE(thred->stack); PR_DELETE(thred->stack);
#if defined(DEBUG)
memset(thred, 0xaf, sizeof(PRThread)); memset(thred, 0xaf, sizeof(PRThread));
#endif
PR_DELETE(thred); PR_DELETE(thred);
} }
} /* PR_DetachThread */ } /* PR_DetachThread */
@ -612,17 +623,27 @@ PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred)
** I don't expect very many threads to be waiting on ** I don't expect very many threads to be waiting on
** a single condition and I don't expect interrupt to ** a single condition and I don't expect interrupt to
** be used very often. ** 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; PRCondVar *cv;
PR_ASSERT(thred != NULL); PR_ASSERT(NULL != thred);
if (NULL == thred) return PR_FAILURE;
thred->state |= PT_THREAD_ABORTED; 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()); PRIntn rv = pthread_cond_broadcast(&cv->cv);
if (!haveLock) PR_Lock(victim->lock); PR_ASSERT(0 == rv);
PR_NotifyAllCondVar(victim);
if (!haveLock) PR_Unlock(victim->lock);
} }
return PR_SUCCESS; return PR_SUCCESS;
} /* PR_Interrupt */ } /* PR_Interrupt */
@ -654,11 +675,11 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
} }
else else
{ {
PRCondVar *cv = PR_NewCondVar(pt_book.ml); PRCondVar *cv = PR_NewCondVar(_pr_sleeplock);
PR_ASSERT(cv != NULL); PR_ASSERT(cv != NULL);
PR_Lock(pt_book.ml); PR_Lock(_pr_sleeplock);
rv = PR_WaitCondVar(cv, ticks); rv = PR_WaitCondVar(cv, ticks);
PR_Unlock(pt_book.ml); PR_Unlock(_pr_sleeplock);
PR_DestroyCondVar(cv); PR_DestroyCondVar(cv);
} }
return rv; return rv;
@ -1252,7 +1273,9 @@ PR_IMPLEMENT(void) PR_SuspendAll()
{ {
PRIntn rv; PRIntn rv;
#ifdef DEBUG
suspendAllOn = PR_TRUE; suspendAllOn = PR_TRUE;
#endif
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n")); 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 * 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); rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
#ifdef DEBUG
suspendAllOn = PR_FALSE; suspendAllOn = PR_FALSE;
#endif
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n")); PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n"));
} /* PR_ResumeAll */ } /* PR_ResumeAll */

Просмотреть файл

@ -26,7 +26,7 @@
** Notify one thread that it has finished waiting on a condition variable ** Notify one thread that it has finished waiting on a condition variable
** Caller must hold the _PR_CVAR_LOCK(cv) ** Caller must hold the _PR_CVAR_LOCK(cv)
*/ */
PRBool NotifyThread (PRThread *thread, PRThread *me) PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
{ {
PRBool rv; 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)); PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
#endif #endif
if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) { 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; break;
} }
q = q->next; q = q->next;
@ -381,7 +381,7 @@ void _PR_ClockInterrupt(void)
if (thread->wait.cvar) { if (thread->wait.cvar) {
PRThreadPriority pri; 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) ); PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
/* Make thread runnable */ /* Make thread runnable */
@ -545,7 +545,7 @@ PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
q = cvar->condQ.next; q = cvar->condQ.next;
while (q != &cvar->condQ) { while (q != &cvar->condQ) {
PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); 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; q = q->next;
} }
_PR_CVAR_UNLOCK(cvar); _PR_CVAR_UNLOCK(cvar);
@ -623,7 +623,7 @@ PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
q = cvar->condQ.next; q = cvar->condQ.next;
while (q != &cvar->condQ) { while (q != &cvar->condQ) {
PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); 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; q = q->next;
} }
_PR_MD_UNLOCK( &(cvar->ilock) ); _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 add this thread thread in the right priority order so when the unlock
occurs, the thread with the higher priority will get the lock. occurs, the thread with the higher priority will get the lock.
*/ */
/* Sort thread into lock's waitQ at appropriate point */
q = lock->waitQ.next; q = lock->waitQ.next;
if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority ==
/* Now scan the list for where to insert this entry */ _PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) {
while (q != &lock->waitQ) { /*
t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next); * If all the threads in the lock waitQ have the same priority,
if (me->priority > t->priority) { * then avoid scanning the list: insert the element at the end.
/* Found a lower priority thread to insert in front of */ */
break; q = &lock->waitQ;
} } else {
q = q->next; /* 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); PR_INSERT_BEFORE(&me->waitQLinks, q);
/* /*

Просмотреть файл

@ -121,7 +121,10 @@ void _PR_InitThreads(PRThreadType type, PRThreadPriority priority,
thread->flags |= _PR_PRIMORDIAL; thread->flags |= _PR_PRIMORDIAL;
#endif #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) { if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
/* /*
* XXX do what? * XXX do what?
@ -724,7 +727,7 @@ static void _PR_Resume(PRThread *thread)
} }
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) #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; PRThread *thread;
PRIntn pri; PRIntn pri;
@ -755,16 +758,20 @@ static PRThread *get_thread(_PRCPU *cpu)
PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
if (thread->no_sched){ if (thread->no_sched){
thread = NULL; thread = NULL;
/* /*
* Need to wakeup cpus to avoid missing a * Need to wakeup cpus to avoid missing a
* runnable thread * runnable thread
*/ * Waking up all CPU's need happen only once.
_PR_MD_WAKEUP_CPUS(); */
*wakeup_cpus = PR_TRUE;
continue; continue;
} else if (thread->io_pending == PR_TRUE) { } else if (thread->io_pending == PR_TRUE) {
/* /*
* A thread that is blocked for I/O needs to run * 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; thread = NULL;
continue; continue;
@ -772,7 +779,7 @@ static PRThread *get_thread(_PRCPU *cpu)
/* Pull thread off of its run queue */ /* Pull thread off of its run queue */
_PR_DEL_RUNQ(thread); _PR_DEL_RUNQ(thread);
_PR_RUNQ_UNLOCK(cpu); _PR_RUNQ_UNLOCK(cpu);
return(thread); return(thread);
} }
} }
} }
@ -800,6 +807,9 @@ void _PR_Schedule(void)
PRUint32 r; PRUint32 r;
PRCList *qp; PRCList *qp;
PRIntn priMin, priMax; PRIntn priMin, priMax;
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
PRBool wakeup_cpus;
#endif
/* Interrupts must be disabled */ /* Interrupts must be disabled */
PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
@ -869,17 +879,25 @@ void _PR_Schedule(void)
_PR_RUNQ_UNLOCK(cpu); _PR_RUNQ_UNLOCK(cpu);
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) #if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
wakeup_cpus = PR_FALSE;
_PR_CPU_LIST_LOCK(); _PR_CPU_LIST_LOCK();
for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
if (cpu != _PR_CPU_PTR(qp)) { if (cpu != _PR_CPU_PTR(qp)) {
if ((thread = get_thread(_PR_CPU_PTR(qp))) != NULL) { if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus))
thread->cpu = cpu; != NULL) {
_PR_CPU_LIST_UNLOCK(); thread->cpu = cpu;
goto found_thread; _PR_CPU_LIST_UNLOCK();
} if (wakeup_cpus == PR_TRUE)
_PR_MD_WAKEUP_CPUS();
goto found_thread;
}
} }
} }
_PR_CPU_LIST_UNLOCK(); _PR_CPU_LIST_UNLOCK();
if (wakeup_cpus == PR_TRUE)
_PR_MD_WAKEUP_CPUS();
#endif /* _PR_LOCAL_THREADS_ONLY */ #endif /* _PR_LOCAL_THREADS_ONLY */
idle_thread: idle_thread:

Просмотреть файл

@ -18,6 +18,7 @@
#include "primpl.h" #include "primpl.h"
extern PRLock *_pr_sleeplock; /* allocated and initialized in prinit */
/* /*
** Routines common to both native and user threads. ** Routines common to both native and user threads.
** **
@ -85,8 +86,7 @@ PR_IMPLEMENT(PRStatus) PR_Yield()
*/ */
PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout) 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) 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 ** but the lock and cvar used are local to the implementation
** and not visible to the caller, therefore not notifiable. ** 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; PR_Lock(_pr_sleeplock);
else while (rv == PR_SUCCESS)
{ {
PRCondVar *cv = PR_NewCondVar(ml); PRIntervalTime delta = PR_IntervalNow() - timein;
PRIntervalTime timein = PR_IntervalNow(); if (delta > timeout) break;
rv = PR_WaitCondVar(cv, timeout - delta);
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);
} }
PR_Unlock(_pr_sleeplock);
PR_DestroyCondVar(cv);
} }
return rv; return rv;
} }
PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread) PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread)

Просмотреть файл

@ -104,7 +104,7 @@ void _PR_DumpThreads(PRFileDesc *fd)
DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu)); DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu));
} }
void PR_ShowStatus(void) PR_IMPLEMENT(void) PR_ShowStatus(void)
{ {
PRIntn is; PRIntn is;

Просмотреть файл

@ -75,7 +75,7 @@ extern void SetupMacPrintfLog(char *logFile);
#endif #endif
PRIntervalTime timeoutTime; PRIntervalTime timeoutTime;
static PRInt32 count = 10; static PRInt32 count = 1;
static PRNetAddr serverAddr; static PRNetAddr serverAddr;
static PRThreadScope thread_scope = PR_LOCAL_THREAD; static PRThreadScope thread_scope = PR_LOCAL_THREAD;
@ -118,9 +118,9 @@ ClientThread(void *_action)
PRInt32 iterations = count; PRInt32 iterations = count;
PRFileDesc *sock = NULL; PRFileDesc *sock = NULL;
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(BASE_PORT); serverAddr.inet.port = PR_htons(BASE_PORT);
serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
for (; iterations--;) { for (; iterations--;) {
PRInt32 rv; PRInt32 rv;
@ -201,29 +201,26 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
/* First bind to the socket */ /* First bind to the socket */
listenSock = PR_NewTCPSocket(); listenSock = PR_NewTCPSocket();
if (!listenSock) { if (!listenSock) {
if (!debug_mode) failed_already=1;
failed_already=1; if (debug_mode)
else
printf("unable to create listen socket\n"); printf("unable to create listen socket\n");
return; return;
} }
listenAddr.inet.family = AF_INET; listenAddr.inet.family = PR_AF_INET;
listenAddr.inet.port = PR_htons(BASE_PORT); 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); rv = PR_Bind(listenSock, &listenAddr);
if (rv == PR_FAILURE) { if (rv == PR_FAILURE) {
if (!debug_mode) failed_already=1;
failed_already=1; if (debug_mode)
else
printf("unable to bind\n"); printf("unable to bind\n");
return; return;
} }
rv = PR_Listen(listenSock, 100); rv = PR_Listen(listenSock, 100);
if (rv == PR_FAILURE) { if (rv == PR_FAILURE) {
if (!debug_mode) failed_already=1;
failed_already=1; if (debug_mode)
else
printf("unable to listen\n"); printf("unable to listen\n");
return; return;
} }
@ -233,9 +230,8 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
(void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope, (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
PR_JOINABLE_THREAD, 0); PR_JOINABLE_THREAD, 0);
if (!clientThread) { if (!clientThread) {
if (!debug_mode) failed_already=1;
failed_already=1; if (debug_mode)
else
printf("error creating client thread\n"); printf("error creating client thread\n");
return; return;
} }
@ -470,7 +466,6 @@ int main(int argc, char **argv)
} }
PL_DestroyOptState(opt); PL_DestroyOptState(opt);
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
PR_STDIO_INIT(); PR_STDIO_INIT();
@ -495,9 +490,9 @@ int main(int argc, char **argv)
#ifdef WINNT #ifdef WINNT
Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
#endif #endif
Measure(TimeoutReadUpdatedTest, "PR_Accept()");
if (debug_mode) if (debug_mode)
printf("\nRun accept() timeout in the read tests\n"); printf("\nRun accept() timeout in the read tests\n");
Measure(TimeoutReadUpdatedTest, "PR_Accept()");
Measure(TimeoutReadReadTest, "PR_AcceptRead()"); Measure(TimeoutReadReadTest, "PR_AcceptRead()");
#ifdef WINNT #ifdef WINNT
Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()"); Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");

Просмотреть файл

@ -239,7 +239,7 @@ static PRIntervalTime Alarms1(PRUint32 loops)
PRAlarm *alarm; PRAlarm *alarm;
AlarmData ad; AlarmData ad;
PRIntervalTime overhead, timein = PR_IntervalNow(); PRIntervalTime overhead, timein = PR_IntervalNow();
PRIntervalTime duration = PR_SecondsToInterval(30); PRIntervalTime duration = PR_SecondsToInterval(3);
PRLock *ml = PR_NewLock(); PRLock *ml = PR_NewLock();
PRCondVar *cv = PR_NewCondVar(ml); PRCondVar *cv = PR_NewCondVar(ml);
@ -469,7 +469,7 @@ static PRUint32 TimeThis(
int prmain(int argc, char** argv) 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 /* 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. 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); PL_DestroyOptState(opt);
if (cpus == 0) cpus = 2; if (cpus == 0) cpus = 1;
if (loops == 0) loops = 100; if (loops == 0) loops = 4;
if (debug_mode) if (debug_mode)
printf("Alarm: Using %d loops\n", loops); printf("Alarm: Using %d loops\n", loops);

Просмотреть файл

@ -59,6 +59,7 @@ PRIntn main(PRIntn argc, char **argv)
output, "PR_AtomicDecrement(%d) == %d: %s\n", output, "PR_AtomicDecrement(%d) == %d: %s\n",
test, rv, (rv < 0) ? "PASSED" : "FAILED"); test, rv, (rv < 0) ? "PASSED" : "FAILED");
/* set to a different value */
test = -2; test = -2;
rv = PR_AtomicSet(&test, 2); rv = PR_AtomicSet(&test, 2);
result = result | (((rv == -2) && (test == 2)) ? 0 : 1); 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", output, "PR_AtomicSet(%d) == %d: %s\n",
test, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); 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( PR_fprintf(
output, "Atomic operations test %s\n", output, "Atomic operations test %s\n",
(result == 0) ? "PASSED" : "FAILED"); (result == 0) ? "PASSED" : "FAILED");

Просмотреть файл

@ -48,16 +48,9 @@
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #ifdef WIN32
#include "process.h" #include <windows.h>
#include <process.h>
#elif defined(_PR_PTHREADS) #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 <pthread.h>
#include "md/_pth.h" #include "md/_pth.h"
#elif defined(IRIX) #elif defined(IRIX)

Просмотреть файл

@ -867,31 +867,16 @@ static void PR_CALLBACK Server(void *arg)
} /* Server */ } /* Server */
#if 0 && defined(DEBUG) && defined(_PR_PTHREADS) #if defined(DEBUG) && defined(_PR_PTHREADS)
static void PrintPthreadStats(void) static void PrintPthreadStats(void)
{ {
char buffer[100]; PT_FPrintStats(debug_out, "\nPThread Statistics\n");
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);
} /* PrintPthreadStats */ } /* PrintPthreadStats */
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */ #endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
static void WaitForCompletion(PRIntn execution) static void WaitForCompletion(PRIntn execution)
{ {
#if 0 && defined(DEBUG) && defined(_PR_PTHREADS) #if defined(DEBUG) && defined(_PR_PTHREADS)
while (execution > 0) while (execution > 0)
{ {
PRIntn dally = (execution > 30) ? 30 : execution; PRIntn dally = (execution > 30) ? 30 : execution;
@ -930,7 +915,8 @@ static Verbosity IncrementVerbosity(void)
PRIntn verboge = (PRIntn)verbosity + 1; PRIntn verboge = (PRIntn)verbosity + 1;
return (Verbosity)verboge; return (Verbosity)verboge;
} /* IncrementVerbosity */ } /* IncrementVerbosity */
PRIntn xmain(PRIntn argc, char** argv)
PRIntn main(PRIntn argc, char** argv)
{ {
PRUintn index; PRUintn index;
PRBool boolean; PRBool boolean;
@ -960,7 +946,7 @@ PRIntn xmain(PRIntn argc, char** argv)
*/ */
PLOptStatus os; 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); debug_out = PR_GetSpecialFD(PR_StandardError);
@ -990,8 +976,6 @@ PRIntn xmain(PRIntn argc, char** argv)
case 'c': /* number of client threads */ case 'c': /* number of client threads */
clients = atoi(opt->value); clients = atoi(opt->value);
break; break;
case 'l': /* number of outer loops */
break;
case 'w': /* minimum server worker threads */ case 'w': /* minimum server worker threads */
workersMin = atoi(opt->value); workersMin = atoi(opt->value);
break; break;
@ -1212,40 +1196,12 @@ PRIntn xmain(PRIntn argc, char** argv)
cltsrv_log_file, TEST_LOG_ALWAYS, cltsrv_log_file, TEST_LOG_ALWAYS,
("main(0x%lx): test complete\n", PR_CurrentThread())); ("main(0x%lx): test complete\n", PR_CurrentThread()));
#if 0 && defined(DEBUG) && defined(_PR_PTHREADS) #if defined(DEBUG) && defined(_PR_PTHREADS)
PrintPthreadStats(); PrintPthreadStats();
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */ #endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
TimeOfDayMessage("Test exiting at", PR_CurrentThread()); TimeOfDayMessage("Test exiting at", PR_CurrentThread());
return 0; 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 */ } /* main */
/* cltsrv.c */ /* cltsrv.c */

Просмотреть файл

@ -194,8 +194,8 @@ void PR_CALLBACK Intrupt(void *arg)
if (debug_mode) printf("Part III\n"); if (debug_mode) printf("Part III\n");
listner = PR_NewTCPSocket(); listner = PR_NewTCPSocket();
memset(&netaddr, 0, sizeof(netaddr)); memset(&netaddr, 0, sizeof(netaddr));
netaddr.inet.ip = PR_htonl(INADDR_ANY); netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
netaddr.inet.family = AF_INET; netaddr.inet.family = PR_AF_INET;
do do
{ {
netaddr.inet.port = PR_htons(port); netaddr.inet.port = PR_htons(port);

Просмотреть файл

@ -75,9 +75,9 @@ thread_main(void *_info)
goto dead; goto dead;
} }
listenAddr.inet.family = AF_INET; listenAddr.inet.family = PR_AF_INET;
listenAddr.inet.port = PR_htons(BASE_PORT + info->id); 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); rv = PR_Bind(listenSock, &listenAddr);
if (rv == PR_FAILURE) { if (rv == PR_FAILURE) {
printf("unable to bind\n"); printf("unable to bind\n");

Просмотреть файл

@ -65,6 +65,7 @@ static PRStatus PrintAddress(const PRNetAddr* address)
else else
{ {
PR_fprintf(err, "\t%s\n", buffer); PR_fprintf(err, "\t%s\n", buffer);
memset(&translation, 0, sizeof(translation));
rv = PR_StringToNetAddr(buffer, &translation); rv = PR_StringToNetAddr(buffer, &translation);
if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr"); if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr");
else else

Просмотреть файл

@ -61,7 +61,7 @@ static PRFileDesc *PushLayer(PRFileDesc *stack)
if (verbosity > quiet) if (verbosity > quiet)
PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
PR_ASSERT(PR_SUCCESS == rv); PR_ASSERT(PR_SUCCESS == rv);
return layer; return stack;
} /* PushLayer */ } /* PushLayer */
static PRFileDesc *PopLayer(PRFileDesc *stack) static PRFileDesc *PopLayer(PRFileDesc *stack)
@ -149,19 +149,91 @@ static void PR_CALLBACK Server(void *arg)
} /* Server */ } /* 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) static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
{ {
PRIntn verbage = (PRIntn)verbosity; PRIntn verbage = (PRIntn)verbosity + delta;
return (Verbosity)(verbage + delta); if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
return (Verbosity)verbage;
} /* ChangeVerbosity */ } /* ChangeVerbosity */
PRIntn main(PRIntn argc, char **argv) PRIntn main(PRIntn argc, char **argv)
{ {
PRStatus rv; PRStatus rv;
PRIntn mits;
PLOptStatus os; PLOptStatus os;
PRFileDesc *client, *service; PRFileDesc *client, *service;
const char *server_name = NULL; const char *server_name = NULL;
PRIOMethods const *stubMethods; const PRIOMethods *stubMethods;
PRThread *client_thread, *server_thread; PRThread *client_thread, *server_thread;
PRThreadScope thread_scope = PR_LOCAL_THREAD; PRThreadScope thread_scope = PR_LOCAL_THREAD;
PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
@ -206,11 +278,13 @@ PRIntn main(PRIntn argc, char **argv)
stubMethods = PR_GetDefaultIOMethods(); stubMethods = PR_GetDefaultIOMethods();
/* /*
** Normally here one would pick and choose between the default ** The protocol we're going to implement is one where in order to initiate
** stub methods and local, unique implmentation. I'm not going ** a send, the sender must first solicit permission. Therefore, every
** quite that far. ** 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) if (NULL == server_name)
rv = PR_InitializeNetAddr( rv = PR_InitializeNetAddr(
@ -226,6 +300,7 @@ PRIntn main(PRIntn argc, char **argv)
/* one type w/o layering */ /* one type w/o layering */
mits = minor_iterations;
while (major_iterations-- > 0) while (major_iterations-- > 0)
{ {
if (verbosity > silent) if (verbosity > silent)
@ -233,6 +308,7 @@ PRIntn main(PRIntn argc, char **argv)
client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
minor_iterations = mits;
server_thread = PR_CreateThread( server_thread = PR_CreateThread(
PR_USER_THREAD, Server, service, PR_USER_THREAD, Server, service,
PR_PRIORITY_HIGH, thread_scope, PR_PRIORITY_HIGH, thread_scope,
@ -261,6 +337,7 @@ PRIntn main(PRIntn argc, char **argv)
client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
minor_iterations = mits;
server_thread = PR_CreateThread( server_thread = PR_CreateThread(
PR_USER_THREAD, Server, PushLayer(service), PR_USER_THREAD, Server, PushLayer(service),
PR_PRIORITY_HIGH, thread_scope, PR_PRIORITY_HIGH, thread_scope,

Просмотреть файл

@ -24,10 +24,18 @@
#include "prlog.h" #include "prlog.h"
#include "prmem.h" #include "prmem.h"
#include "primpl.h"
#include "plgetopt.h" #include "plgetopt.h"
#include <stdlib.h> #include <stdlib.h>
static PRInt32 Random(void)
{
PRInt32 ran = rand() >> 16;
return ran;
} /* Random */
static void Help(void) static void Help(void)
{ {
PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
@ -43,15 +51,19 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
PRIntn index, nl; PRIntn index, nl;
PRLock *ml = NULL; PRLock *ml = NULL;
PRCondVar **cv = 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); 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))) while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
{ {
if (PL_OPT_BAD == os) continue; if (PL_OPT_BAD == os) continue;
switch (opt->option) 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 */ case 'c': /* number of CVs to association with lock */
cvs = atoi(opt->value); cvs = atoi(opt->value);
break; break;
@ -86,7 +98,12 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
{ {
PR_Lock(ml); PR_Lock(ml);
for (nl = 0; nl < cvs; ++nl) 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); PR_Unlock(ml);
} }
@ -97,6 +114,9 @@ static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
printf("PASS\n"); printf("PASS\n");
#if defined(DEBUG) && defined(_PR_PTHREADS)
PT_FPrintStats(err, "\nPThread Statistics\n");
#endif /* defined(DEBUG) && defined(_PR_PTHREADS) */
return 0; return 0;
} }

Просмотреть файл

@ -74,9 +74,9 @@ clientThreadFunc(void *arg)
PRStatus retVal; PRStatus retVal;
PRInt32 nBytes; PRInt32 nBytes;
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port); 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); PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
/* time 1 */ /* 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"); fprintf(stderr, "Can't create a new TCP socket\n");
exit(1); exit(1);
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock, &addr) == PR_FAILURE) { if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");

Просмотреть файл

@ -85,9 +85,9 @@ clientThreadFunc(void *arg)
PRStatus sts; PRStatus sts;
PRInt32 n; PRInt32 n;
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port); 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)); memset(buf, 0, sizeof(buf));
PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip); PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
@ -162,8 +162,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");
@ -188,8 +188,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");

Просмотреть файл

@ -105,8 +105,8 @@ int main(int argc, char **argv)
if (!debug_mode) failed_already=1; if (!debug_mode) failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");
@ -130,8 +130,8 @@ int main(int argc, char **argv)
if (!debug_mode) failed_already=1; if (!debug_mode) failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");

Просмотреть файл

@ -21,6 +21,11 @@
* Purpose: testing priorities * Purpose: testing priorities
*/ */
#ifdef XP_MAC
#error "This test does not run on Macintosh"
#else
#include "prcmon.h" #include "prcmon.h"
#include "prinit.h" #include "prinit.h"
#include "prinrval.h" #include "prinrval.h"
@ -37,22 +42,12 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.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 #define DEFAULT_DURATION 20
static PRBool failed = PR_FALSE; static PRBool failed = PR_FALSE;
static PRIntervalTime oneSecond; static PRIntervalTime oneSecond;
static PRFileDesc *debug_out = NULL; static PRFileDesc *debug_out = NULL;
static PRBool debug_mode = PR_FALSE;
static PRUint32 PerSecond(PRIntervalTime timein) static PRUint32 PerSecond(PRIntervalTime timein)
{ {
@ -96,22 +91,63 @@ static void Help(void)
debug_out, "-d\tturn on debugging output (default: FALSE)\n"); debug_out, "-d\tturn on debugging output (default: FALSE)\n");
} /* Help */ } /* 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) PRIntn main(PRIntn argc, char **argv)
{ {
PLOptStatus os; PLOptStatus os;
PRThread *low, *high;
PRThreadPriority priority;
PRBool debug_mode = PR_FALSE;
PRIntn duration = DEFAULT_DURATION; PRIntn duration = DEFAULT_DURATION;
PRUint32 totalCount, highCount = 0, lowCount = 0; PRUint32 totalCount, highCount = 0, lowCount = 0;
PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:"); PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
#ifdef XP_MAC
SetupMacPrintfLog("priotest.log");
debug_mode = PR_TRUE;
#endif
debug_out = PR_STDOUT; debug_out = PR_STDOUT;
oneSecond = PR_SecondsToInterval(1); oneSecond = PR_SecondsToInterval(1);
@ -137,53 +173,13 @@ PRIntn main(PRIntn argc, char **argv)
if (duration == 0) duration = DEFAULT_DURATION; if (duration == 0) duration = DEFAULT_DURATION;
RudimentaryTests();
printf("Priority test: running for %d seconds\n\n", duration); printf("Priority test: running for %d seconds\n\n", duration);
(void)PerSecond(PR_IntervalNow()); (void)PerSecond(PR_IntervalNow());
totalCount = 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); PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
if (debug_mode) if (debug_mode)
@ -195,27 +191,8 @@ PRIntn main(PRIntn argc, char **argv)
PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount); 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; duration = (duration + 4) / 5;
CreateThreads(&lowCount, &highCount);
while (duration--) while (duration--)
{ {
PRIntn loop = 5; 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_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
} }
PR_ProcessExit((failed) ? 1 : 0); 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 */ return 1; /* or here */
} /* main */ } /* main */
#endif /* ifdef XP_MAC */
/* priotest.c */ /* priotest.c */

Просмотреть файл

@ -284,7 +284,7 @@ int main (int argc, char *argv[])
debug_mode = 1; debug_mode = 1;
break; break;
case 'l': /* limiting number */ case 'l': /* limiting number */
limit = limit = atoi(opt->value); limit = atoi(opt->value);
break; break;
case 't': /* number of threads */ case 't': /* number of threads */
threads = atoi(opt->value); threads = atoi(opt->value);

Просмотреть файл

@ -153,10 +153,10 @@ _server_thread(void *arg_id)
goto done; goto done;
} }
memset(&sa, 0 , PR_NETADDR_SIZE(&sa)); memset(&sa, 0 , sizeof(sa));
sa.inet.family = AF_INET; sa.inet.family = PR_AF_INET;
sa.inet.port = PORT_BASE + *id; 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) { if ( PR_Bind(sock, &sa) < 0) {
fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno); 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; goto done;
} }
memset(&sa, 0 , PR_NETADDR_SIZE(&sa)); memset(&sa, 0 , sizeof(sa));
rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa); rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa);
PR_ASSERT(PR_SUCCESS == rv); PR_ASSERT(PR_SUCCESS == rv);

Просмотреть файл

@ -51,6 +51,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
PRIntn failed_already=0; PRIntn failed_already=0;
PRIntn debug_mode; PRIntn debug_mode;
@ -63,9 +64,9 @@ clientThreadFunc(void *arg)
char buf[128]; char buf[128];
int i; int i;
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.port = PR_htons((PRUint16)port); 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); PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
@ -127,8 +128,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");
@ -152,8 +153,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");

Просмотреть файл

@ -103,8 +103,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");
@ -128,8 +128,8 @@ int main(int argc, char **argv)
failed_already=1; failed_already=1;
goto exit_now; goto exit_now;
} }
addr.inet.family = AF_INET; addr.inet.family = PR_AF_INET;
addr.inet.ip = PR_htonl(INADDR_ANY); addr.inet.ip = PR_htonl(PR_INADDR_ANY);
addr.inet.port = PR_htons(0); addr.inet.port = PR_htons(0);
if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
fprintf(stderr, "Can't bind socket\n"); fprintf(stderr, "Can't bind socket\n");

Просмотреть файл

@ -232,9 +232,9 @@ ServerSetup(void)
} }
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); 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 ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", 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"); if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.port = PR_htons(PORT);
serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) { while(numRequests > 0) {

Просмотреть файл

@ -233,9 +233,9 @@ ServerSetup(void)
} }
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); 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 ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", 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"); if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.port = PR_htons(PORT);
serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) { while(numRequests > 0) {

Просмотреть файл

@ -235,9 +235,9 @@ ServerSetup(void)
} }
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); 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 ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", 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"); if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.port = PR_htons(PORT);
serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) { while(numRequests > 0) {

Просмотреть файл

@ -233,9 +233,9 @@ ServerSetup(void)
} }
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); 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 ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", 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"); if (debug_mode) printf("\tClient could not malloc space!?\n");
memset(&serverAddr, 0, sizeof(PRNetAddr)); memset(&serverAddr, 0, sizeof(PRNetAddr));
serverAddr.inet.family = AF_INET; serverAddr.inet.family = PR_AF_INET;
serverAddr.inet.port = PR_htons(PORT); serverAddr.inet.port = PR_htons(PORT);
serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
while(numRequests > 0) { while(numRequests > 0) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше