mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
update NSPR to 4.24 and keep NSPR Bug 1586070 and win64 patch intact.
This commit is contained in:
parent
dd094ae552
commit
0b9855b841
487 changed files with 42933 additions and 48679 deletions
|
|
@ -1,2 +0,0 @@
|
|||
Makefile
|
||||
_pr_bld.h
|
||||
|
|
@ -66,13 +66,6 @@ endif
|
|||
endif # sparc
|
||||
endif # SunOS
|
||||
|
||||
ifeq ($(OS_ARCH), IRIX)
|
||||
ifeq ($(USE_PTHREADS), 1)
|
||||
OS_LIBS = -lpthread
|
||||
endif
|
||||
OS_LIBS += -lc
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),AIX)
|
||||
DSO_LDOPTS += -binitfini::_PR_Fini
|
||||
OS_LIBS = -lodm -lcfg
|
||||
|
|
@ -109,15 +102,6 @@ GARBAGE += $(MAPFILE)
|
|||
MKSHLIB += $(MAPFILE)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),OSF1)
|
||||
ifeq ($(USE_PTHREADS), 1)
|
||||
OS_LIBS = -lpthread -lrt
|
||||
endif
|
||||
ifneq ($(OS_RELEASE),V2.0)
|
||||
OS_LIBS += -lc_r
|
||||
endif
|
||||
endif
|
||||
|
||||
# Linux, GNU/Hurd, and GNU/kFreeBSD systems
|
||||
ifneq (,$(filter Linux GNU%,$(OS_ARCH)))
|
||||
ifeq ($(USE_PTHREADS), 1)
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
#! gmake
|
||||
|
||||
MOD_DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(MOD_DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(srcdir)/bsrcs.mk
|
||||
CSRCS += $(BTCSRCS)
|
||||
|
||||
TARGETS = $(OBJS)
|
||||
|
||||
INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_NSPR_BUILD_
|
||||
|
||||
export:: $(TARGETS)
|
||||
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# this file lists the source files to be compiled (used in Makefile) and
|
||||
# then enumerated as object files (in objs.mk) for inclusion in the NSPR
|
||||
# shared library
|
||||
|
||||
BTCSRCS = \
|
||||
btthread.c \
|
||||
btlocks.c \
|
||||
btcvar.c \
|
||||
btmon.c \
|
||||
btsem.c \
|
||||
btmisc.c \
|
||||
$(NULL)
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
** Create a new condition variable.
|
||||
**
|
||||
** "lock" is the lock used to protect the condition variable.
|
||||
**
|
||||
** Condition variables are synchronization objects that threads can use
|
||||
** to wait for some condition to occur.
|
||||
**
|
||||
** This may fail if memory is tight or if some operating system resource
|
||||
** is low. In such cases, a NULL will be returned.
|
||||
*/
|
||||
PR_IMPLEMENT(PRCondVar*)
|
||||
PR_NewCondVar (PRLock *lock)
|
||||
{
|
||||
PRCondVar *cv = PR_NEW( PRCondVar );
|
||||
PR_ASSERT( NULL != lock );
|
||||
if( NULL != cv )
|
||||
{
|
||||
cv->lock = lock;
|
||||
cv->sem = create_sem(0, "CVSem");
|
||||
cv->handshakeSem = create_sem(0, "CVHandshake");
|
||||
cv->signalSem = create_sem( 0, "CVSignal");
|
||||
cv->signalBenCount = 0;
|
||||
cv->ns = cv->nw = 0;
|
||||
PR_ASSERT( cv->sem >= B_NO_ERROR );
|
||||
PR_ASSERT( cv->handshakeSem >= B_NO_ERROR );
|
||||
PR_ASSERT( cv->signalSem >= B_NO_ERROR );
|
||||
}
|
||||
return cv;
|
||||
} /* PR_NewCondVar */
|
||||
|
||||
/*
|
||||
** Destroy a condition variable. There must be no thread
|
||||
** waiting on the condvar. The caller is responsible for guaranteeing
|
||||
** that the condvar is no longer in use.
|
||||
**
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DestroyCondVar (PRCondVar *cvar)
|
||||
{
|
||||
status_t result = delete_sem( cvar->sem );
|
||||
PR_ASSERT( result == B_NO_ERROR );
|
||||
|
||||
result = delete_sem( cvar->handshakeSem );
|
||||
PR_ASSERT( result == B_NO_ERROR );
|
||||
|
||||
result = delete_sem( cvar->signalSem );
|
||||
PR_ASSERT( result == B_NO_ERROR );
|
||||
|
||||
PR_DELETE( cvar );
|
||||
}
|
||||
|
||||
/*
|
||||
** The thread that waits on a condition is blocked in a "waiting on
|
||||
** condition" state until another thread notifies the condition or a
|
||||
** caller specified amount of time expires. The lock associated with
|
||||
** the condition variable will be released, which must have be held
|
||||
** prior to the call to wait.
|
||||
**
|
||||
** Logically a notified thread is moved from the "waiting on condition"
|
||||
** state and made "ready." When scheduled, it will attempt to reacquire
|
||||
** the lock that it held when wait was called.
|
||||
**
|
||||
** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and
|
||||
** PR_INTERVAL_NO_WAIT. The former value requires that a condition be
|
||||
** notified (or the thread interrupted) before it will resume from the
|
||||
** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect
|
||||
** is to release the lock, possibly causing a rescheduling within the
|
||||
** runtime, then immediately attempting to reacquire the lock and resume.
|
||||
**
|
||||
** Any other value for timeout will cause the thread to be rescheduled
|
||||
** either due to explicit notification or an expired interval. The latter
|
||||
** must be determined by treating time as one part of the monitored data
|
||||
** being protected by the lock and tested explicitly for an expired
|
||||
** interval.
|
||||
**
|
||||
** Returns PR_FAILURE if the caller has not locked the lock associated
|
||||
** with the condition variable or the thread was interrupted (PR_Interrupt()).
|
||||
** The particular reason can be extracted with PR_GetError().
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout)
|
||||
{
|
||||
status_t err;
|
||||
if( timeout == PR_INTERVAL_NO_WAIT )
|
||||
{
|
||||
PR_Unlock( cvar->lock );
|
||||
PR_Lock( cvar->lock );
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
if( atomic_add( &cvar->signalBenCount, 1 ) > 0 )
|
||||
{
|
||||
if (acquire_sem(cvar->signalSem) == B_INTERRUPTED)
|
||||
{
|
||||
atomic_add( &cvar->signalBenCount, -1 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
cvar->nw += 1;
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
PR_Unlock( cvar->lock );
|
||||
if( timeout==PR_INTERVAL_NO_TIMEOUT )
|
||||
{
|
||||
err = acquire_sem(cvar->sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) );
|
||||
}
|
||||
|
||||
if( atomic_add( &cvar->signalBenCount, 1 ) > 0 )
|
||||
{
|
||||
while (acquire_sem(cvar->signalSem) == B_INTERRUPTED);
|
||||
}
|
||||
|
||||
if (cvar->ns > 0)
|
||||
{
|
||||
release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
cvar->ns -= 1;
|
||||
}
|
||||
cvar->nw -= 1;
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
PR_Lock( cvar->lock );
|
||||
if(err!=B_NO_ERROR)
|
||||
{
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
** Notify ONE thread that is currently waiting on 'cvar'. Which thread is
|
||||
** dependent on the implementation of the runtime. Common sense would dictate
|
||||
** that all threads waiting on a single condition have identical semantics,
|
||||
** therefore which one gets notified is not significant.
|
||||
**
|
||||
** The calling thead must hold the lock that protects the condition, as
|
||||
** well as the invariants that are tightly bound to the condition, when
|
||||
** notify is called.
|
||||
**
|
||||
** Returns PR_FAILURE if the caller has not locked the lock associated
|
||||
** with the condition variable.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_NotifyCondVar (PRCondVar *cvar)
|
||||
{
|
||||
status_t err ;
|
||||
if( atomic_add( &cvar->signalBenCount, 1 ) > 0 )
|
||||
{
|
||||
if (acquire_sem(cvar->signalSem) == B_INTERRUPTED)
|
||||
{
|
||||
atomic_add( &cvar->signalBenCount, -1 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
if (cvar->nw > cvar->ns)
|
||||
{
|
||||
cvar->ns += 1;
|
||||
release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED)
|
||||
{
|
||||
err = B_INTERRUPTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
** Notify all of the threads waiting on the condition variable. The order
|
||||
** that the threads are notified is indeterminant. The lock that protects
|
||||
** the condition must be held.
|
||||
**
|
||||
** Returns PR_FAILURE if the caller has not locked the lock associated
|
||||
** with the condition variable.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_NotifyAllCondVar (PRCondVar *cvar)
|
||||
{
|
||||
int32 handshakes;
|
||||
status_t err = B_OK;
|
||||
|
||||
if( atomic_add( &cvar->signalBenCount, 1 ) > 0 )
|
||||
{
|
||||
if (acquire_sem(cvar->signalSem) == B_INTERRUPTED)
|
||||
{
|
||||
atomic_add( &cvar->signalBenCount, -1 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (cvar->nw > cvar->ns)
|
||||
{
|
||||
handshakes = cvar->nw - cvar->ns;
|
||||
cvar->ns = cvar->nw;
|
||||
release_sem_etc(cvar->sem, handshakes, B_DO_NOT_RESCHEDULE);
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
while (acquire_sem_etc(cvar->handshakeSem, handshakes, 0, 0) == B_INTERRUPTED)
|
||||
{
|
||||
err = B_INTERRUPTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
|
||||
{
|
||||
release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
** File: btlocks.c
|
||||
** Description: Implemenation for thread locks using bthreads
|
||||
** Exports: prlock.h
|
||||
*/
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
void
|
||||
_PR_InitLocks (void)
|
||||
{
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRLock*)
|
||||
PR_NewLock (void)
|
||||
{
|
||||
PRLock *lock;
|
||||
status_t semresult;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
lock = PR_NEWZAP(PRLock);
|
||||
if (lock != NULL) {
|
||||
|
||||
lock->benaphoreCount = 0;
|
||||
lock->semaphoreID = create_sem( 0, "nsprLockSem" );
|
||||
if( lock->semaphoreID < B_NO_ERROR ) {
|
||||
|
||||
PR_DELETE( lock );
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DestroyLock (PRLock* lock)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
PR_ASSERT(NULL != lock);
|
||||
result = delete_sem(lock->semaphoreID);
|
||||
PR_ASSERT(result == B_NO_ERROR);
|
||||
PR_DELETE(lock);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_Lock (PRLock* lock)
|
||||
{
|
||||
PR_ASSERT(lock != NULL);
|
||||
|
||||
if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) {
|
||||
|
||||
if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) {
|
||||
|
||||
atomic_add( &lock->benaphoreCount, -1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lock->owner = find_thread( NULL );
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Unlock (PRLock* lock)
|
||||
{
|
||||
PR_ASSERT(lock != NULL);
|
||||
lock->owner = NULL;
|
||||
if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) {
|
||||
|
||||
release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE );
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_AssertCurrentThreadOwnsLock(PRLock *lock)
|
||||
{
|
||||
PR_ASSERT(lock != NULL);
|
||||
PR_ASSERT(lock->owner == find_thread( NULL ));
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
|
||||
// void _MD_StartInterrupts(void) {PT_LOG("_MD_StartInterrupts")}
|
||||
|
||||
/* this is a total hack.. */
|
||||
|
||||
struct protoent* getprotobyname(const char* name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct protoent* getprotobynumber(int number)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this is needed by prinit for some reason */
|
||||
void
|
||||
_PR_InitStacks (void)
|
||||
{
|
||||
}
|
||||
|
||||
/* this is needed by prinit for some reason */
|
||||
void
|
||||
_PR_InitTPD (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
** Create extra virtual processor threads. Generally used with MP systems.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_SetConcurrency (PRUintn numCPUs)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
** Set thread recycle mode to on (1) or off (0)
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_SetThreadRecycleMode (PRUint32 flag)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
** Get context registers, return with error for now.
|
||||
*/
|
||||
|
||||
PR_IMPLEMENT(PRWord *)
|
||||
_MD_HomeGCRegisters( PRThread *t, int isCurrent, int *np )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *)
|
||||
PR_GetSP( PRThread *t )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_EnumerateThreads( PREnumerator func, void *arg )
|
||||
{
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
** Create a new monitor. Monitors are re-entrant locks with a single built-in
|
||||
** condition variable.
|
||||
**
|
||||
** This may fail if memory is tight or if some operating system resource
|
||||
** is low.
|
||||
*/
|
||||
PR_IMPLEMENT(PRMonitor*)
|
||||
PR_NewMonitor (void)
|
||||
{
|
||||
PRMonitor *mon;
|
||||
PRCondVar *cvar;
|
||||
PRLock *lock;
|
||||
|
||||
mon = PR_NEWZAP( PRMonitor );
|
||||
if( mon )
|
||||
{
|
||||
lock = PR_NewLock();
|
||||
if( !lock )
|
||||
{
|
||||
PR_DELETE( mon );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
cvar = PR_NewCondVar( lock );
|
||||
if( !cvar )
|
||||
{
|
||||
PR_DestroyLock( lock );
|
||||
PR_DELETE( mon );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
mon->cvar = cvar;
|
||||
mon->name = NULL;
|
||||
}
|
||||
|
||||
return( mon );
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
|
||||
{
|
||||
PRMonitor* mon = PR_NewMonitor();
|
||||
if( mon )
|
||||
{
|
||||
mon->name = name;
|
||||
}
|
||||
return mon;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destroy a monitor. The caller is responsible for guaranteeing that the
|
||||
** monitor is no longer in use. There must be no thread waiting on the
|
||||
** monitor's condition variable and that the lock is not held.
|
||||
**
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DestroyMonitor (PRMonitor *mon)
|
||||
{
|
||||
PR_DestroyLock( mon->cvar->lock );
|
||||
PR_DestroyCondVar( mon->cvar );
|
||||
PR_DELETE( mon );
|
||||
}
|
||||
|
||||
/*
|
||||
** Enter the lock associated with the monitor. If the calling thread currently
|
||||
** is in the monitor, the call to enter will silently succeed. In either case,
|
||||
** it will increment the entry count by one.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_EnterMonitor (PRMonitor *mon)
|
||||
{
|
||||
if( mon->cvar->lock->owner == find_thread( NULL ) )
|
||||
{
|
||||
mon->entryCount++;
|
||||
|
||||
} else
|
||||
{
|
||||
PR_Lock( mon->cvar->lock );
|
||||
mon->entryCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Decrement the entry count associated with the monitor. If the decremented
|
||||
** entry count is zero, the monitor is exited. Returns PR_FAILURE if the
|
||||
** calling thread has not entered the monitor.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_ExitMonitor (PRMonitor *mon)
|
||||
{
|
||||
if( mon->cvar->lock->owner != find_thread( NULL ) )
|
||||
{
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
if( --mon->entryCount == 0 )
|
||||
{
|
||||
return( PR_Unlock( mon->cvar->lock ) );
|
||||
}
|
||||
return( PR_SUCCESS );
|
||||
}
|
||||
|
||||
/*
|
||||
** Wait for a notify on the monitor's condition variable. Sleep for "ticks"
|
||||
** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is
|
||||
** indefinite).
|
||||
**
|
||||
** While the thread is waiting it exits the monitor (as if it called
|
||||
** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When
|
||||
** the wait has finished the thread regains control of the monitors lock
|
||||
** with the same entry count as before the wait began.
|
||||
**
|
||||
** The thread waiting on the monitor will be resumed when the monitor is
|
||||
** notified (assuming the thread is the next in line to receive the
|
||||
** notify) or when the "ticks" timeout elapses.
|
||||
**
|
||||
** Returns PR_FAILURE if the caller has not entered the monitor.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Wait (PRMonitor *mon, PRIntervalTime ticks)
|
||||
{
|
||||
PRUint32 entryCount;
|
||||
PRUintn status;
|
||||
PRThread *meThread;
|
||||
thread_id me = find_thread( NULL );
|
||||
meThread = PR_GetCurrentThread();
|
||||
|
||||
if( mon->cvar->lock->owner != me ) return( PR_FAILURE );
|
||||
|
||||
entryCount = mon->entryCount;
|
||||
mon->entryCount = 0;
|
||||
|
||||
status = PR_WaitCondVar( mon->cvar, ticks );
|
||||
|
||||
mon->entryCount = entryCount;
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
/*
|
||||
** Notify a thread waiting on the monitor's condition variable. If a thread
|
||||
** is waiting on the condition variable (using PR_Wait) then it is awakened
|
||||
** and attempts to reenter the monitor.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Notify (PRMonitor *mon)
|
||||
{
|
||||
if( mon->cvar->lock->owner != find_thread( NULL ) )
|
||||
{
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
|
||||
PR_NotifyCondVar( mon->cvar );
|
||||
return( PR_SUCCESS );
|
||||
}
|
||||
|
||||
/*
|
||||
** Notify all of the threads waiting on the monitor's condition variable.
|
||||
** All of threads waiting on the condition are scheduled to reenter the
|
||||
** monitor.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_NotifyAll (PRMonitor *mon)
|
||||
{
|
||||
if( mon->cvar->lock->owner != find_thread( NULL ) )
|
||||
{
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
|
||||
PR_NotifyAllCondVar( mon->cvar );
|
||||
return( PR_SUCCESS );
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of times that the current thread has entered the
|
||||
** lock. Returns zero if the current thread has not entered the lock.
|
||||
*/
|
||||
PR_IMPLEMENT(PRIntn)
|
||||
PR_GetMonitorEntryCount(PRMonitor *mon)
|
||||
{
|
||||
return( (mon->cvar->lock->owner == find_thread( NULL )) ?
|
||||
mon->entryCount : 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
** If the current thread is in |mon|, this assertion is guaranteed to
|
||||
** succeed. Otherwise, the behavior of this function is undefined.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_AssertCurrentThreadInMonitor(PRMonitor *mon)
|
||||
{
|
||||
PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock);
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
** Create a new semaphore object.
|
||||
*/
|
||||
PR_IMPLEMENT(PRSemaphore*)
|
||||
PR_NewSem (PRUintn value)
|
||||
{
|
||||
PRSemaphore *semaphore;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
semaphore = PR_NEWZAP(PRSemaphore);
|
||||
if (NULL != semaphore) {
|
||||
if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR)
|
||||
return NULL;
|
||||
else
|
||||
return semaphore;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destroy the given semaphore object.
|
||||
**
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DestroySem (PRSemaphore *sem)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
PR_ASSERT(sem != NULL);
|
||||
result = delete_sem(sem->sem);
|
||||
PR_ASSERT(result == B_NO_ERROR);
|
||||
PR_DELETE(sem);
|
||||
}
|
||||
|
||||
/*
|
||||
** Wait on a Semaphore.
|
||||
**
|
||||
** This routine allows a calling thread to wait or proceed depending upon
|
||||
** the state of the semahore sem. The thread can proceed only if the
|
||||
** counter value of the semaphore sem is currently greater than 0. If the
|
||||
** value of semaphore sem is positive, it is decremented by one and the
|
||||
** routine returns immediately allowing the calling thread to continue. If
|
||||
** the value of semaphore sem is 0, the calling thread blocks awaiting the
|
||||
** semaphore to be released by another thread.
|
||||
**
|
||||
** This routine can return PR_PENDING_INTERRUPT if the waiting thread
|
||||
** has been interrupted.
|
||||
*/
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_WaitSem (PRSemaphore *sem)
|
||||
{
|
||||
PR_ASSERT(sem != NULL);
|
||||
if (acquire_sem(sem->sem) == B_NO_ERROR)
|
||||
return PR_SUCCESS;
|
||||
else
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine increments the counter value of the semaphore. If other
|
||||
** threads are blocked for the semaphore, then the scheduler will
|
||||
** determine which ONE thread will be unblocked.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_PostSem (PRSemaphore *sem)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
PR_ASSERT(sem != NULL);
|
||||
result = release_sem_etc(sem->sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
PR_ASSERT(result == B_NO_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
** Returns the value of the semaphore referenced by sem without affecting
|
||||
** the state of the semaphore. The value represents the semaphore value
|
||||
** at the time of the call, but may not be the actual value when the
|
||||
** caller inspects it.
|
||||
*/
|
||||
PR_IMPLEMENT(PRUintn)
|
||||
PR_GetValueSem (PRSemaphore *sem)
|
||||
{
|
||||
sem_info info;
|
||||
|
||||
PR_ASSERT(sem != NULL);
|
||||
get_sem_info(sem->sem, &info);
|
||||
return info.count;
|
||||
}
|
||||
|
|
@ -1,662 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <kernel/OS.h>
|
||||
#include <support/TLS.h>
|
||||
|
||||
#include "prlog.h"
|
||||
#include "primpl.h"
|
||||
#include "prcvar.h"
|
||||
#include "prpdce.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* values for PRThread.state */
|
||||
#define BT_THREAD_PRIMORD 0x01 /* this is the primordial thread */
|
||||
#define BT_THREAD_SYSTEM 0x02 /* this is a system thread */
|
||||
#define BT_THREAD_JOINABLE 0x04 /* this is a joinable thread */
|
||||
|
||||
struct _BT_Bookeeping
|
||||
{
|
||||
PRLock *ml; /* a lock to protect ourselves */
|
||||
sem_id cleanUpSem; /* the primoridal thread will block on this
|
||||
sem while waiting for the user threads */
|
||||
PRInt32 threadCount; /* user thred count */
|
||||
|
||||
} bt_book = { NULL, B_ERROR, 0 };
|
||||
|
||||
|
||||
#define BT_TPD_LIMIT 128 /* number of TPD slots we'll provide (arbitrary) */
|
||||
|
||||
/* these will be used to map an index returned by PR_NewThreadPrivateIndex()
|
||||
to the corresponding beos native TLS slot number, and to the destructor
|
||||
for that slot - note that, because it is allocated globally, this data
|
||||
will be automatically zeroed for us when the program begins */
|
||||
static int32 tpd_beosTLSSlots[BT_TPD_LIMIT];
|
||||
static PRThreadPrivateDTOR tpd_dtors[BT_TPD_LIMIT];
|
||||
|
||||
static vint32 tpd_slotsUsed=0; /* number of currently-allocated TPD slots */
|
||||
static int32 tls_prThreadSlot; /* TLS slot in which PRThread will be stored */
|
||||
|
||||
/* this mutex will be used to synchronize access to every
|
||||
PRThread.md.joinSem and PRThread.md.is_joining (we could
|
||||
actually allocate one per thread, but that seems a bit excessive,
|
||||
especially considering that there will probably be little
|
||||
contention, PR_JoinThread() is allowed to block anyway, and the code
|
||||
protected by the mutex is short/fast) */
|
||||
static PRLock *joinSemLock;
|
||||
|
||||
static PRUint32 _bt_MapNSPRToNativePriority( PRThreadPriority priority );
|
||||
static PRThreadPriority _bt_MapNativeToNSPRPriority( PRUint32 priority );
|
||||
static void _bt_CleanupThread(void *arg);
|
||||
static PRThread *_bt_AttachThread();
|
||||
|
||||
void
|
||||
_PR_InitThreads (PRThreadType type, PRThreadPriority priority,
|
||||
PRUintn maxPTDs)
|
||||
{
|
||||
PRThread *primordialThread;
|
||||
PRUint32 beThreadPriority;
|
||||
|
||||
/* allocate joinSem mutex */
|
||||
joinSemLock = PR_NewLock();
|
||||
if (joinSemLock == NULL)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create and initialize NSPR structure for our primordial thread.
|
||||
*/
|
||||
|
||||
primordialThread = PR_NEWZAP(PRThread);
|
||||
if( NULL == primordialThread )
|
||||
{
|
||||
PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
primordialThread->md.joinSem = B_ERROR;
|
||||
|
||||
/*
|
||||
** Set the priority to the desired level.
|
||||
*/
|
||||
|
||||
beThreadPriority = _bt_MapNSPRToNativePriority( priority );
|
||||
|
||||
set_thread_priority( find_thread( NULL ), beThreadPriority );
|
||||
|
||||
primordialThread->priority = priority;
|
||||
|
||||
|
||||
/* set the thread's state - note that the thread is not joinable */
|
||||
primordialThread->state |= BT_THREAD_PRIMORD;
|
||||
if (type == PR_SYSTEM_THREAD)
|
||||
primordialThread->state |= BT_THREAD_SYSTEM;
|
||||
|
||||
/*
|
||||
** Allocate a TLS slot for the PRThread structure (just using
|
||||
** native TLS, as opposed to NSPR TPD, will make PR_GetCurrentThread()
|
||||
** somewhat faster, and will leave one more TPD slot for our client)
|
||||
*/
|
||||
|
||||
tls_prThreadSlot = tls_allocate();
|
||||
|
||||
/*
|
||||
** Stuff our new PRThread structure into our thread specific
|
||||
** slot.
|
||||
*/
|
||||
|
||||
tls_set(tls_prThreadSlot, primordialThread);
|
||||
|
||||
/* allocate lock for bt_book */
|
||||
bt_book.ml = PR_NewLock();
|
||||
if( NULL == bt_book.ml )
|
||||
{
|
||||
PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32
|
||||
_bt_MapNSPRToNativePriority( PRThreadPriority priority )
|
||||
{
|
||||
switch( priority )
|
||||
{
|
||||
case PR_PRIORITY_LOW: return( B_LOW_PRIORITY );
|
||||
case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
|
||||
case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY );
|
||||
case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
|
||||
default: return( B_NORMAL_PRIORITY );
|
||||
}
|
||||
}
|
||||
|
||||
PRThreadPriority
|
||||
_bt_MapNativeToNSPRPriority(PRUint32 priority)
|
||||
{
|
||||
if (priority < B_NORMAL_PRIORITY)
|
||||
return PR_PRIORITY_LOW;
|
||||
if (priority < B_DISPLAY_PRIORITY)
|
||||
return PR_PRIORITY_NORMAL;
|
||||
if (priority < B_URGENT_DISPLAY_PRIORITY)
|
||||
return PR_PRIORITY_HIGH;
|
||||
return PR_PRIORITY_URGENT;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
_bt_mapNativeToNSPRPriority( int32 priority )
|
||||
{
|
||||
switch( priority )
|
||||
{
|
||||
case PR_PRIORITY_LOW: return( B_LOW_PRIORITY );
|
||||
case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
|
||||
case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY );
|
||||
case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
|
||||
default: return( B_NORMAL_PRIORITY );
|
||||
}
|
||||
}
|
||||
|
||||
/* This method is called by all NSPR threads as they exit */
|
||||
void _bt_CleanupThread(void *arg)
|
||||
{
|
||||
PRThread *me = PR_GetCurrentThread();
|
||||
int32 i;
|
||||
|
||||
/* first, clean up all thread-private data */
|
||||
for (i = 0; i < tpd_slotsUsed; i++)
|
||||
{
|
||||
void *oldValue = tls_get(tpd_beosTLSSlots[i]);
|
||||
if ( oldValue != NULL && tpd_dtors[i] != NULL )
|
||||
(*tpd_dtors[i])(oldValue);
|
||||
}
|
||||
|
||||
/* if this thread is joinable, wait for someone to join it */
|
||||
if (me->state & BT_THREAD_JOINABLE)
|
||||
{
|
||||
/* protect access to our joinSem */
|
||||
PR_Lock(joinSemLock);
|
||||
|
||||
if (me->md.is_joining)
|
||||
{
|
||||
/* someone is already waiting to join us (they've
|
||||
allocated a joinSem for us) - let them know we're
|
||||
ready */
|
||||
delete_sem(me->md.joinSem);
|
||||
|
||||
PR_Unlock(joinSemLock);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* noone is currently waiting for our demise - it
|
||||
is our responsibility to allocate the joinSem
|
||||
and block on it */
|
||||
me->md.joinSem = create_sem(0, "join sem");
|
||||
|
||||
/* we're done accessing our joinSem */
|
||||
PR_Unlock(joinSemLock);
|
||||
|
||||
/* wait for someone to join us */
|
||||
while (acquire_sem(me->md.joinSem) == B_INTERRUPTED);
|
||||
}
|
||||
}
|
||||
|
||||
/* if this is a user thread, we must update our books */
|
||||
if ((me->state & BT_THREAD_SYSTEM) == 0)
|
||||
{
|
||||
/* synchronize access to bt_book */
|
||||
PR_Lock( bt_book.ml );
|
||||
|
||||
/* decrement the number of currently-alive user threads */
|
||||
bt_book.threadCount--;
|
||||
|
||||
if (bt_book.threadCount == 0 && bt_book.cleanUpSem != B_ERROR) {
|
||||
/* we are the last user thread, and the primordial thread is
|
||||
blocked in PR_Cleanup() waiting for us to finish - notify
|
||||
it */
|
||||
delete_sem(bt_book.cleanUpSem);
|
||||
}
|
||||
|
||||
PR_Unlock( bt_book.ml );
|
||||
}
|
||||
|
||||
/* finally, delete this thread's PRThread */
|
||||
PR_DELETE(me);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper that all threads invoke that allows us to set some
|
||||
* things up prior to a thread's invocation and clean up after a thread has
|
||||
* exited.
|
||||
*/
|
||||
static void*
|
||||
_bt_root (void* arg)
|
||||
{
|
||||
PRThread *thred = (PRThread*)arg;
|
||||
PRIntn rv;
|
||||
void *privData;
|
||||
status_t result;
|
||||
int i;
|
||||
|
||||
/* save our PRThread object into our TLS */
|
||||
tls_set(tls_prThreadSlot, thred);
|
||||
|
||||
thred->startFunc(thred->arg); /* run the dang thing */
|
||||
|
||||
/* clean up */
|
||||
_bt_CleanupThread(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThread*)
|
||||
PR_CreateThread (PRThreadType type, void (*start)(void* arg), void* arg,
|
||||
PRThreadPriority priority, PRThreadScope scope,
|
||||
PRThreadState state, PRUint32 stackSize)
|
||||
{
|
||||
PRUint32 bePriority;
|
||||
|
||||
PRThread* thred;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
thred = PR_NEWZAP(PRThread);
|
||||
if (thred == NULL)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thred->md.joinSem = B_ERROR;
|
||||
|
||||
thred->arg = arg;
|
||||
thred->startFunc = start;
|
||||
thred->priority = priority;
|
||||
|
||||
if( state == PR_JOINABLE_THREAD )
|
||||
{
|
||||
thred->state |= BT_THREAD_JOINABLE;
|
||||
}
|
||||
|
||||
/* keep some books */
|
||||
|
||||
PR_Lock( bt_book.ml );
|
||||
|
||||
if (type == PR_USER_THREAD)
|
||||
{
|
||||
bt_book.threadCount++;
|
||||
}
|
||||
|
||||
PR_Unlock( bt_book.ml );
|
||||
|
||||
bePriority = _bt_MapNSPRToNativePriority( priority );
|
||||
|
||||
thred->md.tid = spawn_thread((thread_func)_bt_root, "moz-thread",
|
||||
bePriority, thred);
|
||||
if (thred->md.tid < B_OK) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, thred->md.tid);
|
||||
PR_DELETE(thred);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (resume_thread(thred->md.tid) < B_OK) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
PR_DELETE(thred);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return thred;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThread*)
|
||||
PR_AttachThread(PRThreadType type, PRThreadPriority priority,
|
||||
PRThreadStack *stack)
|
||||
{
|
||||
/* PR_GetCurrentThread() will attach a thread if necessary */
|
||||
return PR_GetCurrentThread();
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DetachThread()
|
||||
{
|
||||
/* we don't support detaching */
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_JoinThread (PRThread* thred)
|
||||
{
|
||||
status_t eval, status;
|
||||
|
||||
PR_ASSERT(thred != NULL);
|
||||
|
||||
if ((thred->state & BT_THREAD_JOINABLE) == 0)
|
||||
{
|
||||
PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 );
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
|
||||
/* synchronize access to the thread's joinSem */
|
||||
PR_Lock(joinSemLock);
|
||||
|
||||
if (thred->md.is_joining)
|
||||
{
|
||||
/* another thread is already waiting to join the specified
|
||||
thread - we must fail */
|
||||
PR_Unlock(joinSemLock);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/* let others know we are waiting to join */
|
||||
thred->md.is_joining = PR_TRUE;
|
||||
|
||||
if (thred->md.joinSem == B_ERROR)
|
||||
{
|
||||
/* the thread hasn't finished yet - it is our responsibility to
|
||||
allocate a joinSem and wait on it */
|
||||
thred->md.joinSem = create_sem(0, "join sem");
|
||||
|
||||
/* we're done changing the joinSem now */
|
||||
PR_Unlock(joinSemLock);
|
||||
|
||||
/* wait for the thread to finish */
|
||||
while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the thread has already finished, and has allocated the
|
||||
joinSem itself - let it know it can finally die */
|
||||
delete_sem(thred->md.joinSem);
|
||||
|
||||
PR_Unlock(joinSemLock);
|
||||
}
|
||||
|
||||
/* make sure the thread is dead */
|
||||
wait_for_thread(thred->md.tid, &eval);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThread*)
|
||||
PR_GetCurrentThread ()
|
||||
{
|
||||
PRThread* thred;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
thred = (PRThread *)tls_get( tls_prThreadSlot);
|
||||
if (thred == NULL)
|
||||
{
|
||||
/* this thread doesn't have a PRThread structure (it must be
|
||||
a native thread not created by the NSPR) - assimilate it */
|
||||
thred = _bt_AttachThread();
|
||||
}
|
||||
PR_ASSERT(NULL != thred);
|
||||
|
||||
return thred;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThreadScope)
|
||||
PR_GetThreadScope (const PRThread* thred)
|
||||
{
|
||||
PR_ASSERT(thred != NULL);
|
||||
return PR_GLOBAL_THREAD;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThreadType)
|
||||
PR_GetThreadType (const PRThread* thred)
|
||||
{
|
||||
PR_ASSERT(thred != NULL);
|
||||
return (thred->state & BT_THREAD_SYSTEM) ?
|
||||
PR_SYSTEM_THREAD : PR_USER_THREAD;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThreadState)
|
||||
PR_GetThreadState (const PRThread* thred)
|
||||
{
|
||||
PR_ASSERT(thred != NULL);
|
||||
return (thred->state & BT_THREAD_JOINABLE)?
|
||||
PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRThreadPriority)
|
||||
PR_GetThreadPriority (const PRThread* thred)
|
||||
{
|
||||
PR_ASSERT(thred != NULL);
|
||||
return thred->priority;
|
||||
} /* PR_GetThreadPriority */
|
||||
|
||||
PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred,
|
||||
PRThreadPriority newPri)
|
||||
{
|
||||
PRUint32 bePriority;
|
||||
|
||||
PR_ASSERT( thred != NULL );
|
||||
|
||||
thred->priority = newPri;
|
||||
bePriority = _bt_MapNSPRToNativePriority( newPri );
|
||||
set_thread_priority( thred->md.tid, bePriority );
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_NewThreadPrivateIndex (PRUintn* newIndex,
|
||||
PRThreadPrivateDTOR destructor)
|
||||
{
|
||||
int32 index;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
/* reserve the next available tpd slot */
|
||||
index = atomic_add( &tpd_slotsUsed, 1 );
|
||||
if (index >= BT_TPD_LIMIT)
|
||||
{
|
||||
/* no slots left - decrement value, then fail */
|
||||
atomic_add( &tpd_slotsUsed, -1 );
|
||||
PR_SetError( PR_TPD_RANGE_ERROR, 0 );
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
|
||||
/* allocate a beos-native TLS slot for this index (the new slot
|
||||
automatically contains NULL) */
|
||||
tpd_beosTLSSlots[index] = tls_allocate();
|
||||
|
||||
/* remember the destructor */
|
||||
tpd_dtors[index] = destructor;
|
||||
|
||||
*newIndex = (PRUintn)index;
|
||||
|
||||
return( PR_SUCCESS );
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_SetThreadPrivate (PRUintn index, void* priv)
|
||||
{
|
||||
void *oldValue;
|
||||
|
||||
/*
|
||||
** Sanity checking
|
||||
*/
|
||||
|
||||
if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
|
||||
{
|
||||
PR_SetError( PR_TPD_RANGE_ERROR, 0 );
|
||||
return( PR_FAILURE );
|
||||
}
|
||||
|
||||
/* if the old value isn't NULL, and the dtor for this slot isn't
|
||||
NULL, we must destroy the data */
|
||||
oldValue = tls_get(tpd_beosTLSSlots[index]);
|
||||
if (oldValue != NULL && tpd_dtors[index] != NULL)
|
||||
(*tpd_dtors[index])(oldValue);
|
||||
|
||||
/* save new value */
|
||||
tls_set(tpd_beosTLSSlots[index], priv);
|
||||
|
||||
return( PR_SUCCESS );
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void*)
|
||||
PR_GetThreadPrivate (PRUintn index)
|
||||
{
|
||||
/* make sure the index is valid */
|
||||
if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
|
||||
{
|
||||
PR_SetError( PR_TPD_RANGE_ERROR, 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* return the value */
|
||||
return tls_get( tpd_beosTLSSlots[index] );
|
||||
}
|
||||
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Interrupt (PRThread* thred)
|
||||
{
|
||||
PRIntn rv;
|
||||
|
||||
PR_ASSERT(thred != NULL);
|
||||
|
||||
/*
|
||||
** there seems to be a bug in beos R5 in which calling
|
||||
** resume_thread() on a blocked thread returns B_OK instead
|
||||
** of B_BAD_THREAD_STATE (beos bug #20000422-19095). as such,
|
||||
** to interrupt a thread, we will simply suspend then resume it
|
||||
** (no longer call resume_thread(), check for B_BAD_THREAD_STATE,
|
||||
** the suspend/resume to wake up a blocked thread). this wakes
|
||||
** up blocked threads properly, and doesn't hurt unblocked threads
|
||||
** (they simply get stopped then re-started immediately)
|
||||
*/
|
||||
|
||||
rv = suspend_thread( thred->md.tid );
|
||||
if( rv != B_NO_ERROR )
|
||||
{
|
||||
/* this doesn't appear to be a valid thread_id */
|
||||
PR_SetError( PR_UNKNOWN_ERROR, rv );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
rv = resume_thread( thred->md.tid );
|
||||
if( rv != B_NO_ERROR )
|
||||
{
|
||||
PR_SetError( PR_UNKNOWN_ERROR, rv );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_ClearInterrupt ()
|
||||
{
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Yield ()
|
||||
{
|
||||
/* we just sleep for long enough to cause a reschedule (100
|
||||
microseconds) */
|
||||
snooze(100);
|
||||
}
|
||||
|
||||
#define BT_MILLION 1000000UL
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Sleep (PRIntervalTime ticks)
|
||||
{
|
||||
bigtime_t tps;
|
||||
status_t status;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
tps = PR_IntervalToMicroseconds( ticks );
|
||||
|
||||
status = snooze(tps);
|
||||
if (status == B_NO_ERROR) return PR_SUCCESS;
|
||||
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_Cleanup ()
|
||||
{
|
||||
PRThread *me = PR_GetCurrentThread();
|
||||
|
||||
PR_ASSERT(me->state & BT_THREAD_PRIMORD);
|
||||
if ((me->state & BT_THREAD_PRIMORD) == 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_Lock( bt_book.ml );
|
||||
|
||||
if (bt_book.threadCount != 0)
|
||||
{
|
||||
/* we'll have to wait for some threads to finish - create a
|
||||
sem to block on */
|
||||
bt_book.cleanUpSem = create_sem(0, "cleanup sem");
|
||||
}
|
||||
|
||||
PR_Unlock( bt_book.ml );
|
||||
|
||||
/* note that, if all the user threads were already dead, we
|
||||
wouldn't have created a sem above, so this acquire_sem()
|
||||
will fail immediately */
|
||||
while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_ProcessExit (PRIntn status)
|
||||
{
|
||||
exit(status);
|
||||
}
|
||||
|
||||
PRThread *_bt_AttachThread()
|
||||
{
|
||||
PRThread *thread;
|
||||
thread_info tInfo;
|
||||
|
||||
/* make sure this thread doesn't already have a PRThread structure */
|
||||
PR_ASSERT(tls_get(tls_prThreadSlot) == NULL);
|
||||
|
||||
/* allocate a PRThread structure for this thread */
|
||||
thread = PR_NEWZAP(PRThread);
|
||||
if (thread == NULL)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the native thread's current state */
|
||||
get_thread_info(find_thread(NULL), &tInfo);
|
||||
|
||||
/* initialize new PRThread */
|
||||
thread->md.tid = tInfo.thread;
|
||||
thread->md.joinSem = B_ERROR;
|
||||
thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority);
|
||||
|
||||
/* attached threads are always non-joinable user threads */
|
||||
thread->state = 0;
|
||||
|
||||
/* increment user thread count */
|
||||
PR_Lock(bt_book.ml);
|
||||
bt_book.threadCount++;
|
||||
PR_Unlock(bt_book.ml);
|
||||
|
||||
/* store this thread's PRThread */
|
||||
tls_set(tls_prThreadSlot, thread);
|
||||
|
||||
/* the thread must call _bt_CleanupThread() before it dies, in order
|
||||
to clean up its PRThread, synchronize with the primordial thread,
|
||||
etc. */
|
||||
on_exit_thread(_bt_CleanupThread, NULL);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This makefile appends to the variable OBJS the bthread object modules
|
||||
# that will be part of the nspr20 library.
|
||||
|
||||
include $(srcdir)/bthreads/bsrcs.mk
|
||||
|
||||
OBJS += $(BTCSRCS:%.c=bthreads/$(OBJDIR)/%.$(OBJ_SUFFIX))
|
||||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -81,7 +81,7 @@ private:
|
|||
** for this class.
|
||||
*/
|
||||
PRSize StuffFunction(void*, const char*, PRSize);
|
||||
|
||||
|
||||
}; /* RCFormatBuffer */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -11,13 +11,21 @@
|
|||
|
||||
RCBase::~RCBase() { }
|
||||
|
||||
PRSize RCBase::GetErrorTextLength() { return PR_GetErrorTextLength(); }
|
||||
PRSize RCBase::CopyErrorText(char *text) { return PR_GetErrorText(text); }
|
||||
PRSize RCBase::GetErrorTextLength() {
|
||||
return PR_GetErrorTextLength();
|
||||
}
|
||||
PRSize RCBase::CopyErrorText(char *text) {
|
||||
return PR_GetErrorText(text);
|
||||
}
|
||||
|
||||
void RCBase::SetError(PRErrorCode error, PRInt32 oserror)
|
||||
{ PR_SetError(error, oserror); }
|
||||
{
|
||||
PR_SetError(error, oserror);
|
||||
}
|
||||
|
||||
void RCBase::SetErrorText(PRSize text_length, const char *text)
|
||||
{ PR_SetErrorText(text_length, text); }
|
||||
{
|
||||
PR_SetErrorText(text_length, text);
|
||||
}
|
||||
|
||||
/* rcbase.cpp */
|
||||
|
|
|
|||
|
|
@ -43,8 +43,12 @@ protected:
|
|||
RCBase() { }
|
||||
}; /* RCObject */
|
||||
|
||||
inline PRErrorCode RCBase::GetError() { return PR_GetError(); }
|
||||
inline PRInt32 RCBase::GetOSError() { return PR_GetOSError(); }
|
||||
inline PRErrorCode RCBase::GetError() {
|
||||
return PR_GetError();
|
||||
}
|
||||
inline PRInt32 RCBase::GetOSError() {
|
||||
return PR_GetOSError();
|
||||
}
|
||||
|
||||
#endif /* defined(_RCRUNTIME_H) */
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ RCCondition::RCCondition(class RCLock *lock): RCBase()
|
|||
|
||||
RCCondition::~RCCondition()
|
||||
{
|
||||
if (NULL != cv) PR_DestroyCondVar(cv);
|
||||
if (NULL != cv) {
|
||||
PR_DestroyCondVar(cv);
|
||||
}
|
||||
} /* RCCondition::~RCCondition */
|
||||
|
||||
PRStatus RCCondition::Wait()
|
||||
|
|
@ -34,8 +36,9 @@ PRStatus RCCondition::Wait()
|
|||
SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
rv = PR_FAILURE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
rv = PR_WaitCondVar(cv, timeout.interval);
|
||||
}
|
||||
return rv;
|
||||
} /* RCCondition::Wait */
|
||||
|
||||
|
|
@ -60,6 +63,8 @@ PRStatus RCCondition::SetTimeout(const RCInterval& tmo)
|
|||
return PR_SUCCESS;
|
||||
} /* RCCondition::SetTimeout */
|
||||
|
||||
RCInterval RCCondition::GetTimeout() const { return timeout; }
|
||||
RCInterval RCCondition::GetTimeout() const {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/* rccv.cpp */
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public:
|
|||
virtual PRStatus Broadcast(); /* perhaps ready many threads */
|
||||
|
||||
virtual PRStatus SetTimeout(const RCInterval&);
|
||||
/* set object's current timeout value */
|
||||
/* set object's current timeout value */
|
||||
|
||||
private:
|
||||
PRCondVar *cv;
|
||||
|
|
|
|||
|
|
@ -13,24 +13,42 @@
|
|||
|
||||
RCFileIO::RCFileIO(): RCIO(RCIO::file) { }
|
||||
|
||||
RCFileIO::~RCFileIO() { if (NULL != fd) (void)Close(); }
|
||||
RCFileIO::~RCFileIO() {
|
||||
if (NULL != fd) {
|
||||
(void)Close();
|
||||
}
|
||||
}
|
||||
|
||||
PRInt64 RCFileIO::Available()
|
||||
{ return fd->methods->available(fd); }
|
||||
{
|
||||
return fd->methods->available(fd);
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Close()
|
||||
{ PRStatus rv = fd->methods->close(fd); fd = NULL; return rv; }
|
||||
{
|
||||
PRStatus rv = fd->methods->close(fd);
|
||||
fd = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Delete(const char* filename) { return PR_Delete(filename); }
|
||||
PRStatus RCFileIO::Delete(const char* filename) {
|
||||
return PR_Delete(filename);
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::FileInfo(RCFileInfo* info) const
|
||||
{ return fd->methods->fileInfo64(fd, &info->info); }
|
||||
{
|
||||
return fd->methods->fileInfo64(fd, &info->info);
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo* info)
|
||||
{ return PR_GetFileInfo64(name, &info->info); }
|
||||
{
|
||||
return PR_GetFileInfo64(name, &info->info);
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Fsync()
|
||||
{ return fd->methods->fsync(fd); }
|
||||
{
|
||||
return fd->methods->fsync(fd);
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode)
|
||||
{
|
||||
|
|
@ -39,7 +57,9 @@ PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode)
|
|||
} /* RCFileIO::Open */
|
||||
|
||||
PRInt32 RCFileIO::Read(void *buf, PRSize amount)
|
||||
{ return fd->methods->read(fd, buf, amount); }
|
||||
{
|
||||
return fd->methods->read(fd, buf, amount);
|
||||
}
|
||||
|
||||
PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how)
|
||||
{
|
||||
|
|
@ -55,11 +75,15 @@ PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how)
|
|||
} /* RCFileIO::Seek */
|
||||
|
||||
PRInt32 RCFileIO::Write(const void *buf, PRSize amount)
|
||||
{ return fd->methods->write(fd, buf, amount); }
|
||||
{
|
||||
return fd->methods->write(fd, buf, amount);
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::Writev(
|
||||
const PRIOVec *iov, PRSize size, const RCInterval& timeout)
|
||||
{ return fd->methods->writev(fd, iov, size, timeout); }
|
||||
{
|
||||
return fd->methods->writev(fd, iov, size, timeout);
|
||||
}
|
||||
|
||||
RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special)
|
||||
{
|
||||
|
|
@ -78,7 +102,9 @@ RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special)
|
|||
if (NULL != fd)
|
||||
{
|
||||
spec = new RCFileIO();
|
||||
if (NULL != spec) spec->fd = fd;
|
||||
if (NULL != spec) {
|
||||
spec->fd = fd;
|
||||
}
|
||||
}
|
||||
return spec;
|
||||
} /* RCFileIO::GetSpecialFile */
|
||||
|
|
@ -90,56 +116,104 @@ RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special)
|
|||
** are not valid for this type of I/O class (normal and special file).
|
||||
*/
|
||||
PRStatus RCFileIO::Connect(const RCNetAddr&, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::GetLocalName(RCNetAddr*) const
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::GetPeerName(RCNetAddr*) const
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::GetSocketOption(PRSocketOptionData*) const
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Listen(PRIntn)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt16 RCFileIO::Poll(PRInt16, PRInt16*)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return 0; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::Recv(void*, PRSize, PRIntn, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::Recvfrom(void*, PRSize, PRIntn, RCNetAddr*, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::Send(
|
||||
const void*, PRSize, PRIntn, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::Sendto(
|
||||
const void*, PRSize, PRIntn, const RCNetAddr&, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
RCIO* RCFileIO::Accept(RCNetAddr*, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return NULL; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Bind(const RCNetAddr&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::AcceptRead(
|
||||
RCIO**, RCNetAddr**, void*, PRSize, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::SetSocketOption(const PRSocketOptionData*)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCFileIO::Shutdown(RCIO::ShutdownHow)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt32 RCFileIO::TransmitFile(
|
||||
RCIO*, const void*, PRSize, RCIO::FileDisposition, const RCInterval&)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Class implementation for file information object (ref: prio.h)
|
||||
|
|
@ -148,11 +222,17 @@ PRInt32 RCFileIO::TransmitFile(
|
|||
RCFileInfo::~RCFileInfo() { }
|
||||
|
||||
RCFileInfo::RCFileInfo(const RCFileInfo& her): RCBase()
|
||||
{ info = her.info; } /* RCFileInfo::RCFileInfo */
|
||||
{
|
||||
info = her.info; /* RCFileInfo::RCFileInfo */
|
||||
}
|
||||
|
||||
RCTime RCFileInfo::CreationTime() const { return RCTime(info.creationTime); }
|
||||
RCTime RCFileInfo::CreationTime() const {
|
||||
return RCTime(info.creationTime);
|
||||
}
|
||||
|
||||
RCTime RCFileInfo::ModifyTime() const { return RCTime(info.modifyTime); }
|
||||
RCTime RCFileInfo::ModifyTime() const {
|
||||
return RCTime(info.modifyTime);
|
||||
}
|
||||
|
||||
RCFileInfo::FileType RCFileInfo::Type() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ public:
|
|||
virtual PRInt64 Seek(PRInt64 offset, RCIO::Whence how);
|
||||
virtual PRInt32 Write(const void *buf, PRSize amount);
|
||||
virtual PRInt32 Writev(
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout);
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -52,8 +52,8 @@ private:
|
|||
|
||||
RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout);
|
||||
PRInt32 AcceptRead(
|
||||
RCIO **newfd, RCNetAddr **address, void *buffer,
|
||||
PRSize amount, const RCInterval& timeout);
|
||||
RCIO **newfd, RCNetAddr **address, void *buffer,
|
||||
PRSize amount, const RCInterval& timeout);
|
||||
PRStatus Bind(const RCNetAddr& addr);
|
||||
PRStatus Connect(const RCNetAddr& addr, const RCInterval& timeout);
|
||||
PRStatus GetLocalName(RCNetAddr *addr) const;
|
||||
|
|
@ -62,24 +62,24 @@ private:
|
|||
PRStatus Listen(PRIntn backlog);
|
||||
PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags);
|
||||
PRInt32 Recv(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
PRInt32 Recvfrom(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout);
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout);
|
||||
PRInt32 Send(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
PRInt32 Sendto(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout);
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout);
|
||||
PRStatus SetSocketOption(const PRSocketOptionData *data);
|
||||
PRStatus Shutdown(RCIO::ShutdownHow how);
|
||||
PRInt32 TransmitFile(
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout);
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout);
|
||||
public:
|
||||
|
||||
/*
|
||||
|
|
@ -116,14 +116,16 @@ public:
|
|||
RCTime ModifyTime() const;
|
||||
RCFileInfo::FileType Type() const;
|
||||
|
||||
friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const;
|
||||
friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*);
|
||||
friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const;
|
||||
friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*);
|
||||
|
||||
private:
|
||||
PRFileInfo64 info;
|
||||
}; /* RCFileInfo */
|
||||
|
||||
inline RCFileInfo::RCFileInfo(): RCBase() { }
|
||||
inline PRInt64 RCFileInfo::Size() const { return info.size; }
|
||||
inline PRInt64 RCFileInfo::Size() const {
|
||||
return info.size;
|
||||
}
|
||||
|
||||
#endif /* defined(_RCFILEIO_H) */
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ RCInterval::RCInterval(RCInterval::RCReservedInterval special): RCBase()
|
|||
{
|
||||
switch (special)
|
||||
{
|
||||
case RCInterval::now:
|
||||
interval = PR_IntervalNow();
|
||||
break;
|
||||
case RCInterval::no_timeout:
|
||||
interval = PR_INTERVAL_NO_TIMEOUT;
|
||||
break;
|
||||
case RCInterval::no_wait:
|
||||
interval = PR_INTERVAL_NO_WAIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case RCInterval::now:
|
||||
interval = PR_IntervalNow();
|
||||
break;
|
||||
case RCInterval::no_timeout:
|
||||
interval = PR_INTERVAL_NO_TIMEOUT;
|
||||
break;
|
||||
case RCInterval::no_wait:
|
||||
interval = PR_INTERVAL_NO_WAIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* RCInterval::RCInterval */
|
||||
|
||||
|
|
|
|||
|
|
@ -66,71 +66,125 @@ public:
|
|||
|
||||
private:
|
||||
PRIntervalTime interval;
|
||||
|
||||
|
||||
}; /* RCInterval */
|
||||
|
||||
|
||||
inline RCInterval::RCInterval(): RCBase() { }
|
||||
|
||||
inline RCInterval::RCInterval(const RCInterval& his): RCBase()
|
||||
{ interval = his.interval; }
|
||||
{
|
||||
interval = his.interval;
|
||||
}
|
||||
|
||||
inline RCInterval::RCInterval(PRIntervalTime ticks): RCBase()
|
||||
{ interval = ticks; }
|
||||
{
|
||||
interval = ticks;
|
||||
}
|
||||
|
||||
inline void RCInterval::SetToNow() { interval = PR_IntervalNow(); }
|
||||
inline void RCInterval::SetToNow() {
|
||||
interval = PR_IntervalNow();
|
||||
}
|
||||
|
||||
inline void RCInterval::operator=(const RCInterval& his)
|
||||
{ interval = his.interval; }
|
||||
{
|
||||
interval = his.interval;
|
||||
}
|
||||
|
||||
inline void RCInterval::operator=(PRIntervalTime his)
|
||||
{ interval = his; }
|
||||
{
|
||||
interval = his;
|
||||
}
|
||||
|
||||
inline PRBool RCInterval::operator==(const RCInterval& his)
|
||||
{ return (interval == his.interval) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (interval == his.interval) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCInterval::operator<(const RCInterval& his)
|
||||
{ return (interval < his.interval)? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (interval < his.interval)? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCInterval::operator>(const RCInterval& his)
|
||||
{ return (interval > his.interval) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (interval > his.interval) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCInterval::operator<=(const RCInterval& his)
|
||||
{ return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (interval <= his.interval) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCInterval::operator>=(const RCInterval& his)
|
||||
{ return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (interval <= his.interval) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
inline RCInterval RCInterval::operator+(const RCInterval& his)
|
||||
{ return RCInterval((PRIntervalTime)(interval + his.interval)); }
|
||||
{
|
||||
return RCInterval((PRIntervalTime)(interval + his.interval));
|
||||
}
|
||||
inline RCInterval RCInterval::operator-(const RCInterval& his)
|
||||
{ return RCInterval((PRIntervalTime)(interval - his.interval)); }
|
||||
{
|
||||
return RCInterval((PRIntervalTime)(interval - his.interval));
|
||||
}
|
||||
inline RCInterval& RCInterval::operator+=(const RCInterval& his)
|
||||
{ interval += his.interval; return *this; }
|
||||
{
|
||||
interval += his.interval;
|
||||
return *this;
|
||||
}
|
||||
inline RCInterval& RCInterval::operator-=(const RCInterval& his)
|
||||
{ interval -= his.interval; return *this; }
|
||||
{
|
||||
interval -= his.interval;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RCInterval RCInterval::operator/(PRUint32 him)
|
||||
{ return RCInterval((PRIntervalTime)(interval / him)); }
|
||||
{
|
||||
return RCInterval((PRIntervalTime)(interval / him));
|
||||
}
|
||||
inline RCInterval RCInterval::operator*(PRUint32 him)
|
||||
{ return RCInterval((PRIntervalTime)(interval * him)); }
|
||||
{
|
||||
return RCInterval((PRIntervalTime)(interval * him));
|
||||
}
|
||||
|
||||
inline RCInterval& RCInterval::operator/=(PRUint32 him)
|
||||
{ interval /= him; return *this; }
|
||||
{
|
||||
interval /= him;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RCInterval& RCInterval::operator*=(PRUint32 him)
|
||||
{ interval *= him; return *this; }
|
||||
{
|
||||
interval *= him;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline PRUint32 RCInterval::ToSeconds() const
|
||||
{ return PR_IntervalToSeconds(interval); }
|
||||
{
|
||||
return PR_IntervalToSeconds(interval);
|
||||
}
|
||||
inline PRUint32 RCInterval::ToMilliseconds() const
|
||||
{ return PR_IntervalToMilliseconds(interval); }
|
||||
{
|
||||
return PR_IntervalToMilliseconds(interval);
|
||||
}
|
||||
inline PRUint32 RCInterval::ToMicroseconds() const
|
||||
{ return PR_IntervalToMicroseconds(interval); }
|
||||
inline RCInterval::operator PRIntervalTime() const { return interval; }
|
||||
{
|
||||
return PR_IntervalToMicroseconds(interval);
|
||||
}
|
||||
inline RCInterval::operator PRIntervalTime() const {
|
||||
return interval;
|
||||
}
|
||||
|
||||
inline PRIntervalTime RCInterval::FromSeconds(PRUint32 seconds)
|
||||
{ return PR_SecondsToInterval(seconds); }
|
||||
{
|
||||
return PR_SecondsToInterval(seconds);
|
||||
}
|
||||
inline PRIntervalTime RCInterval::FromMilliseconds(PRUint32 milli)
|
||||
{ return PR_MillisecondsToInterval(milli); }
|
||||
{
|
||||
return PR_MillisecondsToInterval(milli);
|
||||
}
|
||||
inline PRIntervalTime RCInterval::FromMicroseconds(PRUint32 micro)
|
||||
{ return PR_MicrosecondsToInterval(micro); }
|
||||
{
|
||||
return PR_MicrosecondsToInterval(micro);
|
||||
}
|
||||
|
||||
#endif /* defined(_RCINTERVAL_H) */
|
||||
|
||||
|
|
|
|||
|
|
@ -49,14 +49,14 @@ public:
|
|||
|
||||
virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout) = 0;
|
||||
virtual PRInt32 AcceptRead(
|
||||
RCIO **nd, RCNetAddr **raddr, void *buf,
|
||||
PRSize amount, const RCInterval& timeout) = 0;
|
||||
RCIO **nd, RCNetAddr **raddr, void *buf,
|
||||
PRSize amount, const RCInterval& timeout) = 0;
|
||||
virtual PRInt64 Available() = 0;
|
||||
virtual PRStatus Bind(const RCNetAddr& addr) = 0;
|
||||
virtual PRStatus Close() = 0;
|
||||
virtual PRStatus Connect(
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout) = 0;
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout) = 0;
|
||||
virtual PRStatus FileInfo(RCFileInfo *info) const = 0;
|
||||
virtual PRStatus Fsync() = 0;
|
||||
virtual PRStatus GetLocalName(RCNetAddr *addr) const = 0;
|
||||
|
|
@ -67,36 +67,37 @@ public:
|
|||
virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags) = 0;
|
||||
virtual PRInt32 Read(void *buf, PRSize amount) = 0;
|
||||
virtual PRInt32 Recv(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
virtual PRInt32 Recvfrom(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout) = 0;
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout) = 0;
|
||||
virtual PRInt64 Seek(PRInt64 offset, Whence how) = 0;
|
||||
virtual PRInt32 Send(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
virtual PRInt32 Sendto(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout) = 0;
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout) = 0;
|
||||
virtual PRStatus SetSocketOption(const PRSocketOptionData *data) = 0;
|
||||
virtual PRStatus Shutdown(ShutdownHow how) = 0;
|
||||
virtual PRInt32 TransmitFile(
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout) = 0;
|
||||
virtual PRInt32 Write(const void *buf, PRSize amount) = 0;
|
||||
virtual PRInt32 Writev(
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout) = 0;
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout) = 0;
|
||||
|
||||
protected:
|
||||
typedef enum {
|
||||
file = PR_DESC_FILE,
|
||||
tcp = PR_DESC_SOCKET_TCP,
|
||||
udp = PR_DESC_SOCKET_UDP,
|
||||
layered = PR_DESC_LAYERED} RCIOType;
|
||||
layered = PR_DESC_LAYERED
|
||||
} RCIOType;
|
||||
|
||||
RCIO(RCIOType);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ RCLock::RCLock()
|
|||
|
||||
RCLock::~RCLock()
|
||||
{
|
||||
if (NULL != lock) PR_DestroyLock(lock);
|
||||
if (NULL != lock) {
|
||||
PR_DestroyLock(lock);
|
||||
}
|
||||
lock = NULL;
|
||||
} /* RCLock::~RCLock */
|
||||
|
||||
|
|
|
|||
|
|
@ -53,13 +53,21 @@ private:
|
|||
RCEnter(const RCEnter&);
|
||||
void operator=(const RCEnter&);
|
||||
|
||||
void *operator new(PRSize) { return NULL; }
|
||||
void *operator new(PRSize) {
|
||||
return NULL;
|
||||
}
|
||||
void operator delete(void*) { }
|
||||
}; /* RCEnter */
|
||||
|
||||
|
||||
inline RCEnter::RCEnter(RCLock* ml) { lock = ml; lock->Acquire(); }
|
||||
inline RCEnter::~RCEnter() { lock->Release(); lock = NULL; }
|
||||
inline RCEnter::RCEnter(RCLock* ml) {
|
||||
lock = ml;
|
||||
lock->Acquire();
|
||||
}
|
||||
inline RCEnter::~RCEnter() {
|
||||
lock->Release();
|
||||
lock = NULL;
|
||||
}
|
||||
|
||||
#endif /* defined(_RCLOCK_H) */
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@
|
|||
#include <string.h>
|
||||
|
||||
RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase()
|
||||
{ address = his.address; }
|
||||
{
|
||||
address = his.address;
|
||||
}
|
||||
|
||||
RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase()
|
||||
{
|
||||
|
|
@ -42,12 +44,18 @@ RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase()
|
|||
|
||||
RCNetAddr::~RCNetAddr() { }
|
||||
|
||||
void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; }
|
||||
void RCNetAddr::operator=(const RCNetAddr& his) {
|
||||
address = his.address;
|
||||
}
|
||||
|
||||
PRStatus RCNetAddr::FromString(const char* string)
|
||||
{ return PR_StringToNetAddr(string, &address); }
|
||||
{
|
||||
return PR_StringToNetAddr(string, &address);
|
||||
}
|
||||
|
||||
void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; }
|
||||
void RCNetAddr::operator=(const PRNetAddr* addr) {
|
||||
address = *addr;
|
||||
}
|
||||
|
||||
PRBool RCNetAddr::operator==(const RCNetAddr& his) const
|
||||
{
|
||||
|
|
@ -76,14 +84,14 @@ PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const
|
|||
rv = (address.inet.ip == his.address.inet.ip); break;
|
||||
case PR_AF_INET6:
|
||||
rv = (0 == memcmp(
|
||||
&address.ipv6.ip, &his.address.ipv6.ip,
|
||||
sizeof(address.ipv6.ip)));
|
||||
&address.ipv6.ip, &his.address.ipv6.ip,
|
||||
sizeof(address.ipv6.ip)));
|
||||
break;
|
||||
#if defined(XP_UNIX)
|
||||
case PR_AF_LOCAL:
|
||||
rv = (0 == strncmp(
|
||||
address.local.path, his.address.local.path,
|
||||
sizeof(address.local.path)));
|
||||
address.local.path, his.address.local.path,
|
||||
sizeof(address.local.path)));
|
||||
break;
|
||||
#endif
|
||||
default: break;
|
||||
|
|
@ -92,7 +100,9 @@ PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const
|
|||
} /* RCNetAddr::operator== */
|
||||
|
||||
PRStatus RCNetAddr::ToString(char *string, PRSize size) const
|
||||
{ return PR_NetAddrToString(&address, string, size); }
|
||||
{
|
||||
return PR_NetAddrToString(&address, string, size);
|
||||
}
|
||||
|
||||
/*
|
||||
** RCHostLookup
|
||||
|
|
@ -100,7 +110,9 @@ PRStatus RCNetAddr::ToString(char *string, PRSize size) const
|
|||
|
||||
RCHostLookup::~RCHostLookup()
|
||||
{
|
||||
if (NULL != address) delete [] address;
|
||||
if (NULL != address) {
|
||||
delete [] address;
|
||||
}
|
||||
} /* RCHostLookup::~RCHostLookup */
|
||||
|
||||
RCHostLookup::RCHostLookup(): RCBase()
|
||||
|
|
@ -118,14 +130,18 @@ PRStatus RCHostLookup::ByName(const char* name)
|
|||
RCNetAddr* vector = NULL;
|
||||
RCNetAddr* old_vector = NULL;
|
||||
void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE);
|
||||
if (NULL == buffer) return PR_FAILURE;
|
||||
if (NULL == buffer) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry);
|
||||
if (PR_SUCCESS == rv)
|
||||
{
|
||||
for (max = 0, index = 0;; ++max)
|
||||
{
|
||||
index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
|
||||
if (0 == index) break;
|
||||
if (0 == index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (max > 0)
|
||||
{
|
||||
|
|
@ -133,7 +149,9 @@ PRStatus RCHostLookup::ByName(const char* name)
|
|||
while (--max > 0)
|
||||
{
|
||||
index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
|
||||
if (0 == index) break;
|
||||
if (0 == index) {
|
||||
break;
|
||||
}
|
||||
vector[index] = &addr;
|
||||
}
|
||||
{
|
||||
|
|
@ -142,10 +160,14 @@ PRStatus RCHostLookup::ByName(const char* name)
|
|||
address = vector;
|
||||
max_index = max;
|
||||
}
|
||||
if (NULL != old_vector) delete [] old_vector;
|
||||
if (NULL != old_vector) {
|
||||
delete [] old_vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NULL != buffer) PR_DELETE(buffer);
|
||||
if (NULL != buffer) {
|
||||
PR_DELETE(buffer);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
} /* RCHostLookup::ByName */
|
||||
|
||||
|
|
@ -158,14 +180,18 @@ PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
|
|||
RCNetAddr* vector = NULL;
|
||||
RCNetAddr* old_vector = NULL;
|
||||
char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE);
|
||||
if (NULL == buffer) return PR_FAILURE;
|
||||
if (NULL == buffer) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry);
|
||||
if (PR_SUCCESS == rv)
|
||||
{
|
||||
for (max = 0, index = 0;; ++max)
|
||||
{
|
||||
index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
|
||||
if (0 == index) break;
|
||||
if (0 == index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (max > 0)
|
||||
{
|
||||
|
|
@ -173,7 +199,9 @@ PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
|
|||
while (--max > 0)
|
||||
{
|
||||
index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
|
||||
if (0 == index) break;
|
||||
if (0 == index) {
|
||||
break;
|
||||
}
|
||||
vector[index] = &addr;
|
||||
}
|
||||
{
|
||||
|
|
@ -182,18 +210,23 @@ PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
|
|||
address = vector;
|
||||
max_index = max;
|
||||
}
|
||||
if (NULL != old_vector) delete [] old_vector;
|
||||
if (NULL != old_vector) {
|
||||
delete [] old_vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NULL != buffer) PR_DELETE(buffer);
|
||||
if (NULL != buffer) {
|
||||
PR_DELETE(buffer);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
} /* RCHostLookup::ByAddress */
|
||||
|
||||
const RCNetAddr* RCHostLookup::operator[](PRUintn which)
|
||||
{
|
||||
RCNetAddr* addr = NULL;
|
||||
if (which < max_index)
|
||||
if (which < max_index) {
|
||||
addr = &address[which];
|
||||
}
|
||||
return addr;
|
||||
} /* RCHostLookup::operator[] */
|
||||
|
||||
|
|
|
|||
|
|
@ -28,16 +28,16 @@ public:
|
|||
RCNetAddr(const RCNetAddr&); /* copy constructor */
|
||||
RCNetAddr(HostValue, PRUint16 port);/* init'd w/ 'special' assignments */
|
||||
RCNetAddr(const RCNetAddr&, PRUint16 port);
|
||||
/* copy w/ port reassigment */
|
||||
/* copy w/ port reassigment */
|
||||
|
||||
virtual ~RCNetAddr();
|
||||
|
||||
void operator=(const RCNetAddr&);
|
||||
|
||||
virtual PRBool operator==(const RCNetAddr&) const;
|
||||
/* compare of all relavent fields */
|
||||
/* compare of all relavent fields */
|
||||
virtual PRBool EqualHost(const RCNetAddr&) const;
|
||||
/* compare of just host field */
|
||||
/* compare of just host field */
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -45,9 +45,9 @@ public:
|
|||
void operator=(const PRNetAddr*); /* construction from more primitive data */
|
||||
operator const PRNetAddr*() const; /* extraction of underlying representation */
|
||||
virtual PRStatus FromString(const char* string);
|
||||
/* initialization from an ASCII string */
|
||||
/* initialization from an ASCII string */
|
||||
virtual PRStatus ToString(char *string, PRSize size) const;
|
||||
/* convert internal fromat to a string */
|
||||
/* convert internal fromat to a string */
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -87,7 +87,9 @@ private:
|
|||
};
|
||||
|
||||
inline RCNetAddr::RCNetAddr(): RCBase() { }
|
||||
inline RCNetAddr::operator const PRNetAddr*() const { return &address; }
|
||||
inline RCNetAddr::operator const PRNetAddr*() const {
|
||||
return &address;
|
||||
}
|
||||
|
||||
|
||||
#endif /* defined(_RCNETDB_H) */
|
||||
|
|
|
|||
|
|
@ -12,13 +12,20 @@
|
|||
#include <private/pprio.h>
|
||||
|
||||
RCNetStreamIO::~RCNetStreamIO()
|
||||
{ PRStatus rv = (fd->methods->close)(fd); fd = NULL; }
|
||||
{
|
||||
PRStatus rv = (fd->methods->close)(fd);
|
||||
fd = NULL;
|
||||
}
|
||||
|
||||
RCNetStreamIO::RCNetStreamIO(): RCIO(RCIO::tcp)
|
||||
{ fd = PR_NewTCPSocket(); }
|
||||
{
|
||||
fd = PR_NewTCPSocket();
|
||||
}
|
||||
|
||||
RCNetStreamIO::RCNetStreamIO(PRIntn protocol): RCIO(RCIO::tcp)
|
||||
{ fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol); }
|
||||
{
|
||||
fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol);
|
||||
}
|
||||
|
||||
RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout)
|
||||
{
|
||||
|
|
@ -33,8 +40,9 @@ RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout)
|
|||
*addr = &peer;
|
||||
rcio->fd = newfd;
|
||||
}
|
||||
else
|
||||
else {
|
||||
(void)(newfd->methods->close)(newfd);
|
||||
}
|
||||
}
|
||||
return rcio;
|
||||
} /* RCNetStreamIO::Accept */
|
||||
|
|
@ -42,35 +50,48 @@ RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout)
|
|||
PRInt32 RCNetStreamIO::AcceptRead(
|
||||
RCIO **nd, RCNetAddr **raddr, void *buf,
|
||||
PRSize amount, const RCInterval& timeout)
|
||||
{
|
||||
{
|
||||
PRNetAddr *from;
|
||||
PRFileDesc *accepted;
|
||||
PRInt32 rv = (fd->methods->acceptread)(
|
||||
fd, &accepted, &from, buf, amount, timeout);
|
||||
fd, &accepted, &from, buf, amount, timeout);
|
||||
if (rv >= 0)
|
||||
{
|
||||
RCNetStreamIO *ns = new RCNetStreamIO();
|
||||
if (NULL != *nd) ns->fd = accepted;
|
||||
else {PR_Close(accepted); rv = -1; }
|
||||
if (NULL != *nd) {
|
||||
ns->fd = accepted;
|
||||
}
|
||||
else {
|
||||
PR_Close(accepted);
|
||||
rv = -1;
|
||||
}
|
||||
*nd = ns;
|
||||
}
|
||||
return rv;
|
||||
} /* RCNetStreamIO::AcceptRead */
|
||||
|
||||
PRInt64 RCNetStreamIO::Available()
|
||||
{ return (fd->methods->available64)(fd); }
|
||||
{
|
||||
return (fd->methods->available64)(fd);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Bind(const RCNetAddr& addr)
|
||||
{ return (fd->methods->bind)(fd, addr); }
|
||||
{
|
||||
return (fd->methods->bind)(fd, addr);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Connect(const RCNetAddr& addr, const RCInterval& timeout)
|
||||
{ return (fd->methods->connect)(fd, addr, timeout); }
|
||||
{
|
||||
return (fd->methods->connect)(fd, addr, timeout);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::GetLocalName(RCNetAddr *addr) const
|
||||
{
|
||||
PRNetAddr local;
|
||||
PRStatus rv = (fd->methods->getsockname)(fd, &local);
|
||||
if (PR_SUCCESS == rv) *addr = &local;
|
||||
if (PR_SUCCESS == rv) {
|
||||
*addr = &local;
|
||||
}
|
||||
return rv;
|
||||
} /* RCNetStreamIO::GetLocalName */
|
||||
|
||||
|
|
@ -78,25 +99,37 @@ PRStatus RCNetStreamIO::GetPeerName(RCNetAddr *addr) const
|
|||
{
|
||||
PRNetAddr peer;
|
||||
PRStatus rv = (fd->methods->getpeername)(fd, &peer);
|
||||
if (PR_SUCCESS == rv) *addr = &peer;
|
||||
if (PR_SUCCESS == rv) {
|
||||
*addr = &peer;
|
||||
}
|
||||
return rv;
|
||||
} /* RCNetStreamIO::GetPeerName */
|
||||
|
||||
PRStatus RCNetStreamIO::GetSocketOption(PRSocketOptionData *data) const
|
||||
{ return (fd->methods->getsocketoption)(fd, data); }
|
||||
{
|
||||
return (fd->methods->getsocketoption)(fd, data);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Listen(PRIntn backlog)
|
||||
{ return (fd->methods->listen)(fd, backlog); }
|
||||
{
|
||||
return (fd->methods->listen)(fd, backlog);
|
||||
}
|
||||
|
||||
PRInt16 RCNetStreamIO::Poll(PRInt16 in_flags, PRInt16 *out_flags)
|
||||
{ return (fd->methods->poll)(fd, in_flags, out_flags); }
|
||||
{
|
||||
return (fd->methods->poll)(fd, in_flags, out_flags);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Read(void *buf, PRSize amount)
|
||||
{ return (fd->methods->read)(fd, buf, amount); }
|
||||
{
|
||||
return (fd->methods->read)(fd, buf, amount);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Recv(
|
||||
void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
|
||||
{ return (fd->methods->recv)(fd, buf, amount, flags, timeout); }
|
||||
{
|
||||
return (fd->methods->recv)(fd, buf, amount, flags, timeout);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Recvfrom(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
|
|
@ -104,25 +137,35 @@ PRInt32 RCNetStreamIO::Recvfrom(
|
|||
{
|
||||
PRNetAddr peer;
|
||||
PRInt32 rv = (fd->methods->recvfrom)(
|
||||
fd, buf, amount, flags, &peer, timeout);
|
||||
if (-1 != rv) *addr = &peer;
|
||||
fd, buf, amount, flags, &peer, timeout);
|
||||
if (-1 != rv) {
|
||||
*addr = &peer;
|
||||
}
|
||||
return rv;
|
||||
} /* RCNetStreamIO::Recvfrom */
|
||||
|
||||
PRInt32 RCNetStreamIO::Send(
|
||||
const void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
|
||||
{ return (fd->methods->send)(fd, buf, amount, flags, timeout); }
|
||||
{
|
||||
return (fd->methods->send)(fd, buf, amount, flags, timeout);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Sendto(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr, const RCInterval& timeout)
|
||||
{ return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout); }
|
||||
{
|
||||
return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::SetSocketOption(const PRSocketOptionData *data)
|
||||
{ return (fd->methods->setsocketoption)(fd, data); }
|
||||
{
|
||||
return (fd->methods->setsocketoption)(fd, data);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Shutdown(RCIO::ShutdownHow how)
|
||||
{ return (fd->methods->shutdown)(fd, (PRIntn)how); }
|
||||
{
|
||||
return (fd->methods->shutdown)(fd, (PRIntn)how);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::TransmitFile(
|
||||
RCIO *source, const void *headers, PRSize hlen,
|
||||
|
|
@ -130,33 +173,52 @@ PRInt32 RCNetStreamIO::TransmitFile(
|
|||
{
|
||||
RCNetStreamIO *src = (RCNetStreamIO*)source;
|
||||
return (fd->methods->transmitfile)(
|
||||
fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout); }
|
||||
fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Write(const void *buf, PRSize amount)
|
||||
{ return (fd->methods->write)(fd, buf, amount); }
|
||||
{
|
||||
return (fd->methods->write)(fd, buf, amount);
|
||||
}
|
||||
|
||||
PRInt32 RCNetStreamIO::Writev(
|
||||
const PRIOVec *iov, PRSize size, const RCInterval& timeout)
|
||||
{ return (fd->methods->writev)(fd, iov, size, timeout); }
|
||||
|
||||
{
|
||||
return (fd->methods->writev)(fd, iov, size, timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
** Invalid functions
|
||||
*/
|
||||
|
||||
PRStatus RCNetStreamIO::Close()
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::FileInfo(RCFileInfo*) const
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Fsync()
|
||||
{ return (fd->methods->fsync)(fd); }
|
||||
{
|
||||
return (fd->methods->fsync)(fd);
|
||||
}
|
||||
|
||||
PRStatus RCNetStreamIO::Open(const char*, PRIntn, PRIntn)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt64 RCNetStreamIO::Seek(PRInt64, RCIO::Whence)
|
||||
{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
|
||||
{
|
||||
PR_SetError(PR_INVALID_METHOD_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/* RCNetStreamIO.cpp */
|
||||
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ public:
|
|||
|
||||
virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout);
|
||||
virtual PRInt32 AcceptRead(
|
||||
RCIO **nd, RCNetAddr **raddr, void *buf,
|
||||
PRSize amount, const RCInterval& timeout);
|
||||
RCIO **nd, RCNetAddr **raddr, void *buf,
|
||||
PRSize amount, const RCInterval& timeout);
|
||||
virtual PRInt64 Available();
|
||||
virtual PRStatus Bind(const RCNetAddr& addr);
|
||||
virtual PRStatus Connect(
|
||||
const RCNetAddr& addr, const RCInterval& timeout);
|
||||
const RCNetAddr& addr, const RCInterval& timeout);
|
||||
virtual PRStatus GetLocalName(RCNetAddr *addr) const;
|
||||
virtual PRStatus GetPeerName(RCNetAddr *addr) const;
|
||||
virtual PRStatus GetSocketOption(PRSocketOptionData *data) const;
|
||||
|
|
@ -50,28 +50,28 @@ public:
|
|||
virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags);
|
||||
virtual PRInt32 Read(void *buf, PRSize amount);
|
||||
virtual PRInt32 Recv(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
virtual PRInt32 Recvfrom(
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout);
|
||||
void *buf, PRSize amount, PRIntn flags,
|
||||
RCNetAddr* addr, const RCInterval& timeout);
|
||||
virtual PRInt32 Send(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCInterval& timeout);
|
||||
virtual PRInt32 Sendto(
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout);
|
||||
const void *buf, PRSize amount, PRIntn flags,
|
||||
const RCNetAddr& addr,
|
||||
const RCInterval& timeout);
|
||||
virtual PRStatus SetSocketOption(const PRSocketOptionData *data);
|
||||
virtual PRStatus Shutdown(ShutdownHow how);
|
||||
virtual PRInt32 TransmitFile(
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout);
|
||||
RCIO *source, const void *headers,
|
||||
PRSize hlen, RCIO::FileDisposition flags,
|
||||
const RCInterval& timeout);
|
||||
virtual PRInt32 Write(const void *buf, PRSize amount);
|
||||
virtual PRInt32 Writev(
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout);
|
||||
const PRIOVec *iov, PRSize size,
|
||||
const RCInterval& timeout);
|
||||
|
||||
private:
|
||||
/* functions unavailable to this clients of this class */
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ static RCPrimordialThread *primordial = NULL;
|
|||
void nas_Root(void *arg)
|
||||
{
|
||||
RCThread *him = (RCThread*)arg;
|
||||
while (RCThread::ex_unstarted == him->execution)
|
||||
(void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT); /* wait for Start() */
|
||||
while (RCThread::ex_unstarted == him->execution) {
|
||||
(void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT); /* wait for Start() */
|
||||
}
|
||||
him->RootFunction(); /* he gets a self reference */
|
||||
if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity))
|
||||
if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity)) {
|
||||
delete him;
|
||||
}
|
||||
} /* nas_Root */
|
||||
|
||||
RCThread::~RCThread() { }
|
||||
|
|
@ -40,9 +42,9 @@ RCThread::RCThread(
|
|||
{
|
||||
execution = ex_unstarted;
|
||||
identity = PR_CreateThread(
|
||||
PR_USER_THREAD, nas_Root, this,
|
||||
PR_GetThreadPriority(PR_GetCurrentThread()),
|
||||
(PRThreadScope)scope, (PRThreadState)join, stackSize);
|
||||
PR_USER_THREAD, nas_Root, this,
|
||||
PR_GetThreadPriority(PR_GetCurrentThread()),
|
||||
(PRThreadScope)scope, (PRThreadState)join, stackSize);
|
||||
} /* RCThread::RCThread */
|
||||
|
||||
void RCThread::operator=(const RCThread&)
|
||||
|
|
@ -77,8 +79,12 @@ PRStatus RCThread::Join()
|
|||
rv = PR_FAILURE;
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
}
|
||||
else rv = PR_JoinThread(identity);
|
||||
if (PR_SUCCESS == rv) delete this;
|
||||
else {
|
||||
rv = PR_JoinThread(identity);
|
||||
}
|
||||
if (PR_SUCCESS == rv) {
|
||||
delete this;
|
||||
}
|
||||
return rv;
|
||||
} /* RCThread::Join */
|
||||
|
||||
|
|
@ -90,27 +96,41 @@ PRStatus RCThread::Interrupt()
|
|||
rv = PR_FAILURE;
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
}
|
||||
else rv = PR_Interrupt(identity);
|
||||
else {
|
||||
rv = PR_Interrupt(identity);
|
||||
}
|
||||
return rv;
|
||||
} /* RCThread::Interrupt */
|
||||
|
||||
void RCThread::ClearInterrupt() { PR_ClearInterrupt(); }
|
||||
void RCThread::ClearInterrupt() {
|
||||
PR_ClearInterrupt();
|
||||
}
|
||||
|
||||
void RCThread::SetPriority(RCThread::Priority new_priority)
|
||||
{ PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); }
|
||||
{
|
||||
PR_SetThreadPriority(identity, (PRThreadPriority)new_priority);
|
||||
}
|
||||
|
||||
PRThread *RCThread::Self()
|
||||
{ return PR_GetCurrentThread(); }
|
||||
{
|
||||
return PR_GetCurrentThread();
|
||||
}
|
||||
|
||||
RCThread::Scope RCThread::GetScope() const
|
||||
{ return (RCThread::Scope)PR_GetThreadScope(identity); }
|
||||
{
|
||||
return (RCThread::Scope)PR_GetThreadScope(identity);
|
||||
}
|
||||
|
||||
RCThread::State RCThread::GetState() const
|
||||
{ return (RCThread::State)PR_GetThreadState(identity); }
|
||||
{
|
||||
return (RCThread::State)PR_GetThreadState(identity);
|
||||
}
|
||||
|
||||
RCThread::Priority RCThread::GetPriority() const
|
||||
{ return (RCThread::Priority)PR_GetThreadPriority(identity); }
|
||||
|
||||
{
|
||||
return (RCThread::Priority)PR_GetThreadPriority(identity);
|
||||
}
|
||||
|
||||
static void _rc_PDDestructor(RCThreadPrivateData* privateData)
|
||||
{
|
||||
PR_ASSERT(NULL != privateData);
|
||||
|
|
@ -120,10 +140,14 @@ static void _rc_PDDestructor(RCThreadPrivateData* privateData)
|
|||
static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor;
|
||||
|
||||
PRStatus RCThread::NewPrivateIndex(PRUintn* index)
|
||||
{ return PR_NewThreadPrivateIndex(index, _tpd_dtor); }
|
||||
{
|
||||
return PR_NewThreadPrivateIndex(index, _tpd_dtor);
|
||||
}
|
||||
|
||||
PRStatus RCThread::SetPrivateData(PRUintn index)
|
||||
{ return PR_SetThreadPrivate(index, NULL); }
|
||||
{
|
||||
return PR_SetThreadPrivate(index, NULL);
|
||||
}
|
||||
|
||||
PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data)
|
||||
{
|
||||
|
|
@ -131,10 +155,15 @@ PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data)
|
|||
}
|
||||
|
||||
RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index)
|
||||
{ return (RCThreadPrivateData*)PR_GetThreadPrivate(index); }
|
||||
{
|
||||
return (RCThreadPrivateData*)PR_GetThreadPrivate(index);
|
||||
}
|
||||
|
||||
PRStatus RCThread::Sleep(const RCInterval& ticks)
|
||||
{ PRIntervalTime tmo = ticks; return PR_Sleep(tmo); }
|
||||
{
|
||||
PRIntervalTime tmo = ticks;
|
||||
return PR_Sleep(tmo);
|
||||
}
|
||||
|
||||
RCPrimordialThread *RCThread::WrapPrimordialThread()
|
||||
{
|
||||
|
|
@ -155,7 +184,9 @@ RCPrimordialThread *RCThread::WrapPrimordialThread()
|
|||
me->execution = RCThread::ex_started;
|
||||
me->identity = PR_GetCurrentThread();
|
||||
}
|
||||
else delete me; /* somebody beat us to it */
|
||||
else {
|
||||
delete me; /* somebody beat us to it */
|
||||
}
|
||||
}
|
||||
return primordial;
|
||||
} /* RCThread::WrapPrimordialThread */
|
||||
|
|
@ -166,10 +197,12 @@ RCPrimordialThread::~RCPrimordialThread() { }
|
|||
|
||||
void RCPrimordialThread::RootFunction()
|
||||
{
|
||||
PR_NOT_REACHED("Primordial thread calling root function");
|
||||
PR_NOT_REACHED("Primordial thread calling root function");
|
||||
} /* RCPrimordialThread::RootFunction */
|
||||
|
||||
PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); }
|
||||
|
||||
PRStatus RCPrimordialThread::Cleanup() {
|
||||
return PR_Cleanup();
|
||||
}
|
||||
|
||||
PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class PR_IMPLEMENT(RCThread): public RCBase
|
|||
{
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
typedef enum
|
||||
{
|
||||
local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD
|
||||
} Scope;
|
||||
|
|
@ -68,12 +68,12 @@ public:
|
|||
* the target thread returns from it's root function.
|
||||
*/
|
||||
virtual PRStatus Join();
|
||||
|
||||
|
||||
/*
|
||||
* The priority of a newly created thread is the same as the creator.
|
||||
* The priority may be changed either by the new thread itself, by
|
||||
* the creator or any other arbitrary thread.
|
||||
*/
|
||||
*/
|
||||
virtual void SetPriority(Priority newPriority);
|
||||
|
||||
|
||||
|
|
@ -82,14 +82,14 @@ public:
|
|||
* is doing and return with a well known error code.
|
||||
*/
|
||||
virtual PRStatus Interrupt();
|
||||
|
||||
|
||||
/*
|
||||
* And in case a thread was interrupted and didn't get a chance
|
||||
* to have the notification delivered, a way to cancel the pending
|
||||
* status.
|
||||
*/
|
||||
static void ClearInterrupt();
|
||||
|
||||
|
||||
/*
|
||||
* Methods to discover the attributes of an existing thread.
|
||||
*/
|
||||
|
|
@ -150,15 +150,15 @@ private:
|
|||
/* There is no public default constructor or copy constructor */
|
||||
RCThread();
|
||||
RCThread(const RCThread&);
|
||||
|
||||
|
||||
/* And there is no assignment operator */
|
||||
void operator=(const RCThread&);
|
||||
|
||||
public:
|
||||
static RCPrimordialThread *WrapPrimordialThread();
|
||||
static RCPrimordialThread *WrapPrimordialThread();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
** class RCPrimordialThread
|
||||
*/
|
||||
|
|
@ -180,7 +180,7 @@ public:
|
|||
*/
|
||||
static PRStatus SetVirtualProcessors(PRIntn count=10);
|
||||
|
||||
friend class RCThread;
|
||||
friend class RCThread;
|
||||
private:
|
||||
/*
|
||||
** None other than the runtime can create of destruct
|
||||
|
|
@ -192,4 +192,4 @@ private:
|
|||
void RootFunction();
|
||||
}; /* RCPrimordialThread */
|
||||
|
||||
#endif /* defined(_RCTHREAD_H) */
|
||||
#endif /* defined(_RCTHREAD_H) */
|
||||
|
|
|
|||
|
|
@ -11,24 +11,46 @@
|
|||
|
||||
RCTime::~RCTime() { }
|
||||
|
||||
RCTime::RCTime(PRTime time): RCBase() { gmt = time; }
|
||||
RCTime::RCTime(const RCTime& his): RCBase() { gmt = his.gmt; }
|
||||
RCTime::RCTime(RCTime::Current): RCBase() { gmt = PR_Now(); }
|
||||
RCTime::RCTime(PRTime time): RCBase() {
|
||||
gmt = time;
|
||||
}
|
||||
RCTime::RCTime(const RCTime& his): RCBase() {
|
||||
gmt = his.gmt;
|
||||
}
|
||||
RCTime::RCTime(RCTime::Current): RCBase() {
|
||||
gmt = PR_Now();
|
||||
}
|
||||
RCTime::RCTime(const PRExplodedTime& time): RCBase()
|
||||
{ gmt = PR_ImplodeTime(&time); }
|
||||
{
|
||||
gmt = PR_ImplodeTime(&time);
|
||||
}
|
||||
|
||||
void RCTime::operator=(const PRExplodedTime& time)
|
||||
{ gmt = PR_ImplodeTime(&time); }
|
||||
{
|
||||
gmt = PR_ImplodeTime(&time);
|
||||
}
|
||||
|
||||
RCTime RCTime::operator+(const RCTime& his)
|
||||
{ RCTime sum(gmt + his.gmt); return sum; }
|
||||
{
|
||||
RCTime sum(gmt + his.gmt);
|
||||
return sum;
|
||||
}
|
||||
|
||||
RCTime RCTime::operator-(const RCTime& his)
|
||||
{ RCTime difference(gmt - his.gmt); return difference; }
|
||||
{
|
||||
RCTime difference(gmt - his.gmt);
|
||||
return difference;
|
||||
}
|
||||
|
||||
RCTime RCTime::operator/(PRUint64 his)
|
||||
{ RCTime quotient(gmt / gmt); return quotient; }
|
||||
{
|
||||
RCTime quotient(gmt / gmt);
|
||||
return quotient;
|
||||
}
|
||||
|
||||
RCTime RCTime::operator*(PRUint64 his)
|
||||
{ RCTime product(gmt * his); return product; }
|
||||
{
|
||||
RCTime product(gmt * his);
|
||||
return product;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
virtual ~RCTime();
|
||||
|
||||
/* assignment operators */
|
||||
void operator=(const RCTime&);
|
||||
void operator=(const RCTime&);
|
||||
void operator=(const PRExplodedTime&);
|
||||
|
||||
/* comparitive operators */
|
||||
|
|
@ -75,31 +75,61 @@ public:
|
|||
|
||||
inline RCTime::RCTime(): RCBase() { }
|
||||
|
||||
inline void RCTime::Now() { gmt = PR_Now(); }
|
||||
inline RCTime::operator PRTime() const { return gmt; }
|
||||
inline void RCTime::Now() {
|
||||
gmt = PR_Now();
|
||||
}
|
||||
inline RCTime::operator PRTime() const {
|
||||
return gmt;
|
||||
}
|
||||
|
||||
inline void RCTime::operator=(PRTime his) { gmt = his; }
|
||||
inline void RCTime::operator=(const RCTime& his) { gmt = his.gmt; }
|
||||
inline void RCTime::operator=(PRTime his) {
|
||||
gmt = his;
|
||||
}
|
||||
inline void RCTime::operator=(const RCTime& his) {
|
||||
gmt = his.gmt;
|
||||
}
|
||||
|
||||
inline PRBool RCTime::operator<(const RCTime& his)
|
||||
{ return (gmt < his.gmt) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (gmt < his.gmt) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCTime::operator>(const RCTime& his)
|
||||
{ return (gmt > his.gmt) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (gmt > his.gmt) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCTime::operator<=(const RCTime& his)
|
||||
{ return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCTime::operator>=(const RCTime& his)
|
||||
{ return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
inline PRBool RCTime::operator==(const RCTime& his)
|
||||
{ return (gmt == his.gmt) ? PR_TRUE : PR_FALSE; }
|
||||
{
|
||||
return (gmt == his.gmt) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
inline RCTime& RCTime::operator+=(const RCTime& his)
|
||||
{ gmt += his.gmt; return *this; }
|
||||
{
|
||||
gmt += his.gmt;
|
||||
return *this;
|
||||
}
|
||||
inline RCTime& RCTime::operator-=(const RCTime& his)
|
||||
{ gmt -= his.gmt; return *this; }
|
||||
{
|
||||
gmt -= his.gmt;
|
||||
return *this;
|
||||
}
|
||||
inline RCTime& RCTime::operator/=(PRUint64 his)
|
||||
{ gmt /= his; return *this; }
|
||||
{
|
||||
gmt /= his;
|
||||
return *this;
|
||||
}
|
||||
inline RCTime& RCTime::operator*=(PRUint64 his)
|
||||
{ gmt *= his; return *this; }
|
||||
{
|
||||
gmt *= his;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* defined(_RCTIME_H) */
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -49,24 +49,6 @@ LDOPTS = -L$(dist_libdir)
|
|||
LIBPR = -lnspr$(MOD_MAJOR_VERSION)
|
||||
LIBPL = -lplc$(MOD_MAJOR_VERSION)
|
||||
|
||||
ifeq ($(OS_ARCH), IRIX)
|
||||
LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared
|
||||
# For 6.x machines, include this flag
|
||||
ifeq ($(basename $(OS_RELEASE)),6)
|
||||
ifeq ($(USE_N32),1)
|
||||
LDOPTS += -n32
|
||||
else
|
||||
LDOPTS += -32
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PTHREADS), 1)
|
||||
ifeq ($(OS_RELEASE), 6.2)
|
||||
LDOPTS += -Wl,-woff,85
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Solaris
|
||||
ifeq ($(OS_ARCH), SunOS)
|
||||
ifdef NS_USE_GCC
|
||||
|
|
@ -103,10 +85,6 @@ ifneq ($(OS_ARCH), WINNT)
|
|||
PWD = $(shell pwd)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), OSF1)
|
||||
LDOPTS += -rpath $(PWD)/$(dist_libdir)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), HP-UX)
|
||||
LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@
|
|||
** Description: Test to hammer on various components of NSPR
|
||||
** Modification History:
|
||||
** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
|
||||
** The debug mode will print all of the printfs associated with this test.
|
||||
** The regress mode will be the default mode. Since the regress tool limits
|
||||
** The debug mode will print all of the printfs associated with this test.
|
||||
** The regress mode will be the default mode. Since the regress tool limits
|
||||
** the output to a one line status:PASS or FAIL,all of the printf statements
|
||||
** have been handled with an if (debug_mode) statement.
|
||||
** have been handled with an if (debug_mode) statement.
|
||||
** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
|
||||
** recognize the return code from tha main program.
|
||||
** recognize the return code from tha main program.
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
|
|
@ -46,19 +46,21 @@ class HammerData
|
|||
{
|
||||
public:
|
||||
typedef enum {
|
||||
sg_go, sg_stop, sg_done} Action;
|
||||
sg_go, sg_stop, sg_done
|
||||
} Action;
|
||||
typedef enum {
|
||||
sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem;
|
||||
sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek
|
||||
} Problem;
|
||||
|
||||
virtual ~HammerData();
|
||||
HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip);
|
||||
virtual ~HammerData();
|
||||
HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip);
|
||||
virtual PRUint32 Random();
|
||||
|
||||
Action action;
|
||||
Problem problem;
|
||||
PRUint32 writes;
|
||||
RCInterval timein;
|
||||
friend class Hammer;
|
||||
friend class Hammer;
|
||||
private:
|
||||
RCLock *ml;
|
||||
RCCondition *cv;
|
||||
|
|
@ -117,7 +119,7 @@ Hammer::~Hammer() { }
|
|||
|
||||
Hammer::Hammer(
|
||||
RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip):
|
||||
HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { }
|
||||
HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { }
|
||||
|
||||
HammerData::~HammerData() { }
|
||||
|
||||
|
|
@ -171,7 +173,9 @@ void Hammer::RootFunction()
|
|||
|
||||
(void)sprintf(filename, "%ssg%04p.dat", baseName, this);
|
||||
|
||||
if (debug_mode) PR_fprintf(output, "Starting work on %s\n", filename);
|
||||
if (debug_mode) {
|
||||
PR_fprintf(output, "Starting work on %s\n", filename);
|
||||
}
|
||||
|
||||
while (PR_TRUE)
|
||||
{
|
||||
|
|
@ -182,52 +186,78 @@ void Hammer::RootFunction()
|
|||
while (minor-- > 0)
|
||||
{
|
||||
problem = sg_okay;
|
||||
if (action != sg_go) goto finished;
|
||||
if (action != sg_go) {
|
||||
goto finished;
|
||||
}
|
||||
problem = sg_open;
|
||||
rv = file.Open(filename, PR_RDWR|PR_CREATE_FILE, 0666);
|
||||
if (PR_FAILURE == rv) goto finished;
|
||||
if (PR_FAILURE == rv) {
|
||||
goto finished;
|
||||
}
|
||||
for (index = 0; index < pages; index++)
|
||||
{
|
||||
problem = sg_okay;
|
||||
if (action != sg_go) goto close;
|
||||
if (action != sg_go) {
|
||||
goto close;
|
||||
}
|
||||
problem = sg_seek;
|
||||
bytes = file.Seek(pageSize * index, RCFileIO::set);
|
||||
if (bytes != pageSize * index) goto close;
|
||||
if (bytes != pageSize * index) {
|
||||
goto close;
|
||||
}
|
||||
problem = sg_write;
|
||||
bytes = file.Write(&zero, sizeof(zero));
|
||||
if (bytes <= 0) goto close;
|
||||
if (bytes <= 0) {
|
||||
goto close;
|
||||
}
|
||||
writes += 1;
|
||||
}
|
||||
problem = sg_close;
|
||||
rv = file.Close();
|
||||
if (rv != PR_SUCCESS) goto purge;
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto purge;
|
||||
}
|
||||
|
||||
problem = sg_okay;
|
||||
if (action != sg_go) goto purge;
|
||||
if (action != sg_go) {
|
||||
goto purge;
|
||||
}
|
||||
|
||||
problem = sg_open;
|
||||
rv = file.Open(filename, PR_RDWR, 0666);
|
||||
if (PR_FAILURE == rv) goto finished;
|
||||
if (PR_FAILURE == rv) {
|
||||
goto finished;
|
||||
}
|
||||
for (index = 0; index < pages; index++)
|
||||
{
|
||||
problem = sg_okay;
|
||||
if (action != sg_go) goto close;
|
||||
if (action != sg_go) {
|
||||
goto close;
|
||||
}
|
||||
problem = sg_seek;
|
||||
bytes = file.Seek(pageSize * index, RCFileIO::set);
|
||||
if (bytes != pageSize * index) goto close;
|
||||
if (bytes != pageSize * index) {
|
||||
goto close;
|
||||
}
|
||||
problem = sg_write;
|
||||
bytes = file.Write(&zero, sizeof(zero));
|
||||
if (bytes <= 0) goto close;
|
||||
if (bytes <= 0) {
|
||||
goto close;
|
||||
}
|
||||
writes += 1;
|
||||
random = (random + 511) % pages;
|
||||
}
|
||||
problem = sg_close;
|
||||
rv = file.Close();
|
||||
if (rv != PR_SUCCESS) goto purge;
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto purge;
|
||||
}
|
||||
problem = sg_delete;
|
||||
rv = file.Delete(filename);
|
||||
if (rv != PR_SUCCESS) goto finished;
|
||||
}
|
||||
if (rv != PR_SUCCESS) {
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close:
|
||||
|
|
@ -239,7 +269,9 @@ finished:
|
|||
action = HammerData::sg_done;
|
||||
cv->Notify();
|
||||
|
||||
if (debug_mode) PR_fprintf(output, "Ending work on %s\n", filename);
|
||||
if (debug_mode) {
|
||||
PR_fprintf(output, "Ending work on %s\n", filename);
|
||||
}
|
||||
|
||||
return;
|
||||
} /* Hammer::RootFunction */
|
||||
|
|
@ -278,7 +310,7 @@ static Hammer* hammer[100];
|
|||
PRIntn main (PRIntn argc, char *argv[])
|
||||
{
|
||||
RCLock ml;
|
||||
PLOptStatus os;
|
||||
PLOptStatus os;
|
||||
RCCondition cv(&ml);
|
||||
PRUint32 writesMax = 0, durationTot = 0;
|
||||
RCThread::Scope thread_scope = RCThread::local;
|
||||
|
|
@ -288,57 +320,65 @@ PRIntn main (PRIntn argc, char *argv[])
|
|||
|
||||
const char *where[] = {"okay", "open", "close", "delete", "write", "seek"};
|
||||
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:");
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:");
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
{
|
||||
if (PL_OPT_BAD == os) continue;
|
||||
if (PL_OPT_BAD == os) {
|
||||
continue;
|
||||
}
|
||||
switch (opt->option)
|
||||
{
|
||||
case 0:
|
||||
baseName = opt->value;
|
||||
break;
|
||||
case 'G': /* global threads */
|
||||
thread_scope = RCThread::global;
|
||||
break;
|
||||
case 'd': /* debug mode */
|
||||
debug_mode = 1;
|
||||
break;
|
||||
case 'l': /* limiting number */
|
||||
limit = atoi(opt->value);
|
||||
break;
|
||||
case 't': /* number of threads */
|
||||
threads = atoi(opt->value);
|
||||
break;
|
||||
case 'i': /* iteration counter */
|
||||
max_virtual_procs = atoi(opt->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
baseName = opt->value;
|
||||
break;
|
||||
case 'G': /* global threads */
|
||||
thread_scope = RCThread::global;
|
||||
break;
|
||||
case 'd': /* debug mode */
|
||||
debug_mode = 1;
|
||||
break;
|
||||
case 'l': /* limiting number */
|
||||
limit = atoi(opt->value);
|
||||
break;
|
||||
case 't': /* number of threads */
|
||||
threads = atoi(opt->value);
|
||||
break;
|
||||
case 'i': /* iteration counter */
|
||||
max_virtual_procs = atoi(opt->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
PL_DestroyOptState(opt);
|
||||
PL_DestroyOptState(opt);
|
||||
output = PR_GetSpecialFD(PR_StandardOutput);
|
||||
|
||||
/* main test */
|
||||
|
||||
/* main test */
|
||||
|
||||
cv.SetTimeout(interleave);
|
||||
|
||||
if (max_virtual_procs == 0) max_virtual_procs = 2;
|
||||
if (limit == 0) limit = 57;
|
||||
if (threads == 0) threads = 10;
|
||||
|
||||
if (max_virtual_procs == 0) {
|
||||
max_virtual_procs = 2;
|
||||
}
|
||||
if (limit == 0) {
|
||||
limit = 57;
|
||||
}
|
||||
if (threads == 0) {
|
||||
threads = 10;
|
||||
}
|
||||
|
||||
if (debug_mode) PR_fprintf(output,
|
||||
"%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n",
|
||||
programName, max_virtual_procs, threads, limit,
|
||||
(thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL");
|
||||
"%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n",
|
||||
programName, max_virtual_procs, threads, limit,
|
||||
(thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL");
|
||||
|
||||
for (virtual_procs = 0; virtual_procs < max_virtual_procs; ++virtual_procs)
|
||||
{
|
||||
if (debug_mode)
|
||||
PR_fprintf(output,
|
||||
"%s: Setting number of virtual processors to %d\n",
|
||||
programName, virtual_procs + 1);
|
||||
RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1);
|
||||
PR_fprintf(output,
|
||||
"%s: Setting number of virtual processors to %d\n",
|
||||
programName, virtual_procs + 1);
|
||||
RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1);
|
||||
for (active = 0; active < threads; active++)
|
||||
{
|
||||
hammer[active] = new Hammer(thread_scope, &ml, &cv, limit);
|
||||
|
|
@ -354,8 +394,9 @@ PRIntn main (PRIntn argc, char *argv[])
|
|||
RCEnter scope(&ml);
|
||||
for (poll = 0; poll < threads; poll++)
|
||||
{
|
||||
if (hammer[poll]->action == HammerData::sg_go) /* don't overwrite done */
|
||||
hammer[poll]->action = HammerData::sg_stop; /* ask him to stop */
|
||||
if (hammer[poll]->action == HammerData::sg_go) { /* don't overwrite done */
|
||||
hammer[poll]->action = HammerData::sg_stop; /* ask him to stop */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -364,24 +405,32 @@ PRIntn main (PRIntn argc, char *argv[])
|
|||
for (poll = 0; poll < threads; poll++)
|
||||
{
|
||||
ml.Acquire();
|
||||
while (hammer[poll]->action < HammerData::sg_done) cv.Wait();
|
||||
while (hammer[poll]->action < HammerData::sg_done) {
|
||||
cv.Wait();
|
||||
}
|
||||
ml.Release();
|
||||
|
||||
if (hammer[poll]->problem == HammerData::sg_okay)
|
||||
{
|
||||
duration = RCInterval(RCInterval::now) - hammer[poll]->timein;
|
||||
writes = hammer[poll]->writes * 1000 / duration;
|
||||
if (writes < writesMin) writesMin = writes;
|
||||
if (writes > writesMax) writesMax = writes;
|
||||
if (writes < writesMin) {
|
||||
writesMin = writes;
|
||||
}
|
||||
if (writes > writesMax) {
|
||||
writesMax = writes;
|
||||
}
|
||||
writesTot += hammer[poll]->writes;
|
||||
durationTot += duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug_mode) PR_fprintf(output,
|
||||
"%s: test failed %s after %ld seconds\n",
|
||||
programName, where[hammer[poll]->problem], duration);
|
||||
else failed_already=1;
|
||||
"%s: test failed %s after %ld seconds\n",
|
||||
programName, where[hammer[poll]->problem], duration);
|
||||
else {
|
||||
failed_already=1;
|
||||
}
|
||||
}
|
||||
active -= 1; /* this is another one down */
|
||||
(void)hammer[poll]->Join();
|
||||
|
|
@ -389,12 +438,12 @@ PRIntn main (PRIntn argc, char *argv[])
|
|||
}
|
||||
}
|
||||
if (debug_mode) PR_fprintf(output,
|
||||
"%s: [%ld [%ld] %ld] writes/sec average\n",
|
||||
programName, writesMin,
|
||||
writesTot * 1000 / durationTot, writesMax);
|
||||
"%s: [%ld [%ld] %ld] writes/sec average\n",
|
||||
programName, writesMin,
|
||||
writesTot * 1000 / durationTot, writesMax);
|
||||
}
|
||||
|
||||
failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup());
|
||||
PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n");
|
||||
return failed_already;
|
||||
failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup());
|
||||
PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n");
|
||||
return failed_already;
|
||||
} /* main */
|
||||
|
|
|
|||
|
|
@ -70,8 +70,12 @@ void Shared::RootFunction()
|
|||
while (PR_SUCCESS == status)
|
||||
{
|
||||
RCEnter entry(ml);
|
||||
while (twiddle && (PR_SUCCESS == status)) status = Wait();
|
||||
if (verbosity) PR_fprintf(debug_out, "+");
|
||||
while (twiddle && (PR_SUCCESS == status)) {
|
||||
status = Wait();
|
||||
}
|
||||
if (verbosity) {
|
||||
PR_fprintf(debug_out, "+");
|
||||
}
|
||||
twiddle = PR_TRUE;
|
||||
next->twiddle = PR_FALSE;
|
||||
next->Notify();
|
||||
|
|
@ -83,11 +87,11 @@ static void Help(void)
|
|||
debug_out = PR_STDOUT;
|
||||
|
||||
PR_fprintf(
|
||||
debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n");
|
||||
debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n");
|
||||
PR_fprintf(
|
||||
debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
|
||||
debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
|
||||
PR_fprintf(
|
||||
debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
|
||||
debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
|
||||
PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
|
||||
PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
|
||||
PR_fprintf(debug_out, "-G n\tglobal threads only (default: FALSE)\n");
|
||||
|
|
@ -96,59 +100,63 @@ static void Help(void)
|
|||
|
||||
PRIntn main(PRIntn argc, char **argv)
|
||||
{
|
||||
PLOptStatus os;
|
||||
PLOptStatus os;
|
||||
PRStatus status;
|
||||
PRBool help = PR_FALSE;
|
||||
PRUintn concurrency = 1;
|
||||
RCThread::Scope thread_scope = RCThread::local;
|
||||
PRUintn thread_count, inner_count, loop_count, average;
|
||||
PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
{
|
||||
if (PL_OPT_BAD == os) continue;
|
||||
if (PL_OPT_BAD == os) {
|
||||
continue;
|
||||
}
|
||||
switch (opt->option)
|
||||
{
|
||||
case 'v': /* verbose mode */
|
||||
verbosity = PR_TRUE;
|
||||
case 'd': /* debug mode */
|
||||
debug_mode = PR_TRUE;
|
||||
break;
|
||||
case 'c': /* loop counter */
|
||||
loop_limit = atoi(opt->value);
|
||||
break;
|
||||
case 't': /* thread limit */
|
||||
thread_limit = atoi(opt->value);
|
||||
break;
|
||||
case 'C': /* Concurrency limit */
|
||||
concurrency = atoi(opt->value);
|
||||
break;
|
||||
case 'G': /* global threads only */
|
||||
thread_scope = RCThread::global;
|
||||
break;
|
||||
case 'h': /* help message */
|
||||
Help();
|
||||
help = PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 'v': /* verbose mode */
|
||||
verbosity = PR_TRUE;
|
||||
case 'd': /* debug mode */
|
||||
debug_mode = PR_TRUE;
|
||||
break;
|
||||
case 'c': /* loop counter */
|
||||
loop_limit = atoi(opt->value);
|
||||
break;
|
||||
case 't': /* thread limit */
|
||||
thread_limit = atoi(opt->value);
|
||||
break;
|
||||
case 'C': /* Concurrency limit */
|
||||
concurrency = atoi(opt->value);
|
||||
break;
|
||||
case 'G': /* global threads only */
|
||||
thread_scope = RCThread::global;
|
||||
break;
|
||||
case 'h': /* help message */
|
||||
Help();
|
||||
help = PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
PL_DestroyOptState(opt);
|
||||
PL_DestroyOptState(opt);
|
||||
|
||||
if (help) return -1;
|
||||
if (help) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PR_TRUE == debug_mode)
|
||||
{
|
||||
debug_out = PR_STDOUT;
|
||||
PR_fprintf(debug_out, "Test parameters\n");
|
||||
PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
|
||||
PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
|
||||
PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
|
||||
PR_fprintf(
|
||||
debug_out, "\tThread type: %s\n",
|
||||
(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
|
||||
}
|
||||
if (PR_TRUE == debug_mode)
|
||||
{
|
||||
debug_out = PR_STDOUT;
|
||||
PR_fprintf(debug_out, "Test parameters\n");
|
||||
PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
|
||||
PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
|
||||
PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
|
||||
PR_fprintf(
|
||||
debug_out, "\tThread type: %s\n",
|
||||
(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
|
||||
}
|
||||
|
||||
/*
|
||||
** The interesting part starts here
|
||||
|
|
@ -165,62 +173,68 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
shared = new Shared(thread_scope, link, &lock);
|
||||
shared->Start(); /* make it run */
|
||||
link = (Home*)shared;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass the message around the horn a few times */
|
||||
for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
|
||||
{
|
||||
timein.SetToNow();
|
||||
for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
|
||||
{
|
||||
RCEnter entry(&lock);
|
||||
home.twiddle = PR_TRUE;
|
||||
shared->twiddle = PR_FALSE;
|
||||
shared->Notify();
|
||||
while (home.twiddle)
|
||||
timein.SetToNow();
|
||||
for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
|
||||
{
|
||||
RCEnter entry(&lock);
|
||||
home.twiddle = PR_TRUE;
|
||||
shared->twiddle = PR_FALSE;
|
||||
shared->Notify();
|
||||
while (home.twiddle)
|
||||
{
|
||||
failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE;
|
||||
failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
}
|
||||
timeout += (RCInterval(RCInterval::now) - timein);
|
||||
}
|
||||
}
|
||||
timeout += (RCInterval(RCInterval::now) - timein);
|
||||
}
|
||||
|
||||
/* Figure out how well we did */
|
||||
if (debug_mode)
|
||||
{
|
||||
average = timeout.ToMicroseconds()
|
||||
/ (INNER_LOOPS * loop_limit * thread_count);
|
||||
PR_fprintf(
|
||||
debug_out, "Average switch times %d usecs for %d threads\n",
|
||||
if (debug_mode)
|
||||
{
|
||||
average = timeout.ToMicroseconds()
|
||||
/ (INNER_LOOPS * loop_limit * thread_count);
|
||||
PR_fprintf(
|
||||
debug_out, "Average switch times %d usecs for %d threads\n",
|
||||
average, thread_limit);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start reclamation process */
|
||||
link = shared;
|
||||
for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
|
||||
{
|
||||
if (&home == link) break;
|
||||
if (&home == link) {
|
||||
break;
|
||||
}
|
||||
status = ((Shared*)link)->Interrupt();
|
||||
if (PR_SUCCESS != status)
|
||||
if (PR_SUCCESS != status)
|
||||
{
|
||||
failed = PR_TRUE;
|
||||
if (debug_mode)
|
||||
PL_FPrintError(debug_out, "Failed to interrupt");
|
||||
if (debug_mode) {
|
||||
PL_FPrintError(debug_out, "Failed to interrupt");
|
||||
}
|
||||
}
|
||||
link = link->next;
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
|
||||
{
|
||||
link = shared->next;
|
||||
status = shared->Join();
|
||||
if (PR_SUCCESS != status)
|
||||
{
|
||||
if (PR_SUCCESS != status)
|
||||
{
|
||||
failed = PR_TRUE;
|
||||
if (debug_mode)
|
||||
PL_FPrintError(debug_out, "Failed to join");
|
||||
if (debug_mode) {
|
||||
PL_FPrintError(debug_out, "Failed to join");
|
||||
}
|
||||
}
|
||||
if (&home == link) {
|
||||
break;
|
||||
}
|
||||
if (&home == link) break;
|
||||
shared = (Shared*)link;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ private:
|
|||
TestThread::~TestThread() { }
|
||||
|
||||
TestThread::TestThread(RCThread::State state, PRIntn count):
|
||||
RCThread(RCThread::global, state, 0) { mydata = count; }
|
||||
RCThread(RCThread::global, state, 0) {
|
||||
mydata = count;
|
||||
}
|
||||
|
||||
void TestThread::RootFunction()
|
||||
{
|
||||
|
|
@ -46,7 +48,7 @@ public:
|
|||
PRIntn data;
|
||||
};
|
||||
|
||||
Foo1::Foo1()
|
||||
Foo1::Foo1()
|
||||
{
|
||||
data = 0xafaf;
|
||||
thread = new TestThread(RCThread::joinable, 0xafaf);
|
||||
|
|
|
|||
|
|
@ -68,8 +68,9 @@ static void PrintProgress(PRIntn line)
|
|||
|
||||
static void MyAssert(const char *expr, const char *file, PRIntn line)
|
||||
{
|
||||
if (debug > 0)
|
||||
if (debug > 0) {
|
||||
(void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
|
||||
}
|
||||
} /* MyAssert */
|
||||
|
||||
#define MY_ASSERT(_expr) \
|
||||
|
|
@ -86,14 +87,16 @@ int main(PRIntn argc, char *argv[])
|
|||
RCThread *primordial = RCThread::WrapPrimordialThread();
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
{
|
||||
if (PL_OPT_BAD == os) continue;
|
||||
if (PL_OPT_BAD == os) {
|
||||
continue;
|
||||
}
|
||||
switch (opt->option)
|
||||
{
|
||||
case 'd': /* debug mode */
|
||||
debug = PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 'd': /* debug mode */
|
||||
debug = PR_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
PL_DestroyOptState(opt);
|
||||
|
|
@ -103,8 +106,9 @@ int main(PRIntn argc, char *argv[])
|
|||
MyPrivateData extension = MyPrivateData("EXTENSION");
|
||||
MyPrivateData key_string[] = {
|
||||
"Key #0", "Key #1", "Key #2", "Key #3",
|
||||
"Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
|
||||
|
||||
"Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"
|
||||
};
|
||||
|
||||
|
||||
did = should = PR_FALSE;
|
||||
for (keys = 0; keys < 4; ++keys)
|
||||
|
|
@ -133,7 +137,7 @@ int main(PRIntn argc, char *argv[])
|
|||
}
|
||||
PrintProgress(__LINE__);
|
||||
|
||||
/* re-assign the private data, albeit the same content */
|
||||
/* re-assign the private data, albeit the same content */
|
||||
did = PR_FALSE; should = PR_TRUE;
|
||||
for (keys = 0; keys < 4; ++keys)
|
||||
{
|
||||
|
|
@ -190,13 +194,21 @@ int main(PRIntn argc, char *argv[])
|
|||
MY_ASSERT(PR_SUCCESS == rv);
|
||||
}
|
||||
|
||||
if (debug) PR_fprintf(fout, "Creating thread\n");
|
||||
if (debug) {
|
||||
PR_fprintf(fout, "Creating thread\n");
|
||||
}
|
||||
thread = new MyThread();
|
||||
if (debug) PR_fprintf(fout, "Starting thread\n");
|
||||
if (debug) {
|
||||
PR_fprintf(fout, "Starting thread\n");
|
||||
}
|
||||
thread->Start();
|
||||
if (debug) PR_fprintf(fout, "Joining thread\n");
|
||||
if (debug) {
|
||||
PR_fprintf(fout, "Joining thread\n");
|
||||
}
|
||||
(void)thread->Join();
|
||||
if (debug) PR_fprintf(fout, "Joined thread\n");
|
||||
if (debug) {
|
||||
PR_fprintf(fout, "Joined thread\n");
|
||||
}
|
||||
|
||||
failed |= (PR_FAILURE == RCPrimordialThread::Cleanup());
|
||||
|
||||
|
|
@ -237,8 +249,12 @@ MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him)
|
|||
|
||||
void MyPrivateData::Release()
|
||||
{
|
||||
if (should) did = PR_TRUE;
|
||||
else failed = PR_TRUE;
|
||||
if (should) {
|
||||
did = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
failed = PR_TRUE;
|
||||
}
|
||||
} /* MyPrivateData::operator= */
|
||||
|
||||
/*
|
||||
|
|
@ -253,12 +269,13 @@ void MyThread::RootFunction()
|
|||
PRStatus rv;
|
||||
PRUintn keys;
|
||||
const RCThreadPrivateData *pd;
|
||||
|
||||
|
||||
MyPrivateData extension = MyPrivateData("EXTENSION");
|
||||
MyPrivateData key_string[] = {
|
||||
"Key #0", "Key #1", "Key #2", "Key #3",
|
||||
"Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
|
||||
|
||||
"Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"
|
||||
};
|
||||
|
||||
did = should = PR_FALSE;
|
||||
for (keys = 0; keys < 8; ++keys)
|
||||
{
|
||||
|
|
@ -284,7 +301,7 @@ void MyThread::RootFunction()
|
|||
}
|
||||
PrintProgress(__LINE__);
|
||||
#endif
|
||||
|
||||
|
||||
did = PR_FALSE; should = PR_TRUE;
|
||||
for (keys = 0; keys < 4; ++keys)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -18,8 +18,8 @@ PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
|
@ -33,51 +33,57 @@ PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
|
|||
|
||||
PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
if (dir) {
|
||||
rv = _PR_MD_CLOSE_DIR(&dir->md);
|
||||
PR_DELETE(dir);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
PR_DELETE(dir);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_MKDIR(name, mode);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_MKDIR(name, mode);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
rv = _PR_MD_MAKE_DIR(name, mode);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
rv = _PR_MD_MAKE_DIR(name, mode);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_RMDIR(name);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_RMDIR(name);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_UNICODE
|
||||
|
|
@ -85,7 +91,7 @@ PRInt32 rv;
|
|||
* UTF16 Interface
|
||||
*/
|
||||
PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
|
||||
{
|
||||
{
|
||||
PRDirUTF16 *dir;
|
||||
PRStatus sts;
|
||||
|
||||
|
|
@ -100,10 +106,10 @@ PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
|
|||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
|
||||
{
|
||||
{
|
||||
/*
|
||||
* _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in
|
||||
* machine-dependent code
|
||||
|
|
@ -111,20 +117,22 @@ PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags
|
|||
PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags);
|
||||
dir->d.name = name;
|
||||
return name ? &dir->d : NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir)
|
||||
{
|
||||
PRInt32 rv;
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
if (dir) {
|
||||
rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md);
|
||||
PR_DELETE(dir);
|
||||
if (rv < 0)
|
||||
return PR_FAILURE;
|
||||
else
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,8 +63,12 @@ PRFileDesc *_PR_Getfd(void)
|
|||
{
|
||||
do
|
||||
{
|
||||
if (NULL == _pr_fd_cache.head) goto allocate; /* nothing there */
|
||||
if (_pr_fd_cache.count < _pr_fd_cache.limit_low) goto allocate;
|
||||
if (NULL == _pr_fd_cache.head) {
|
||||
goto allocate; /* nothing there */
|
||||
}
|
||||
if (_pr_fd_cache.count < _pr_fd_cache.limit_low) {
|
||||
goto allocate;
|
||||
}
|
||||
|
||||
/* we "should" be able to extract an fd from the cache */
|
||||
PR_Lock(_pr_fd_cache.ml); /* need the lock to do this safely */
|
||||
|
|
@ -104,10 +108,16 @@ allocate:
|
|||
if (NULL != fd)
|
||||
{
|
||||
fd->secret = PR_NEW(PRFilePrivate);
|
||||
if (NULL == fd->secret) PR_DELETE(fd);
|
||||
if (NULL == fd->secret) {
|
||||
PR_DELETE(fd);
|
||||
}
|
||||
}
|
||||
if (NULL != fd) {
|
||||
goto finished;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
if (NULL != fd) goto finished;
|
||||
else return NULL;
|
||||
|
||||
} /* _PR_Getfd */
|
||||
|
||||
|
|
@ -157,10 +167,14 @@ PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high)
|
|||
** turn the caches off, or turn them on. It is not dependent
|
||||
** on the compilation setting of DEBUG.
|
||||
*/
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
if (low > high) {
|
||||
low = high; /* sanity check the params */
|
||||
}
|
||||
|
||||
if (low > high) low = high; /* sanity check the params */
|
||||
|
||||
PR_Lock(_pr_fd_cache.ml);
|
||||
_pr_fd_cache.limit_high = high;
|
||||
_pr_fd_cache.limit_low = low;
|
||||
|
|
@ -179,7 +193,7 @@ void _PR_InitFdCache(void)
|
|||
const char *low = PR_GetEnv("NSPR_FD_CACHE_SIZE_LOW");
|
||||
const char *high = PR_GetEnv("NSPR_FD_CACHE_SIZE_HIGH");
|
||||
|
||||
/*
|
||||
/*
|
||||
** _low is allowed to be zero, _high is not.
|
||||
** If _high is zero, we're not doing the caching.
|
||||
*/
|
||||
|
|
@ -191,19 +205,27 @@ void _PR_InitFdCache(void)
|
|||
_pr_fd_cache.limit_high = 0;
|
||||
#endif /* defined(DEBUG) */
|
||||
|
||||
if (NULL != low) _pr_fd_cache.limit_low = atoi(low);
|
||||
if (NULL != high) _pr_fd_cache.limit_high = atoi(high);
|
||||
if (NULL != low) {
|
||||
_pr_fd_cache.limit_low = atoi(low);
|
||||
}
|
||||
if (NULL != high) {
|
||||
_pr_fd_cache.limit_high = atoi(high);
|
||||
}
|
||||
|
||||
if (_pr_fd_cache.limit_low < 0)
|
||||
if (_pr_fd_cache.limit_low < 0) {
|
||||
_pr_fd_cache.limit_low = 0;
|
||||
if (_pr_fd_cache.limit_low > FD_SETSIZE)
|
||||
}
|
||||
if (_pr_fd_cache.limit_low > FD_SETSIZE) {
|
||||
_pr_fd_cache.limit_low = FD_SETSIZE;
|
||||
}
|
||||
|
||||
if (_pr_fd_cache.limit_high > FD_SETSIZE)
|
||||
if (_pr_fd_cache.limit_high > FD_SETSIZE) {
|
||||
_pr_fd_cache.limit_high = FD_SETSIZE;
|
||||
}
|
||||
|
||||
if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low)
|
||||
if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low) {
|
||||
_pr_fd_cache.limit_high = _pr_fd_cache.limit_low;
|
||||
}
|
||||
|
||||
_pr_fd_cache.ml = PR_NewLock();
|
||||
PR_ASSERT(NULL != _pr_fd_cache.ml);
|
||||
|
|
|
|||
|
|
@ -28,21 +28,22 @@ static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount)
|
|||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
rv = -1;
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
rv = -1;
|
||||
}
|
||||
if (_PR_IO_PENDING(me)) {
|
||||
PR_SetError(PR_IO_PENDING_ERROR, 0);
|
||||
rv = -1;
|
||||
rv = -1;
|
||||
}
|
||||
if (rv == -1) {
|
||||
return rv;
|
||||
}
|
||||
if (rv == -1)
|
||||
return rv;
|
||||
|
||||
rv = _PR_MD_READ(fd, buf, amount);
|
||||
if (rv < 0) {
|
||||
PR_ASSERT(rv == -1);
|
||||
}
|
||||
rv = _PR_MD_READ(fd, buf, amount);
|
||||
if (rv < 0) {
|
||||
PR_ASSERT(rv == -1);
|
||||
}
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -56,14 +57,15 @@ static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 am
|
|||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
rv = -1;
|
||||
rv = -1;
|
||||
}
|
||||
if (_PR_IO_PENDING(me)) {
|
||||
PR_SetError(PR_IO_PENDING_ERROR, 0);
|
||||
rv = -1;
|
||||
rv = -1;
|
||||
}
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
|
||||
count = 0;
|
||||
#if !defined(_PR_HAVE_O_APPEND) /* Bugzilla: 4090, 276330 */
|
||||
|
|
@ -74,17 +76,17 @@ static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 am
|
|||
} /* if (fd->secret->appendMode...) */
|
||||
#endif /* _PR_HAVE_O_APPEND */
|
||||
while (amount > 0) {
|
||||
temp = _PR_MD_WRITE(fd, buf, amount);
|
||||
if (temp < 0) {
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
count += temp;
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
buf = (const void*) ((const char*)buf + temp);
|
||||
amount -= temp;
|
||||
temp = _PR_MD_WRITE(fd, buf, amount);
|
||||
if (temp < 0) {
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
count += temp;
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
buf = (const void*) ((const char*)buf + temp);
|
||||
amount -= temp;
|
||||
}
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
|
||||
return count;
|
||||
|
|
@ -112,8 +114,9 @@ static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd)
|
|||
|
||||
cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
|
||||
|
||||
if (cur >= 0)
|
||||
end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
|
||||
if (cur >= 0) {
|
||||
end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
|
||||
}
|
||||
|
||||
if ((cur < 0) || (end < 0)) {
|
||||
return -1;
|
||||
|
|
@ -133,10 +136,13 @@ static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
|
|||
LL_I2L(minus_one, -1);
|
||||
cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
|
||||
|
||||
if (LL_GE_ZERO(cur))
|
||||
end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
|
||||
if (LL_GE_ZERO(cur)) {
|
||||
end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
|
||||
}
|
||||
|
||||
if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
|
||||
if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) {
|
||||
return minus_one;
|
||||
}
|
||||
|
||||
LL_SUB(result, end, cur);
|
||||
(void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
|
||||
|
|
@ -146,42 +152,47 @@ static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
|
|||
|
||||
static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = _PR_MD_PIPEAVAILABLE(fd);
|
||||
return rv;
|
||||
PRInt32 rv;
|
||||
rv = _PR_MD_PIPEAVAILABLE(fd);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
|
||||
{
|
||||
PRInt64 rv;
|
||||
LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_GETOPENFILEINFO(fd, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info)
|
||||
{
|
||||
/* $$$$ NOT YET IMPLEMENTED */
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_GETOPENFILEINFO64(fd, info);
|
||||
if (rv < 0) return PR_FAILURE;
|
||||
else return PR_SUCCESS;
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
|
||||
|
|
@ -189,7 +200,7 @@ static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
|
|||
PRInt32 result;
|
||||
result = _PR_MD_FSYNC(fd);
|
||||
if (result < 0) {
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -197,7 +208,7 @@ static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
|
|||
static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
|
||||
{
|
||||
if (!fd || !fd->secret
|
||||
|| (fd->secret->state != _PR_FILEDESC_OPEN
|
||||
|| (fd->secret->state != _PR_FILEDESC_OPEN
|
||||
&& fd->secret->state != _PR_FILEDESC_CLOSED)) {
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
|
|
@ -232,30 +243,30 @@ static PRIOMethods _pr_fileMethods = {
|
|||
FileSeek64,
|
||||
FileGetInfo,
|
||||
FileGetInfo64,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
FilePoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
FilePoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt
|
||||
};
|
||||
|
||||
|
|
@ -276,30 +287,30 @@ static PRIOMethods _pr_pipeMethods = {
|
|||
(PRSeek64FN)_PR_InvalidInt64,
|
||||
(PRFileInfoFN)_PR_InvalidStatus,
|
||||
(PRFileInfo64FN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
FilePoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
FilePoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt
|
||||
};
|
||||
|
||||
|
|
@ -316,7 +327,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
|
|||
PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
/* Map pr open flags and mode to os specific flags */
|
||||
|
||||
|
|
@ -344,7 +357,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
|
|||
PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
/* Map pr open flags and mode to os specific flags */
|
||||
|
||||
|
|
@ -369,8 +384,8 @@ PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
|
|||
struct rlimit rlim;
|
||||
|
||||
if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
/* XXX need to call PR_SetError() */
|
||||
return -1;
|
||||
/* XXX need to call PR_SetError() */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rlim.rlim_max;
|
||||
|
|
@ -388,9 +403,6 @@ PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
|
|||
ULONG ulCurMaxFH = 0;
|
||||
DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH);
|
||||
return ulCurMaxFH;
|
||||
#elif defined(XP_BEOS)
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
#else
|
||||
write me;
|
||||
#endif
|
||||
|
|
@ -402,19 +414,23 @@ PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
|
|||
struct rlimit rlim;
|
||||
PRInt32 tableMax = PR_GetSysfdTableMax();
|
||||
|
||||
if (tableMax < 0)
|
||||
if (tableMax < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tableMax > FD_SETSIZE)
|
||||
if (tableMax > FD_SETSIZE) {
|
||||
tableMax = FD_SETSIZE;
|
||||
}
|
||||
|
||||
rlim.rlim_max = tableMax;
|
||||
|
||||
/* Grow as much as we can; even if too big */
|
||||
if ( rlim.rlim_max < table_size )
|
||||
if ( rlim.rlim_max < table_size ) {
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
else
|
||||
}
|
||||
else {
|
||||
rlim.rlim_cur = table_size;
|
||||
}
|
||||
|
||||
if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
/* XXX need to call PR_SetError() */
|
||||
|
|
@ -425,16 +441,18 @@ PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
|
|||
#elif defined(XP_OS2)
|
||||
PRInt32 tableMax = PR_GetSysfdTableMax();
|
||||
if (table_size > tableMax) {
|
||||
APIRET rc = NO_ERROR;
|
||||
rc = DosSetMaxFH(table_size);
|
||||
if (rc == NO_ERROR)
|
||||
return table_size;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
APIRET rc = NO_ERROR;
|
||||
rc = DosSetMaxFH(table_size);
|
||||
if (rc == NO_ERROR) {
|
||||
return table_size;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return tableMax;
|
||||
#elif defined(AIX) || defined(QNX) \
|
||||
|| defined(WIN32) || defined(WIN16) || defined(XP_BEOS)
|
||||
|| defined(WIN32) || defined(WIN16)
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
#else
|
||||
|
|
@ -444,31 +462,35 @@ PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
|
|||
|
||||
PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_DELETE(name);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_DELETE(name);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_GETFILEINFO(fn, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_GETFILEINFO(fn, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
rv = _PR_MD_GETFILEINFO64(fn, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
|
|
@ -479,34 +501,38 @@ PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
|
|||
|
||||
PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_RENAME(from, to);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_RENAME(from, to);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_ACCESS(name, how);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else
|
||||
return PR_SUCCESS;
|
||||
rv = _PR_MD_ACCESS(name, how);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
} else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Import an existing OS file to NSPR
|
||||
** Import an existing OS file to NSPR
|
||||
*/
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd)
|
||||
{
|
||||
PRFileDesc *fd = NULL;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
|
||||
if( !fd ) {
|
||||
|
|
@ -519,13 +545,15 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd)
|
|||
}
|
||||
|
||||
/*
|
||||
** Import an existing OS pipe to NSPR
|
||||
** Import an existing OS pipe to NSPR
|
||||
*/
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd)
|
||||
{
|
||||
PRFileDesc *fd = NULL;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods);
|
||||
if( !fd ) {
|
||||
|
|
@ -552,7 +580,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd)
|
|||
* nspr 1.0. Therefore, it still uses the nspr 1.0 error-reporting
|
||||
* mechanism -- returns a PRInt32, which is the error code when the call
|
||||
* fails.
|
||||
*
|
||||
*
|
||||
* If we need this function in nspr 2.0, it should be changed to
|
||||
* return PRStatus, as follows:
|
||||
*
|
||||
|
|
@ -574,7 +602,7 @@ PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
|
|||
PRInt32 rv;
|
||||
|
||||
rv = _PR_MD_STAT(name, buf);
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif /* !defined(WIN16) */
|
||||
|
|
@ -594,8 +622,9 @@ PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
|
|||
#endif
|
||||
|
||||
PR_Lock(_pr_flock_lock);
|
||||
while (fd->secret->lockCount == -1)
|
||||
while (fd->secret->lockCount == -1) {
|
||||
PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
|
||||
}
|
||||
if (fd->secret->lockCount == 0) {
|
||||
fd->secret->lockCount = -1;
|
||||
PR_Unlock(_pr_flock_lock);
|
||||
|
|
@ -607,7 +636,7 @@ PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
|
|||
fd->secret->lockCount++;
|
||||
}
|
||||
PR_Unlock(_pr_flock_lock);
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -628,8 +657,9 @@ PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
|
|||
if (fd->secret->lockCount == 0) {
|
||||
status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
|
||||
PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0);
|
||||
if (status == PR_SUCCESS)
|
||||
if (status == PR_SUCCESS) {
|
||||
fd->secret->lockCount = 1;
|
||||
}
|
||||
} else {
|
||||
fd->secret->lockCount++;
|
||||
}
|
||||
|
|
@ -645,8 +675,9 @@ PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
|
|||
PR_Lock(_pr_flock_lock);
|
||||
if (fd->secret->lockCount == 1) {
|
||||
rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
|
||||
if (rv == PR_SUCCESS)
|
||||
if (rv == PR_SUCCESS) {
|
||||
fd->secret->lockCount = 0;
|
||||
}
|
||||
} else {
|
||||
fd->secret->lockCount--;
|
||||
}
|
||||
|
|
@ -664,7 +695,9 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
HANDLE readEnd, writeEnd;
|
||||
SECURITY_ATTRIBUTES pipeAttributes;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
|
||||
pipeAttributes.nLength = sizeof(pipeAttributes);
|
||||
|
|
@ -692,14 +725,16 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
(*readPipe)->secret->inheritable = _PR_TRI_TRUE;
|
||||
(*writePipe)->secret->inheritable = _PR_TRI_TRUE;
|
||||
return PR_SUCCESS;
|
||||
#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
#elif defined(XP_UNIX) || defined(XP_OS2)
|
||||
#ifdef XP_OS2
|
||||
HFILE pipefd[2];
|
||||
#else
|
||||
int pipefd[2];
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
#ifdef XP_OS2
|
||||
if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
|
||||
|
|
@ -722,13 +757,9 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
close(pipefd[1]);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
|
||||
_PR_MD_MAKE_NONBLOCK(*readPipe);
|
||||
#endif
|
||||
_PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
|
||||
#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
|
||||
_PR_MD_MAKE_NONBLOCK(*writePipe);
|
||||
#endif
|
||||
_PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
|
||||
return PR_SUCCESS;
|
||||
#else
|
||||
|
|
@ -741,15 +772,17 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
/* ================ UTF16 Interfaces ================================ */
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
|
||||
const PRUnichar *name, PRIntn flags, PRIntn mode)
|
||||
{
|
||||
{
|
||||
PROsfd osfd;
|
||||
PRFileDesc *fd = 0;
|
||||
#if !defined(_PR_HAVE_O_APPEND)
|
||||
PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
/* Map pr open flags and mode to os specific flags */
|
||||
osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
|
||||
if (osfd != -1) {
|
||||
|
|
@ -765,12 +798,14 @@ PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
|
|||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
|
||||
if (rv < 0) {
|
||||
return PR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ void _PR_InitIO(void)
|
|||
|
||||
#ifdef WIN32
|
||||
_pr_stdin = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_INPUT_HANDLE),
|
||||
methods);
|
||||
methods);
|
||||
_pr_stdout = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
methods);
|
||||
methods);
|
||||
_pr_stderr = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_ERROR_HANDLE),
|
||||
methods);
|
||||
methods);
|
||||
#ifdef WINNT
|
||||
_pr_stdin->secret->md.sync_file_io = PR_TRUE;
|
||||
_pr_stdout->secret->md.sync_file_io = PR_TRUE;
|
||||
|
|
@ -88,8 +88,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
|
|||
PRFileDesc *result = NULL;
|
||||
PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError);
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
switch (osfd)
|
||||
{
|
||||
case PR_StandardInput: result = _pr_stdin; break;
|
||||
|
|
@ -107,25 +109,25 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
|
|||
PRFileDesc *fd;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
/*
|
||||
* Assert that the file descriptor is small enough to fit in the
|
||||
* fd_set passed to select
|
||||
*/
|
||||
PR_ASSERT(osfd < FD_SETSIZE);
|
||||
/*
|
||||
* Assert that the file descriptor is small enough to fit in the
|
||||
* fd_set passed to select
|
||||
*/
|
||||
PR_ASSERT(osfd < FD_SETSIZE);
|
||||
#endif
|
||||
fd = _PR_Getfd();
|
||||
if (fd) {
|
||||
/* Initialize the members of PRFileDesc and PRFilePrivate */
|
||||
fd->methods = methods;
|
||||
fd->secret->state = _PR_FILEDESC_OPEN;
|
||||
fd->secret->md.osfd = osfd;
|
||||
fd->secret->md.osfd = osfd;
|
||||
#if defined(_WIN64)
|
||||
fd->secret->alreadyConnected = PR_FALSE;
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
#endif
|
||||
_PR_MD_INIT_FILEDESC(fd);
|
||||
} else {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
|
@ -144,62 +146,62 @@ PRLock *_fd_waiting_for_overlapped_done_lock = NULL;
|
|||
|
||||
void CheckOverlappedPendingSocketsAreDone()
|
||||
{
|
||||
if (!_fd_waiting_for_overlapped_done_lock ||
|
||||
!_fd_waiting_for_overlapped_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
PR_Lock(_fd_waiting_for_overlapped_done_lock);
|
||||
|
||||
PRFileDescList *cur = _fd_waiting_for_overlapped_done;
|
||||
PRFileDescList *previous = NULL;
|
||||
while (cur) {
|
||||
PR_ASSERT(cur->fd->secret->overlappedActive);
|
||||
PRFileDesc *fd = cur->fd;
|
||||
DWORD rvSent;
|
||||
if (GetOverlappedResult((HANDLE)fd->secret->md.osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) {
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("CheckOverlappedPendingSocketsAreDone GetOverlappedResult succeeded\n"));
|
||||
} else {
|
||||
DWORD err = WSAGetLastError();
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("CheckOverlappedPendingSocketsAreDone GetOverlappedResult failed %d\n", err));
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
}
|
||||
if (!_fd_waiting_for_overlapped_done_lock ||
|
||||
!_fd_waiting_for_overlapped_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fd->secret->overlappedActive) {
|
||||
PR_Lock(_fd_waiting_for_overlapped_done_lock);
|
||||
|
||||
_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd);
|
||||
fd->secret->state = _PR_FILEDESC_CLOSED;
|
||||
PRFileDescList *cur = _fd_waiting_for_overlapped_done;
|
||||
PRFileDescList *previous = NULL;
|
||||
while (cur) {
|
||||
PR_ASSERT(cur->fd->secret->overlappedActive);
|
||||
PRFileDesc *fd = cur->fd;
|
||||
DWORD rvSent;
|
||||
if (GetOverlappedResult((HANDLE)fd->secret->md.osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) {
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("CheckOverlappedPendingSocketsAreDone GetOverlappedResult succeeded\n"));
|
||||
} else {
|
||||
DWORD err = WSAGetLastError();
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("CheckOverlappedPendingSocketsAreDone GetOverlappedResult failed %d\n", err));
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fd->secret->overlappedActive) {
|
||||
|
||||
_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd);
|
||||
fd->secret->state = _PR_FILEDESC_CLOSED;
|
||||
#ifdef _PR_HAVE_PEEK_BUFFER
|
||||
if (fd->secret->peekBuffer) {
|
||||
PR_ASSERT(fd->secret->peekBufSize > 0);
|
||||
PR_DELETE(fd->secret->peekBuffer);
|
||||
fd->secret->peekBufSize = 0;
|
||||
fd->secret->peekBytes = 0;
|
||||
}
|
||||
if (fd->secret->peekBuffer) {
|
||||
PR_ASSERT(fd->secret->peekBufSize > 0);
|
||||
PR_DELETE(fd->secret->peekBuffer);
|
||||
fd->secret->peekBufSize = 0;
|
||||
fd->secret->peekBytes = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_FreeFileDesc(fd);
|
||||
PR_FreeFileDesc(fd);
|
||||
|
||||
if (previous) {
|
||||
previous->next = cur->next;
|
||||
} else {
|
||||
_fd_waiting_for_overlapped_done = cur->next;
|
||||
}
|
||||
PRFileDescList *del = cur;
|
||||
cur = cur->next;
|
||||
PR_Free(del);
|
||||
} else {
|
||||
previous = cur;
|
||||
cur = cur->next;
|
||||
if (previous) {
|
||||
previous->next = cur->next;
|
||||
} else {
|
||||
_fd_waiting_for_overlapped_done = cur->next;
|
||||
}
|
||||
PRFileDescList *del = cur;
|
||||
cur = cur->next;
|
||||
PR_Free(del);
|
||||
} else {
|
||||
previous = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(_fd_waiting_for_overlapped_done_lock);
|
||||
PR_Unlock(_fd_waiting_for_overlapped_done_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -209,11 +211,11 @@ void CheckOverlappedPendingSocketsAreDone()
|
|||
PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
||||
{
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
// For each iteration check if TFO overlapped IOs are down.
|
||||
CheckOverlappedPendingSocketsAreDone();
|
||||
// For each iteration check if TFO overlapped IOs are down.
|
||||
CheckOverlappedPendingSocketsAreDone();
|
||||
#endif
|
||||
|
||||
return(_PR_MD_PR_POLL(pds, npds, timeout));
|
||||
return(_PR_MD_PR_POLL(pds, npds, timeout));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -223,7 +225,7 @@ PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
|
|||
PRFileDesc *fd,
|
||||
PRBool inheritable)
|
||||
{
|
||||
#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2)
|
||||
/*
|
||||
* Only a non-layered, NSPR file descriptor can be inherited
|
||||
* by a child process.
|
||||
|
|
|
|||
|
|
@ -22,26 +22,26 @@ PRIOMethods _pr_faulty_methods = {
|
|||
(PRSeek64FN)_PR_InvalidInt64,
|
||||
(PRFileInfoFN)_PR_InvalidStatus,
|
||||
(PRFileInfo64FN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
(PRPollFN)_PR_InvalidInt16,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
|
|
@ -106,159 +106,159 @@ PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc *fd)
|
|||
|
||||
PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
|
||||
{
|
||||
return((fd->methods->read)(fd,buf,amount));
|
||||
return((fd->methods->read)(fd,buf,amount));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
|
||||
{
|
||||
return((fd->methods->write)(fd,buf,amount));
|
||||
return((fd->methods->write)(fd,buf,amount));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
|
||||
{
|
||||
return((fd->methods->seek)(fd, offset, whence));
|
||||
return((fd->methods->seek)(fd, offset, whence));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
|
||||
{
|
||||
return((fd->methods->seek64)(fd, offset, whence));
|
||||
return((fd->methods->seek64)(fd, offset, whence));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc *fd)
|
||||
{
|
||||
return((fd->methods->available)(fd));
|
||||
return((fd->methods->available)(fd));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc *fd)
|
||||
{
|
||||
return((fd->methods->available64)(fd));
|
||||
return((fd->methods->available64)(fd));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info)
|
||||
{
|
||||
return((fd->methods->fileInfo)(fd, info));
|
||||
return((fd->methods->fileInfo)(fd, info));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
|
||||
{
|
||||
return((fd->methods->fileInfo64)(fd, info));
|
||||
return((fd->methods->fileInfo64)(fd, info));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc *fd)
|
||||
{
|
||||
return((fd->methods->fsync)(fd));
|
||||
return((fd->methods->fsync)(fd));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Connect(
|
||||
PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->connect)(fd,addr,timeout));
|
||||
return((fd->methods->connect)(fd,addr,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_ConnectContinue(
|
||||
PRFileDesc *fd, PRInt16 out_flags)
|
||||
{
|
||||
return((fd->methods->connectcontinue)(fd,out_flags));
|
||||
return((fd->methods->connectcontinue)(fd,out_flags));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr,
|
||||
PRIntervalTime timeout)
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->accept)(fd,addr,timeout));
|
||||
return((fd->methods->accept)(fd,addr,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr)
|
||||
{
|
||||
return((fd->methods->bind)(fd,addr));
|
||||
return((fd->methods->bind)(fd,addr));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how)
|
||||
{
|
||||
return((fd->methods->shutdown)(fd,how));
|
||||
return((fd->methods->shutdown)(fd,how));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog)
|
||||
{
|
||||
return((fd->methods->listen)(fd,backlog));
|
||||
return((fd->methods->listen)(fd,backlog));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||
PRIntn flags, PRIntervalTime timeout)
|
||||
PRIntn flags, PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->recv)(fd,buf,amount,flags,timeout));
|
||||
return((fd->methods->recv)(fd,buf,amount,flags,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
|
||||
PRIntn flags, PRIntervalTime timeout)
|
||||
PRIntn flags, PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->send)(fd,buf,amount,flags,timeout));
|
||||
return((fd->methods->send)(fd,buf,amount,flags,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov,
|
||||
PRInt32 iov_size, PRIntervalTime timeout)
|
||||
PRInt32 iov_size, PRIntervalTime timeout)
|
||||
{
|
||||
if (iov_size > PR_MAX_IOVECTOR_SIZE)
|
||||
{
|
||||
PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
return((fd->methods->writev)(fd,iov,iov_size,timeout));
|
||||
return((fd->methods->writev)(fd,iov,iov_size,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
|
||||
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout));
|
||||
return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_SendTo(
|
||||
PRFileDesc *fd, const void *buf, PRInt32 amount,
|
||||
PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout));
|
||||
return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_TransmitFile(
|
||||
PRFileDesc *sd, PRFileDesc *fd, const void *hdr, PRInt32 hlen,
|
||||
PRTransmitFileFlags flags, PRIntervalTime timeout)
|
||||
{
|
||||
return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout));
|
||||
return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_AcceptRead(
|
||||
PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
|
||||
void *buf, PRInt32 amount, PRIntervalTime timeout)
|
||||
{
|
||||
return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout));
|
||||
return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
|
||||
{
|
||||
return((fd->methods->getsockname)(fd,addr));
|
||||
return((fd->methods->getsockname)(fd,addr));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
|
||||
{
|
||||
return((fd->methods->getpeername)(fd,addr));
|
||||
return((fd->methods->getpeername)(fd,addr));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
|
||||
PRFileDesc *fd, PRSocketOptionData *data)
|
||||
{
|
||||
return((fd->methods->getsocketoption)(fd, data));
|
||||
return((fd->methods->getsocketoption)(fd, data));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
|
||||
PRFileDesc *fd, const PRSocketOptionData *data)
|
||||
{
|
||||
return((fd->methods->setsocketoption)(fd, data));
|
||||
return((fd->methods->setsocketoption)(fd, data));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_SendFile(
|
||||
PRFileDesc *sd, PRSendFileData *sfd,
|
||||
PRTransmitFileFlags flags, PRIntervalTime timeout)
|
||||
PRFileDesc *sd, PRSendFileData *sfd,
|
||||
PRTransmitFileFlags flags, PRIntervalTime timeout)
|
||||
{
|
||||
return((sd->methods->sendfile)(sd,sfd,flags,timeout));
|
||||
return((sd->methods->sendfile)(sd,sfd,flags,timeout));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
|
||||
|
|
@ -274,7 +274,9 @@ PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
|
|||
** operation - it waits indefinitely.
|
||||
*/
|
||||
accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (NULL == accepted) return rv;
|
||||
if (NULL == accepted) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = PR_Recv(accepted, buf, amount, 0, timeout);
|
||||
if (rv >= 0)
|
||||
|
|
@ -299,7 +301,7 @@ PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
|
|||
* they are sent before and after the file, respectively.
|
||||
*
|
||||
* PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
|
||||
*
|
||||
*
|
||||
* return number of bytes sent or -1 on error
|
||||
*
|
||||
*/
|
||||
|
|
@ -310,7 +312,7 @@ PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
|
|||
* An implementation based on memory-mapped files
|
||||
*/
|
||||
|
||||
#define SENDFILE_MMAP_CHUNK (256 * 1024)
|
||||
#define SENDFILE_MMAP_CHUNK (256 * 1024)
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
||||
PRFileDesc *sd, PRSendFileData *sfd,
|
||||
|
|
@ -333,7 +335,7 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
goto done;
|
||||
}
|
||||
if (sfd->file_nbytes &&
|
||||
(info.size < (sfd->file_offset + sfd->file_nbytes))) {
|
||||
(info.size < (sfd->file_offset + sfd->file_nbytes))) {
|
||||
/*
|
||||
* there are fewer bytes in file to send than specified
|
||||
*/
|
||||
|
|
@ -341,10 +343,12 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
count = -1;
|
||||
goto done;
|
||||
}
|
||||
if (sfd->file_nbytes)
|
||||
if (sfd->file_nbytes) {
|
||||
file_bytes = sfd->file_nbytes;
|
||||
else
|
||||
}
|
||||
else {
|
||||
file_bytes = info.size - sfd->file_offset;
|
||||
}
|
||||
|
||||
alignment = PR_GetMemMapAlignment();
|
||||
|
||||
|
|
@ -400,8 +404,9 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
index++;
|
||||
}
|
||||
rv = PR_Writev(sd, iov, index, timeout);
|
||||
if (len)
|
||||
if (len) {
|
||||
PR_MemUnmap(addr, mmap_len);
|
||||
}
|
||||
if (rv < 0) {
|
||||
count = -1;
|
||||
goto done;
|
||||
|
|
@ -411,8 +416,9 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
|
||||
file_bytes -= len;
|
||||
count += rv;
|
||||
if (!file_bytes) /* header, file and trailer are sent */
|
||||
if (!file_bytes) { /* header, file and trailer are sent */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* send remaining bytes of the file, if any
|
||||
|
|
@ -449,14 +455,17 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
if (rv >= 0) {
|
||||
PR_ASSERT(rv == sfd->tlen);
|
||||
count += rv;
|
||||
} else
|
||||
} else {
|
||||
count = -1;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (mapHandle)
|
||||
if (mapHandle) {
|
||||
PR_CloseFileMap(mapHandle);
|
||||
if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
|
||||
}
|
||||
if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) {
|
||||
PR_Close(sd);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
@ -584,10 +593,12 @@ PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
|
|||
rv = count;
|
||||
|
||||
done:
|
||||
if (buf)
|
||||
if (buf) {
|
||||
PR_DELETE(buf);
|
||||
if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
|
||||
}
|
||||
if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) {
|
||||
PR_Close(sd);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,117 +16,117 @@ static PRIOMethods ipv6_to_v4_tcpMethods;
|
|||
static PRIOMethods ipv6_to_v4_udpMethods;
|
||||
static PRDescIdentity _pr_ipv6_to_ipv4_id;
|
||||
extern PRBool IsValidNetAddr(const PRNetAddr *addr);
|
||||
extern PRIPv6Addr _pr_in6addr_any;
|
||||
extern PRIPv6Addr _pr_in6addr_loopback;
|
||||
extern const PRIPv6Addr _pr_in6addr_any;
|
||||
extern const PRIPv6Addr _pr_in6addr_loopback;
|
||||
|
||||
/*
|
||||
* convert an IPv4-mapped IPv6 addr to an IPv4 addr
|
||||
*/
|
||||
static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr,
|
||||
PRNetAddr *dst_v4addr)
|
||||
PRNetAddr *dst_v4addr)
|
||||
{
|
||||
const PRUint8 *srcp;
|
||||
const PRUint8 *srcp;
|
||||
|
||||
PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
|
||||
PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
|
||||
|
||||
if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
|
||||
srcp = src_v6addr->ipv6.ip.pr_s6_addr;
|
||||
memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
|
||||
if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
|
||||
srcp = src_v6addr->ipv6.ip.pr_s6_addr;
|
||||
memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
|
||||
} else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) {
|
||||
dst_v4addr->inet.ip = htonl(INADDR_ANY);
|
||||
} else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) {
|
||||
dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK);
|
||||
}
|
||||
dst_v4addr->inet.family = PR_AF_INET;
|
||||
dst_v4addr->inet.port = src_v6addr->ipv6.port;
|
||||
dst_v4addr->inet.family = PR_AF_INET;
|
||||
dst_v4addr->inet.port = src_v6addr->ipv6.port;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert an IPv4 addr to an IPv4-mapped IPv6 addr
|
||||
*/
|
||||
static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr,
|
||||
PRNetAddr *dst_v6addr)
|
||||
PRNetAddr *dst_v6addr)
|
||||
{
|
||||
PRUint8 *dstp;
|
||||
PRUint8 *dstp;
|
||||
|
||||
PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
|
||||
dst_v6addr->ipv6.family = PR_AF_INET6;
|
||||
dst_v6addr->ipv6.port = src_v4addr->inet.port;
|
||||
PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
|
||||
dst_v6addr->ipv6.family = PR_AF_INET6;
|
||||
dst_v6addr->ipv6.port = src_v4addr->inet.port;
|
||||
|
||||
if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
|
||||
dst_v6addr->ipv6.ip = _pr_in6addr_any;
|
||||
} else {
|
||||
dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
|
||||
memset(dstp, 0, 10);
|
||||
memset(dstp + 10, 0xff, 2);
|
||||
memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
|
||||
}
|
||||
if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
|
||||
dst_v6addr->ipv6.ip = _pr_in6addr_any;
|
||||
} else {
|
||||
dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
|
||||
memset(dstp, 0, 10);
|
||||
memset(dstp + 10, 0xff, 2);
|
||||
memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd,
|
||||
const PRNetAddr *addr)
|
||||
const PRNetAddr *addr)
|
||||
{
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
PRFileDesc *lo = fd->lower;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
PRFileDesc *lo = fd->lower;
|
||||
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrAny)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrAny)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return((lo->methods->bind)(lo,tmp_addrp));
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return((lo->methods->bind)(lo,tmp_addrp));
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect(
|
||||
PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
|
||||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo(
|
||||
PRFileDesc *fd, const void *buf, PRInt32 amount,
|
||||
PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
const PRNetAddr *tmp_addrp;
|
||||
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
if (PR_AF_INET6 != addr->raw.family) {
|
||||
PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
|
||||
PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
|
||||
_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
|
||||
tmp_addrp = &tmp_ipv4addr;
|
||||
} else {
|
||||
PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return (fd->lower->methods->sendto)(
|
||||
fd->lower, buf, amount, flags, tmp_addrp, timeout);
|
||||
fd->lower, buf, amount, flags, tmp_addrp, timeout);
|
||||
}
|
||||
|
||||
static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
|
||||
|
|
@ -135,7 +135,7 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
|
|||
PRStatus rv;
|
||||
PRFileDesc *newfd;
|
||||
PRFileDesc *newstack;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRNetAddr *addrlower = NULL;
|
||||
|
||||
PR_ASSERT(fd != NULL);
|
||||
|
|
@ -149,16 +149,18 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
|
|||
}
|
||||
*newstack = *fd; /* make a copy of the accepting layer */
|
||||
|
||||
if (addr)
|
||||
if (addr) {
|
||||
addrlower = &tmp_ipv4addr;
|
||||
}
|
||||
newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout);
|
||||
if (NULL == newfd)
|
||||
{
|
||||
PR_DELETE(newstack);
|
||||
return NULL;
|
||||
}
|
||||
if (addr)
|
||||
if (addr) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr);
|
||||
}
|
||||
|
||||
rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
|
||||
PR_ASSERT(PR_SUCCESS == rv);
|
||||
|
|
@ -166,12 +168,12 @@ static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
|
|||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
|
||||
PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
|
||||
PRIntervalTime timeout)
|
||||
PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 nbytes;
|
||||
PRStatus rv;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRFileDesc *newstack;
|
||||
|
||||
PR_ASSERT(sd != NULL);
|
||||
|
|
@ -186,14 +188,14 @@ static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
|
|||
*newstack = *sd; /* make a copy of the accepting layer */
|
||||
|
||||
nbytes = sd->lower->methods->acceptread(
|
||||
sd->lower, nd, ipv6_raddr, buf, amount, timeout);
|
||||
sd->lower, nd, ipv6_raddr, buf, amount, timeout);
|
||||
if (-1 == nbytes)
|
||||
{
|
||||
PR_DELETE(newstack);
|
||||
return nbytes;
|
||||
}
|
||||
tmp_ipv4addr = **ipv6_raddr; /* copy */
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
|
||||
tmp_ipv4addr = **ipv6_raddr; /* copy */
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
|
||||
|
||||
/* this PR_PushIOLayer call cannot fail */
|
||||
rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
|
||||
|
|
@ -202,47 +204,47 @@ static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
|
|||
}
|
||||
|
||||
static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd,
|
||||
PRNetAddr *ipv6addr)
|
||||
PRNetAddr *ipv6addr)
|
||||
{
|
||||
PRStatus result;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRStatus result;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
|
||||
result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
|
||||
if (PR_SUCCESS == result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
|
||||
if (PR_SUCCESS == result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd,
|
||||
PRNetAddr *ipv6addr)
|
||||
PRNetAddr *ipv6addr)
|
||||
{
|
||||
PRStatus result;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRStatus result;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
|
||||
result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr);
|
||||
if (PR_SUCCESS == result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr);
|
||||
if (PR_SUCCESS == result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf,
|
||||
PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
|
||||
PRIntervalTime timeout)
|
||||
PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRInt32 result;
|
||||
PRNetAddr tmp_ipv4addr;
|
||||
PRInt32 result;
|
||||
|
||||
result = (fd->lower->methods->recvfrom)(
|
||||
fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
|
||||
if (-1 != result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
|
||||
if (-1 != result) {
|
||||
_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
|
||||
PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(_PR_INET6_PROBE)
|
||||
|
|
@ -261,13 +263,15 @@ static PRBool
|
|||
_pr_probe_ipv6_presence(void)
|
||||
{
|
||||
#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
|
||||
if (_pr_find_getipnodebyname() != PR_SUCCESS)
|
||||
if (_pr_find_getipnodebyname() != PR_SUCCESS) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO)
|
||||
if (_pr_find_getaddrinfo() != PR_SUCCESS)
|
||||
if (_pr_find_getaddrinfo() != PR_SUCCESS) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return _pr_test_ipv6_socket();
|
||||
|
|
@ -282,83 +286,87 @@ static PRStatus PR_CALLBACK _pr_init_ipv6(void)
|
|||
|
||||
#if defined(_PR_INET6_PROBE)
|
||||
ipv6_is_present = _pr_probe_ipv6_presence();
|
||||
if (ipv6_is_present)
|
||||
if (ipv6_is_present) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
_pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
|
||||
PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);
|
||||
|
||||
stubMethods = PR_GetDefaultIOMethods();
|
||||
stubMethods = PR_GetDefaultIOMethods();
|
||||
|
||||
ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */
|
||||
/* then override the ones we care about */
|
||||
ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
|
||||
ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
|
||||
ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
|
||||
ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
|
||||
ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
|
||||
ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
|
||||
/*
|
||||
ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
|
||||
ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
|
||||
*/
|
||||
ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */
|
||||
/* then override the ones we care about */
|
||||
ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
|
||||
ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
|
||||
ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
|
||||
ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
|
||||
ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName;
|
||||
ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
|
||||
/*
|
||||
ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
|
||||
ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
|
||||
*/
|
||||
return PR_SUCCESS;
|
||||
ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */
|
||||
/* then override the ones we care about */
|
||||
ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
|
||||
ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
|
||||
ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
|
||||
ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
|
||||
ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
|
||||
ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
|
||||
/*
|
||||
ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
|
||||
ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
|
||||
*/
|
||||
ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */
|
||||
/* then override the ones we care about */
|
||||
ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
|
||||
ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
|
||||
ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
|
||||
ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
|
||||
ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName;
|
||||
ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
|
||||
/*
|
||||
ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
|
||||
ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
|
||||
*/
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(_PR_INET6_PROBE)
|
||||
PRBool _pr_ipv6_is_present(void)
|
||||
{
|
||||
if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS)
|
||||
if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return ipv6_is_present;
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
|
||||
{
|
||||
PRFileDesc *ipv6_fd = NULL;
|
||||
PRFileDesc *ipv6_fd = NULL;
|
||||
|
||||
if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS)
|
||||
return PR_FAILURE;
|
||||
if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* For platforms with no support for IPv6
|
||||
* create layered socket for IPv4-mapped IPv6 addresses
|
||||
*/
|
||||
if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
|
||||
ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
|
||||
&ipv6_to_v4_tcpMethods);
|
||||
else
|
||||
ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
|
||||
&ipv6_to_v4_udpMethods);
|
||||
if (NULL == ipv6_fd) {
|
||||
goto errorExit;
|
||||
}
|
||||
ipv6_fd->secret = NULL;
|
||||
/*
|
||||
* For platforms with no support for IPv6
|
||||
* create layered socket for IPv4-mapped IPv6 addresses
|
||||
*/
|
||||
if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
|
||||
ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
|
||||
&ipv6_to_v4_tcpMethods);
|
||||
else
|
||||
ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
|
||||
&ipv6_to_v4_udpMethods);
|
||||
if (NULL == ipv6_fd) {
|
||||
goto errorExit;
|
||||
}
|
||||
ipv6_fd->secret = NULL;
|
||||
|
||||
if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
|
||||
goto errorExit;
|
||||
}
|
||||
if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
errorExit:
|
||||
|
||||
if (ipv6_fd)
|
||||
ipv6_fd->dtor(ipv6_fd);
|
||||
return PR_FAILURE;
|
||||
if (ipv6_fd) {
|
||||
ipv6_fd->dtor(ipv6_fd);
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@ static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack);
|
|||
void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
|
||||
{
|
||||
PR_ASSERT(fd != NULL);
|
||||
if (NULL != fd->lower) fd->lower->higher = fd->higher;
|
||||
if (NULL != fd->higher) fd->higher->lower = fd->lower;
|
||||
if (NULL != fd->lower) {
|
||||
fd->lower->higher = fd->higher;
|
||||
}
|
||||
if (NULL != fd->higher) {
|
||||
fd->higher->lower = fd->lower;
|
||||
}
|
||||
PR_DELETE(fd);
|
||||
}
|
||||
|
||||
|
|
@ -32,42 +36,42 @@ void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
|
|||
static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
|
||||
{
|
||||
PRFileDesc *top, *lower;
|
||||
PRStatus rv;
|
||||
PRStatus rv;
|
||||
|
||||
PR_ASSERT(fd != NULL);
|
||||
PR_ASSERT(fd->lower != NULL);
|
||||
PR_ASSERT(fd->secret == NULL);
|
||||
PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED);
|
||||
|
||||
if (PR_IO_LAYER_HEAD == fd->identity) {
|
||||
/*
|
||||
* new style stack; close all the layers, before deleting the
|
||||
* stack head
|
||||
*/
|
||||
rv = fd->lower->methods->close(fd->lower);
|
||||
_PR_DestroyIOLayer(fd);
|
||||
return rv;
|
||||
}
|
||||
if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
|
||||
/*
|
||||
* lower layers of new style stack
|
||||
*/
|
||||
lower = fd->lower;
|
||||
/*
|
||||
* pop and cleanup current layer
|
||||
*/
|
||||
top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER);
|
||||
top->dtor(top);
|
||||
/*
|
||||
* then call lower layer
|
||||
*/
|
||||
return (lower->methods->close(lower));
|
||||
} else {
|
||||
/* old style stack */
|
||||
top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
|
||||
top->dtor(top);
|
||||
return (fd->methods->close)(fd);
|
||||
}
|
||||
if (PR_IO_LAYER_HEAD == fd->identity) {
|
||||
/*
|
||||
* new style stack; close all the layers, before deleting the
|
||||
* stack head
|
||||
*/
|
||||
rv = fd->lower->methods->close(fd->lower);
|
||||
_PR_DestroyIOLayer(fd);
|
||||
return rv;
|
||||
}
|
||||
if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
|
||||
/*
|
||||
* lower layers of new style stack
|
||||
*/
|
||||
lower = fd->lower;
|
||||
/*
|
||||
* pop and cleanup current layer
|
||||
*/
|
||||
top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER);
|
||||
top->dtor(top);
|
||||
/*
|
||||
* then call lower layer
|
||||
*/
|
||||
return (lower->methods->close(lower));
|
||||
} else {
|
||||
/* old style stack */
|
||||
top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
|
||||
top->dtor(top);
|
||||
return (fd->methods->close)(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount)
|
||||
|
|
@ -146,7 +150,7 @@ static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info
|
|||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov,
|
||||
PRInt32 size, PRIntervalTime timeout)
|
||||
PRInt32 size, PRIntervalTime timeout)
|
||||
{
|
||||
PR_ASSERT(fd != NULL);
|
||||
PR_ASSERT(fd->lower != NULL);
|
||||
|
|
@ -178,15 +182,16 @@ static PRFileDesc* PR_CALLBACK pl_TopAccept (
|
|||
PRStatus rv;
|
||||
PRFileDesc *newfd, *layer = fd;
|
||||
PRFileDesc *newstack;
|
||||
PRBool newstyle_stack = PR_FALSE;
|
||||
PRBool newstyle_stack = PR_FALSE;
|
||||
|
||||
PR_ASSERT(fd != NULL);
|
||||
PR_ASSERT(fd->lower != NULL);
|
||||
|
||||
/* test for new style stack */
|
||||
while (NULL != layer->higher)
|
||||
layer = layer->higher;
|
||||
newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
|
||||
/* test for new style stack */
|
||||
while (NULL != layer->higher) {
|
||||
layer = layer->higher;
|
||||
}
|
||||
newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
|
||||
newstack = PR_NEW(PRFileDesc);
|
||||
if (NULL == newstack)
|
||||
{
|
||||
|
|
@ -246,7 +251,7 @@ static PRInt32 PR_CALLBACK pl_DefRecv (
|
|||
PR_ASSERT(fd->lower != NULL);
|
||||
|
||||
return (fd->lower->methods->recv)(
|
||||
fd->lower, buf, amount, flags, timeout);
|
||||
fd->lower, buf, amount, flags, timeout);
|
||||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK pl_DefSend (
|
||||
|
|
@ -267,7 +272,7 @@ static PRInt32 PR_CALLBACK pl_DefRecvfrom (
|
|||
PR_ASSERT(fd->lower != NULL);
|
||||
|
||||
return (fd->lower->methods->recvfrom)(
|
||||
fd->lower, buf, amount, flags, addr, timeout);
|
||||
fd->lower, buf, amount, flags, addr, timeout);
|
||||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK pl_DefSendto (
|
||||
|
|
@ -278,7 +283,7 @@ static PRInt32 PR_CALLBACK pl_DefSendto (
|
|||
PR_ASSERT(fd->lower != NULL);
|
||||
|
||||
return (fd->lower->methods->sendto)(
|
||||
fd->lower, buf, amount, flags, addr, timeout);
|
||||
fd->lower, buf, amount, flags, addr, timeout);
|
||||
}
|
||||
|
||||
static PRInt16 PR_CALLBACK pl_DefPoll (
|
||||
|
|
@ -298,15 +303,16 @@ static PRInt32 PR_CALLBACK pl_DefAcceptread (
|
|||
PRStatus rv;
|
||||
PRFileDesc *newstack;
|
||||
PRFileDesc *layer = sd;
|
||||
PRBool newstyle_stack = PR_FALSE;
|
||||
PRBool newstyle_stack = PR_FALSE;
|
||||
|
||||
PR_ASSERT(sd != NULL);
|
||||
PR_ASSERT(sd->lower != NULL);
|
||||
|
||||
/* test for new style stack */
|
||||
while (NULL != layer->higher)
|
||||
layer = layer->higher;
|
||||
newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
|
||||
/* test for new style stack */
|
||||
while (NULL != layer->higher) {
|
||||
layer = layer->higher;
|
||||
}
|
||||
newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
|
||||
newstack = PR_NEW(PRFileDesc);
|
||||
if (NULL == newstack)
|
||||
{
|
||||
|
|
@ -316,18 +322,18 @@ static PRInt32 PR_CALLBACK pl_DefAcceptread (
|
|||
*newstack = *sd; /* make a copy of the accepting layer */
|
||||
|
||||
nbytes = sd->lower->methods->acceptread(
|
||||
sd->lower, nd, raddr, buf, amount, t);
|
||||
sd->lower, nd, raddr, buf, amount, t);
|
||||
if (-1 == nbytes)
|
||||
{
|
||||
PR_DELETE(newstack);
|
||||
return nbytes;
|
||||
}
|
||||
if (newstyle_stack) {
|
||||
newstack->lower = *nd;
|
||||
(*nd)->higher = newstack;
|
||||
*nd = newstack;
|
||||
return nbytes;
|
||||
}
|
||||
newstack->lower = *nd;
|
||||
(*nd)->higher = newstack;
|
||||
*nd = newstack;
|
||||
return nbytes;
|
||||
}
|
||||
/* this PR_PushIOLayer call cannot fail */
|
||||
rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
|
||||
PR_ASSERT(PR_SUCCESS == rv);
|
||||
|
|
@ -342,7 +348,7 @@ static PRInt32 PR_CALLBACK pl_DefTransmitfile (
|
|||
PR_ASSERT(sd->lower != NULL);
|
||||
|
||||
return sd->lower->methods->transmitfile(
|
||||
sd->lower, fd, headers, hlen, flags, t);
|
||||
sd->lower, fd, headers, hlen, flags, t);
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr)
|
||||
|
|
@ -380,14 +386,14 @@ static PRStatus PR_CALLBACK pl_DefSetsocketoption (
|
|||
}
|
||||
|
||||
static PRInt32 PR_CALLBACK pl_DefSendfile (
|
||||
PRFileDesc *sd, PRSendFileData *sfd,
|
||||
PRTransmitFileFlags flags, PRIntervalTime timeout)
|
||||
PRFileDesc *sd, PRSendFileData *sfd,
|
||||
PRTransmitFileFlags flags, PRIntervalTime timeout)
|
||||
{
|
||||
PR_ASSERT(sd != NULL);
|
||||
PR_ASSERT(sd->lower != NULL);
|
||||
|
||||
return sd->lower->methods->sendfile(
|
||||
sd->lower, sfd, flags, timeout);
|
||||
sd->lower, sfd, flags, timeout);
|
||||
}
|
||||
|
||||
/* Methods for the top of the stack. Just call down to the next fd. */
|
||||
|
|
@ -440,13 +446,15 @@ PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
|
|||
{
|
||||
PRFileDesc *fd = NULL;
|
||||
PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
|
||||
if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident))
|
||||
if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident)) {
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = PR_NEWZAP(PRFileDesc);
|
||||
if (NULL == fd)
|
||||
if (NULL == fd) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd->methods = methods;
|
||||
|
|
@ -459,41 +467,43 @@ PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
|
|||
|
||||
/*
|
||||
* PR_CreateIOLayer
|
||||
* Create a new style stack, where the stack top is a dummy header.
|
||||
* Unlike the old style stacks, the contents of the stack head
|
||||
* are not modified when a layer is pushed onto or popped from a new
|
||||
* style stack.
|
||||
* Create a new style stack, where the stack top is a dummy header.
|
||||
* Unlike the old style stacks, the contents of the stack head
|
||||
* are not modified when a layer is pushed onto or popped from a new
|
||||
* style stack.
|
||||
*/
|
||||
|
||||
PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top)
|
||||
{
|
||||
PRFileDesc *fd = NULL;
|
||||
|
||||
fd = PR_NEWZAP(PRFileDesc);
|
||||
if (NULL == fd)
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
else
|
||||
{
|
||||
fd->methods = &pl_methods;
|
||||
fd->dtor = pl_FDDestructor;
|
||||
fd->identity = PR_IO_LAYER_HEAD;
|
||||
fd->higher = NULL;
|
||||
fd->lower = top;
|
||||
top->higher = fd;
|
||||
top->lower = NULL;
|
||||
}
|
||||
fd = PR_NEWZAP(PRFileDesc);
|
||||
if (NULL == fd) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd->methods = &pl_methods;
|
||||
fd->dtor = pl_FDDestructor;
|
||||
fd->identity = PR_IO_LAYER_HEAD;
|
||||
fd->higher = NULL;
|
||||
fd->lower = top;
|
||||
top->higher = fd;
|
||||
top->lower = NULL;
|
||||
}
|
||||
return fd;
|
||||
} /* PR_CreateIOLayer */
|
||||
|
||||
/*
|
||||
* _PR_DestroyIOLayer
|
||||
* Delete the stack head of a new style stack.
|
||||
* Delete the stack head of a new style stack.
|
||||
*/
|
||||
|
||||
static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
|
||||
{
|
||||
if (NULL == stack)
|
||||
if (NULL == stack) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_DELETE(stack);
|
||||
return PR_SUCCESS;
|
||||
|
|
@ -516,24 +526,24 @@ PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
|
|||
|
||||
if (stack == insert)
|
||||
{
|
||||
/* going on top of the stack */
|
||||
/* old-style stack */
|
||||
PRFileDesc copy = *stack;
|
||||
*stack = *fd;
|
||||
*fd = copy;
|
||||
fd->higher = stack;
|
||||
if (fd->lower)
|
||||
{
|
||||
PR_ASSERT(fd->lower->higher == stack);
|
||||
fd->lower->higher = fd;
|
||||
}
|
||||
stack->lower = fd;
|
||||
stack->higher = NULL;
|
||||
} else {
|
||||
/* going on top of the stack */
|
||||
/* old-style stack */
|
||||
PRFileDesc copy = *stack;
|
||||
*stack = *fd;
|
||||
*fd = copy;
|
||||
fd->higher = stack;
|
||||
if (fd->lower)
|
||||
{
|
||||
PR_ASSERT(fd->lower->higher == stack);
|
||||
fd->lower->higher = fd;
|
||||
}
|
||||
stack->lower = fd;
|
||||
stack->higher = NULL;
|
||||
} else {
|
||||
/*
|
||||
* going somewhere in the middle of the stack for both old and new
|
||||
* style stacks, or going on top of stack for new style stack
|
||||
*/
|
||||
* going somewhere in the middle of the stack for both old and new
|
||||
* style stacks, or going on top of stack for new style stack
|
||||
*/
|
||||
fd->lower = insert;
|
||||
fd->higher = insert->higher;
|
||||
|
||||
|
|
@ -559,7 +569,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
|
|||
|
||||
if (extract == stack) {
|
||||
/* popping top layer of the stack */
|
||||
/* old style stack */
|
||||
/* old style stack */
|
||||
PRFileDesc copy = *stack;
|
||||
extract = stack->lower;
|
||||
*stack = *extract;
|
||||
|
|
@ -569,16 +579,16 @@ PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
|
|||
PR_ASSERT(stack->lower->higher == extract);
|
||||
stack->lower->higher = stack;
|
||||
}
|
||||
} else if ((PR_IO_LAYER_HEAD == stack->identity) &&
|
||||
(extract == stack->lower) && (extract->lower == NULL)) {
|
||||
/*
|
||||
* new style stack
|
||||
* popping the only layer in the stack; delete the stack too
|
||||
*/
|
||||
stack->lower = NULL;
|
||||
_PR_DestroyIOLayer(stack);
|
||||
} else {
|
||||
/* for both kinds of stacks */
|
||||
} else if ((PR_IO_LAYER_HEAD == stack->identity) &&
|
||||
(extract == stack->lower) && (extract->lower == NULL)) {
|
||||
/*
|
||||
* new style stack
|
||||
* popping the only layer in the stack; delete the stack too
|
||||
*/
|
||||
stack->lower = NULL;
|
||||
_PR_DestroyIOLayer(stack);
|
||||
} else {
|
||||
/* for both kinds of stacks */
|
||||
extract->lower->higher = extract->higher;
|
||||
extract->higher->lower = extract->lower;
|
||||
}
|
||||
|
|
@ -602,7 +612,9 @@ PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name)
|
|||
PRDescIdentity identity, length;
|
||||
char **names = NULL, *name = NULL, **old = NULL;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident);
|
||||
|
||||
|
|
@ -634,7 +646,9 @@ retry:
|
|||
names = (char**)PR_CALLOC(length * sizeof(char*));
|
||||
if (NULL == names)
|
||||
{
|
||||
if (NULL != name) PR_DELETE(name);
|
||||
if (NULL != name) {
|
||||
PR_DELETE(name);
|
||||
}
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return PR_INVALID_IO_LAYER;
|
||||
}
|
||||
|
|
@ -664,7 +678,9 @@ retry:
|
|||
else
|
||||
{
|
||||
PR_Unlock(identity_cache.ml);
|
||||
if (NULL != names) PR_DELETE(names);
|
||||
if (NULL != names) {
|
||||
PR_DELETE(names);
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
|
@ -676,8 +692,12 @@ retry:
|
|||
PR_ASSERT(identity_cache.ident < identity_cache.length);
|
||||
PR_Unlock(identity_cache.ml);
|
||||
|
||||
if (NULL != old) PR_DELETE(old);
|
||||
if (NULL != names) PR_DELETE(names);
|
||||
if (NULL != old) {
|
||||
PR_DELETE(old);
|
||||
}
|
||||
if (NULL != names) {
|
||||
PR_DELETE(names);
|
||||
}
|
||||
|
||||
return identity;
|
||||
} /* PR_GetUniqueIdentity */
|
||||
|
|
@ -685,13 +705,15 @@ retry:
|
|||
PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident)
|
||||
{
|
||||
const char *rv = NULL;
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
if ((PR_TOP_IO_LAYER != ident) && (ident >= 0)) {
|
||||
PR_Lock(identity_cache.ml);
|
||||
PR_ASSERT(ident <= identity_cache.ident);
|
||||
rv = (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];
|
||||
PR_Unlock(identity_cache.ml);
|
||||
PR_Lock(identity_cache.ml);
|
||||
PR_ASSERT(ident <= identity_cache.ident);
|
||||
rv = (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];
|
||||
PR_Unlock(identity_cache.ml);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
@ -701,9 +723,9 @@ PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
|
|||
{
|
||||
PR_ASSERT(NULL != fd);
|
||||
if (PR_IO_LAYER_HEAD == fd->identity) {
|
||||
PR_ASSERT(NULL != fd->lower);
|
||||
return fd->lower->identity;
|
||||
}
|
||||
PR_ASSERT(NULL != fd->lower);
|
||||
return fd->lower->identity;
|
||||
}
|
||||
return fd->identity;
|
||||
} /* PR_GetLayersIdentity */
|
||||
|
||||
|
|
@ -712,19 +734,23 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity i
|
|||
PRFileDesc *layer = fd;
|
||||
|
||||
if (PR_TOP_IO_LAYER == id) {
|
||||
if (PR_IO_LAYER_HEAD == fd->identity) {
|
||||
return fd->lower;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
if (PR_IO_LAYER_HEAD == fd->identity) {
|
||||
return fd->lower;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
for (layer = fd; layer != NULL; layer = layer->lower)
|
||||
{
|
||||
if (id == layer->identity) return layer;
|
||||
if (id == layer->identity) {
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
for (layer = fd; layer != NULL; layer = layer->higher)
|
||||
{
|
||||
if (id == layer->identity) return layer;
|
||||
if (id == layer->identity) {
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
} /* PR_GetIdentitiesLayer */
|
||||
|
|
@ -748,8 +774,9 @@ void _PR_CleanupLayerCache(void)
|
|||
{
|
||||
PRDescIdentity ident;
|
||||
|
||||
for (ident = 0; ident <= identity_cache.ident; ident++)
|
||||
for (ident = 0; ident <= identity_cache.ident; ident++) {
|
||||
PR_DELETE(identity_cache.name[ident]);
|
||||
}
|
||||
|
||||
PR_DELETE(identity_cache.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,8 +166,9 @@ PRIntn strcasecmp(const char *a, const char *b)
|
|||
const unsigned char *ua = (const unsigned char *)a;
|
||||
const unsigned char *ub = (const unsigned char *)b;
|
||||
|
||||
if( ((const char *)0 == a) || (const char *)0 == b )
|
||||
if( ((const char *)0 == a) || (const char *)0 == b ) {
|
||||
return (PRIntn)(a-b);
|
||||
}
|
||||
|
||||
while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )
|
||||
{
|
||||
|
|
@ -201,7 +202,9 @@ void _PR_InitLog(void)
|
|||
count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
|
||||
module, &delta, &level, &delta);
|
||||
pos += delta;
|
||||
if (count == 0) break;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** If count == 2, then we got module and level. If count
|
||||
|
|
@ -223,7 +226,9 @@ void _PR_InitLog(void)
|
|||
(0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
while (lm != NULL) {
|
||||
if (skip_modcheck) lm -> level = (PRLogModuleLevel)level;
|
||||
if (skip_modcheck) {
|
||||
lm -> level = (PRLogModuleLevel)level;
|
||||
}
|
||||
else if (strcasecmp(module, lm->name) == 0) {
|
||||
lm->level = (PRLogModuleLevel)level;
|
||||
break;
|
||||
|
|
@ -234,7 +239,9 @@ void _PR_InitLog(void)
|
|||
/*found:*/
|
||||
count = sscanf(&ev[pos], " , %n", &delta);
|
||||
pos += delta;
|
||||
if (count == EOF) break;
|
||||
if (count == EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
PR_SetLogBuffering(isSync ? 0 : bufSize);
|
||||
|
||||
|
|
@ -274,7 +281,7 @@ void _PR_LogCleanup(void)
|
|||
#ifdef XP_PC
|
||||
&& logFile != WIN32_DEBUG_FILE
|
||||
#endif
|
||||
) {
|
||||
) {
|
||||
fclose(logFile);
|
||||
}
|
||||
#else
|
||||
|
|
@ -284,8 +291,9 @@ void _PR_LogCleanup(void)
|
|||
#endif
|
||||
logFile = NULL;
|
||||
|
||||
if (logBuf)
|
||||
if (logBuf) {
|
||||
PR_DELETE(logBuf);
|
||||
}
|
||||
|
||||
while (lm != NULL) {
|
||||
PRLogModuleInfo *next = lm->next;
|
||||
|
|
@ -318,7 +326,9 @@ static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm )
|
|||
count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
|
||||
module, &delta, &level, &delta);
|
||||
pos += delta;
|
||||
if (count == 0) break;
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** If count == 2, then we got module and level. If count
|
||||
|
|
@ -334,7 +344,9 @@ static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm )
|
|||
}
|
||||
count = sscanf(&ev[pos], " , %n", &delta);
|
||||
pos += delta;
|
||||
if (count == EOF) break;
|
||||
if (count == EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end _PR_SetLogModuleLevel() */
|
||||
|
|
@ -343,7 +355,9 @@ PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name)
|
|||
{
|
||||
PRLogModuleInfo *lm;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
lm = PR_NEWZAP(PRLogModuleInfo);
|
||||
if (lm) {
|
||||
|
|
@ -371,8 +385,9 @@ PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
|
|||
{
|
||||
const char *mode = appendToLog ? "a" : "w";
|
||||
newLogFile = fopen(file, mode);
|
||||
if (!newLogFile)
|
||||
if (!newLogFile) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifndef WINCE /* _IONBF does not exist in the Windows Mobile 6 SDK. */
|
||||
/* We do buffering ourselves. */
|
||||
|
|
@ -385,7 +400,7 @@ PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
|
|||
#ifdef XP_PC
|
||||
&& logFile != WIN32_DEBUG_FILE
|
||||
#endif
|
||||
) {
|
||||
) {
|
||||
fclose(logFile);
|
||||
}
|
||||
logFile = newLogFile;
|
||||
|
|
@ -414,8 +429,9 @@ PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size)
|
|||
{
|
||||
PR_LogFlush();
|
||||
|
||||
if (logBuf)
|
||||
if (logBuf) {
|
||||
PR_DELETE(logBuf);
|
||||
}
|
||||
|
||||
if (buffer_size >= LINE_BUF_SIZE) {
|
||||
logp = logBuf = (char*) PR_MALLOC(buffer_size);
|
||||
|
|
@ -432,7 +448,9 @@ PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
|
|||
PRThread *me;
|
||||
PRExplodedTime now;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
if (!logFile) {
|
||||
return;
|
||||
|
|
@ -520,10 +538,10 @@ PR_IMPLEMENT(void) PR_LogFlush(void)
|
|||
{
|
||||
if (logBuf && logFile) {
|
||||
_PR_LOCK_LOG();
|
||||
if (logp > logBuf) {
|
||||
_PUT_LOG(logFile, logBuf, logp - logBuf);
|
||||
logp = logBuf;
|
||||
}
|
||||
if (logp > logBuf) {
|
||||
_PUT_LOG(logFile, logBuf, logp - logBuf);
|
||||
logp = logBuf;
|
||||
}
|
||||
_PR_UNLOCK_LOG();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,11 +62,10 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
{
|
||||
case PR_SockOpt_Linger:
|
||||
{
|
||||
#if !defined(XP_BEOS) || defined(BONE_VERSION)
|
||||
struct linger linger;
|
||||
length = sizeof(linger);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char *) &linger, &length);
|
||||
fd, level, name, (char *) &linger, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
{
|
||||
PR_ASSERT(sizeof(linger) == length);
|
||||
|
|
@ -76,10 +75,6 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
PR_SecondsToInterval(linger.l_linger);
|
||||
}
|
||||
break;
|
||||
#else
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return PR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
case PR_SockOpt_Reuseaddr:
|
||||
case PR_SockOpt_Keepalive:
|
||||
|
|
@ -94,9 +89,10 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
#endif
|
||||
length = sizeof(value);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&value, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
fd, level, name, (char*)&value, &length);
|
||||
if (PR_SUCCESS == rv) {
|
||||
data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_McastLoopback:
|
||||
|
|
@ -108,9 +104,10 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
#endif
|
||||
length = sizeof(bool);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&bool, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
fd, level, name, (char*)&bool, &length);
|
||||
if (PR_SUCCESS == rv) {
|
||||
data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_RecvBufferSize:
|
||||
|
|
@ -120,9 +117,10 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
PRIntn value;
|
||||
length = sizeof(value);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&value, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
fd, level, name, (char*)&value, &length);
|
||||
if (PR_SUCCESS == rv) {
|
||||
data->value.recv_buffer_size = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_IpTimeToLive:
|
||||
|
|
@ -131,7 +129,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
/* These options should really be an int (or PRIntn). */
|
||||
length = sizeof(PRUintn);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&data->value.ip_ttl, &length);
|
||||
fd, level, name, (char*)&data->value.ip_ttl, &length);
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_McastTimeToLive:
|
||||
|
|
@ -143,9 +141,10 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
#endif
|
||||
length = sizeof(ttl);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&ttl, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
fd, level, name, (char*)&ttl, &length);
|
||||
if (PR_SUCCESS == rv) {
|
||||
data->value.mcast_ttl = ttl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef IP_ADD_MEMBERSHIP
|
||||
|
|
@ -155,7 +154,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
struct ip_mreq mreq;
|
||||
length = sizeof(mreq);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name, (char*)&mreq, &length);
|
||||
fd, level, name, (char*)&mreq, &length);
|
||||
if (PR_SUCCESS == rv)
|
||||
{
|
||||
data->value.add_member.mcaddr.inet.ip =
|
||||
|
|
@ -171,14 +170,14 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat
|
|||
/* This option is a struct in_addr. */
|
||||
length = sizeof(data->value.mcast_if.inet.ip);
|
||||
rv = _PR_MD_GETSOCKOPT(
|
||||
fd, level, name,
|
||||
(char*)&data->value.mcast_if.inet.ip, &length);
|
||||
fd, level, name,
|
||||
(char*)&data->value.mcast_if.inet.ip, &length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PR_NOT_REACHED("Unknown socket option");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
} /* _PR_SocketGetSocketOption */
|
||||
|
|
@ -196,7 +195,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
{
|
||||
#ifdef WINNT
|
||||
PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
|
||||
|| (fd->secret->nonblocking == data->value.non_blocking));
|
||||
|| (fd->secret->nonblocking == data->value.non_blocking));
|
||||
if (fd->secret->md.io_model_committed
|
||||
&& (fd->secret->nonblocking != data->value.non_blocking))
|
||||
{
|
||||
|
|
@ -221,17 +220,12 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
{
|
||||
case PR_SockOpt_Linger:
|
||||
{
|
||||
#if !defined(XP_BEOS) || defined(BONE_VERSION)
|
||||
struct linger linger;
|
||||
linger.l_onoff = data->value.linger.polarity;
|
||||
linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&linger, sizeof(linger));
|
||||
fd, level, name, (char*)&linger, sizeof(linger));
|
||||
break;
|
||||
#else
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return PR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
case PR_SockOpt_Reuseaddr:
|
||||
case PR_SockOpt_Keepalive:
|
||||
|
|
@ -246,7 +240,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
#endif
|
||||
value = (data->value.reuse_addr) ? 1 : 0;
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&value, sizeof(value));
|
||||
fd, level, name, (char*)&value, sizeof(value));
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_McastLoopback:
|
||||
|
|
@ -258,7 +252,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
#endif
|
||||
bool = data->value.mcast_loopback ? 1 : 0;
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&bool, sizeof(bool));
|
||||
fd, level, name, (char*)&bool, sizeof(bool));
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_RecvBufferSize:
|
||||
|
|
@ -267,7 +261,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
{
|
||||
PRIntn value = data->value.recv_buffer_size;
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&value, sizeof(value));
|
||||
fd, level, name, (char*)&value, sizeof(value));
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_IpTimeToLive:
|
||||
|
|
@ -275,7 +269,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
{
|
||||
/* These options should really be an int (or PRIntn). */
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
|
||||
fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
|
||||
break;
|
||||
}
|
||||
case PR_SockOpt_McastTimeToLive:
|
||||
|
|
@ -287,7 +281,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
#endif
|
||||
ttl = data->value.mcast_ttl;
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&ttl, sizeof(ttl));
|
||||
fd, level, name, (char*)&ttl, sizeof(ttl));
|
||||
break;
|
||||
}
|
||||
#ifdef IP_ADD_MEMBERSHIP
|
||||
|
|
@ -300,7 +294,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
mreq.imr_interface.s_addr =
|
||||
data->value.add_member.ifaddr.inet.ip;
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&mreq, sizeof(mreq));
|
||||
fd, level, name, (char*)&mreq, sizeof(mreq));
|
||||
break;
|
||||
}
|
||||
#endif /* IP_ADD_MEMBERSHIP */
|
||||
|
|
@ -308,14 +302,14 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt
|
|||
{
|
||||
/* This option is a struct in_addr. */
|
||||
rv = _PR_MD_SETSOCKOPT(
|
||||
fd, level, name, (char*)&data->value.mcast_if.inet.ip,
|
||||
sizeof(data->value.mcast_if.inet.ip));
|
||||
fd, level, name, (char*)&data->value.mcast_if.inet.ip,
|
||||
sizeof(data->value.mcast_if.inet.ip));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PR_NOT_REACHED("Unknown socket option");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
} /* _PR_SocketSetSocketOption */
|
||||
|
|
@ -441,7 +435,7 @@ PRStatus _PR_MapOptionName(
|
|||
};
|
||||
|
||||
if ((optname < PR_SockOpt_Linger)
|
||||
|| (optname >= PR_SockOpt_Last))
|
||||
|| (optname >= PR_SockOpt_Last))
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -21,19 +21,19 @@ PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap(
|
|||
PRFileMap *fmap;
|
||||
|
||||
PR_ASSERT(prot == PR_PROT_READONLY || prot == PR_PROT_READWRITE
|
||||
|| prot == PR_PROT_WRITECOPY);
|
||||
|| prot == PR_PROT_WRITECOPY);
|
||||
fmap = PR_NEWZAP(PRFileMap);
|
||||
if (NULL == fmap) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
fmap->fd = fd;
|
||||
fmap->prot = prot;
|
||||
if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) {
|
||||
return fmap;
|
||||
return fmap;
|
||||
}
|
||||
PR_DELETE(fmap);
|
||||
return NULL;
|
||||
PR_DELETE(fmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void)
|
||||
|
|
@ -64,5 +64,5 @@ PR_IMPLEMENT(PRStatus) PR_SyncMemMap(
|
|||
void *addr,
|
||||
PRUint32 len)
|
||||
{
|
||||
return _PR_MD_SYNC_MEM_MAP(fd, addr, len);
|
||||
return _PR_MD_SYNC_MEM_MAP(fd, addr, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct {
|
|||
static PRStatus TimerInit(void);
|
||||
static void TimerManager(void *arg);
|
||||
static TimerEvent *CreateTimer(PRIntervalTime timeout,
|
||||
void (*func)(void *), void *arg);
|
||||
void (*func)(void *), void *arg);
|
||||
static PRBool CancelTimer(TimerEvent *timer);
|
||||
|
||||
static void TimerManager(void *arg)
|
||||
|
|
@ -81,7 +81,7 @@ static void TimerManager(void *arg)
|
|||
{
|
||||
timeout = (PRIntervalTime)(timer->absolute - now);
|
||||
PR_WaitCondVar(tm_vars.new_timer, timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_Unlock(tm_vars.ml);
|
||||
|
|
@ -143,7 +143,7 @@ static PRBool CancelTimer(TimerEvent *timer)
|
|||
}
|
||||
PR_Unlock(tm_vars.ml);
|
||||
PR_DELETE(timer);
|
||||
return canceled;
|
||||
return canceled;
|
||||
}
|
||||
|
||||
static PRStatus TimerInit(void)
|
||||
|
|
@ -165,8 +165,8 @@ static PRStatus TimerInit(void)
|
|||
}
|
||||
PR_INIT_CLIST(&tm_vars.timer_queue);
|
||||
tm_vars.manager_thread = PR_CreateThread(
|
||||
PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
|
||||
PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
|
||||
if (NULL == tm_vars.manager_thread)
|
||||
{
|
||||
goto failed;
|
||||
|
|
@ -231,7 +231,9 @@ static PRWaitGroup *MW_Init2(void)
|
|||
if (NULL == group) /* there is this special case */
|
||||
{
|
||||
group = PR_CreateWaitGroup(_PR_DEFAULT_HASH_LENGTH);
|
||||
if (NULL == group) goto failed_alloc;
|
||||
if (NULL == group) {
|
||||
goto failed_alloc;
|
||||
}
|
||||
PR_Lock(mw_lock);
|
||||
if (NULL == mw_state->group)
|
||||
{
|
||||
|
|
@ -239,7 +241,9 @@ static PRWaitGroup *MW_Init2(void)
|
|||
group = NULL;
|
||||
}
|
||||
PR_Unlock(mw_lock);
|
||||
if (group != NULL) (void)PR_DestroyWaitGroup(group);
|
||||
if (group != NULL) {
|
||||
(void)PR_DestroyWaitGroup(group);
|
||||
}
|
||||
group = mw_state->group; /* somebody beat us to it */
|
||||
}
|
||||
failed_alloc:
|
||||
|
|
@ -301,7 +305,7 @@ static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
|
|||
}
|
||||
hidx = (hidx + hoffset) % (hash->length);
|
||||
}
|
||||
return _prmw_rehash;
|
||||
return _prmw_rehash;
|
||||
} /* MW_AddHashInternal */
|
||||
|
||||
static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
||||
|
|
@ -314,7 +318,8 @@ static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
|||
|
||||
static const PRInt32 prime_number[] = {
|
||||
_PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427,
|
||||
2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771};
|
||||
2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771
|
||||
};
|
||||
PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32));
|
||||
|
||||
/* look up the next size we'd like to use for the hash table */
|
||||
|
|
@ -337,7 +342,7 @@ static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
|||
|
||||
/* allocate the new hash table and fill it in with the old */
|
||||
newHash = (_PRWaiterHash*)PR_CALLOC(
|
||||
sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
|
||||
sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
|
||||
if (NULL == newHash)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
|
|
@ -347,7 +352,7 @@ static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
|||
newHash->length = length;
|
||||
retry = PR_FALSE;
|
||||
for (desc = &oldHash->recv_wait;
|
||||
newHash->count < oldHash->count; ++desc)
|
||||
newHash->count < oldHash->count; ++desc)
|
||||
{
|
||||
PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length);
|
||||
if (NULL != *desc)
|
||||
|
|
@ -362,7 +367,9 @@ static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (retry) continue;
|
||||
if (retry) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PR_DELETE(group->waiter);
|
||||
group->waiter = newHash;
|
||||
|
|
@ -408,11 +415,13 @@ static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd)
|
|||
_PRWaiterHash *hash = group->waiter;
|
||||
PRUintn hidx = _MW_HASH(fd, hash->length);
|
||||
PRUintn hoffset = 0;
|
||||
|
||||
|
||||
while (rehash-- > 0)
|
||||
{
|
||||
desc = (&hash->recv_wait) + hidx;
|
||||
if ((*desc != NULL) && ((*desc)->fd == fd)) return desc;
|
||||
if ((*desc != NULL) && ((*desc)->fd == fd)) {
|
||||
return desc;
|
||||
}
|
||||
if (0 == hoffset)
|
||||
{
|
||||
hoffset = _MW_HASH2(fd, hash->length);
|
||||
|
|
@ -447,7 +456,9 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
goto aborted;
|
||||
}
|
||||
if (_MW_ABORTED(st)) goto aborted;
|
||||
if (_MW_ABORTED(st)) {
|
||||
goto aborted;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -470,8 +481,9 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
PR_Lock(group->ml);
|
||||
goto failed_alloc;
|
||||
}
|
||||
if (NULL != old_polling_list)
|
||||
if (NULL != old_polling_list) {
|
||||
PR_DELETE(old_polling_list);
|
||||
}
|
||||
PR_Lock(group->ml);
|
||||
if (_prmw_running != group->state)
|
||||
{
|
||||
|
|
@ -492,22 +504,24 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
for (count = 0; count < group->waiter->count; ++waiter)
|
||||
{
|
||||
PR_ASSERT(waiter < &group->waiter->recv_wait
|
||||
+ group->waiter->length);
|
||||
+ group->waiter->length);
|
||||
if (NULL != *waiter) /* a live one! */
|
||||
{
|
||||
if ((PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
|
||||
&& (since_last_poll >= (*waiter)->timeout))
|
||||
&& (since_last_poll >= (*waiter)->timeout)) {
|
||||
_MW_DoneInternal(group, waiter, PR_MW_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
|
||||
{
|
||||
(*waiter)->timeout -= since_last_poll;
|
||||
if ((*waiter)->timeout < polling_interval)
|
||||
if ((*waiter)->timeout < polling_interval) {
|
||||
polling_interval = (*waiter)->timeout;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(poll_list < group->polling_list
|
||||
+ group->polling_count);
|
||||
+ group->polling_count);
|
||||
poll_list->fd = (*waiter)->fd;
|
||||
poll_list->in_flags = PR_POLL_READ;
|
||||
poll_list->out_flags = 0;
|
||||
|
|
@ -520,7 +534,7 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_ASSERT(count == group->waiter->count);
|
||||
|
||||
|
|
@ -529,9 +543,13 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
** we need to return.
|
||||
*/
|
||||
if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
&& (1 == group->waiting_threads)) break;
|
||||
&& (1 == group->waiting_threads)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == count) continue; /* wait for new business */
|
||||
if (0 == count) {
|
||||
continue; /* wait for new business */
|
||||
}
|
||||
|
||||
group->last_poll = now;
|
||||
|
||||
|
|
@ -553,7 +571,7 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
else if (0 < count_ready)
|
||||
{
|
||||
for (poll_list = group->polling_list; count > 0;
|
||||
poll_list++, count--)
|
||||
poll_list++, count--)
|
||||
{
|
||||
PR_ASSERT(
|
||||
poll_list < group->polling_list + group->polling_count);
|
||||
|
|
@ -564,8 +582,9 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
** If 'waiter' is NULL, that means the wait receive
|
||||
** descriptor has been canceled.
|
||||
*/
|
||||
if (NULL != waiter)
|
||||
if (NULL != waiter) {
|
||||
_MW_DoneInternal(group, waiter, PR_MW_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -576,7 +595,9 @@ static PRStatus _MW_PollInternal(PRWaitGroup *group)
|
|||
** belongs to the client.
|
||||
*/
|
||||
if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
&& (1 == group->waiting_threads)) break;
|
||||
&& (1 == group->waiting_threads)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rv = PR_SUCCESS;
|
||||
|
|
@ -604,7 +625,7 @@ static PRMWGroupState MW_TestForShutdownInternal(PRWaitGroup *group)
|
|||
** to make sure no more threads are made to wait.
|
||||
*/
|
||||
if ((_prmw_stopping == rv)
|
||||
&& (0 == group->waiting_threads))
|
||||
&& (0 == group->waiting_threads))
|
||||
{
|
||||
rv = group->state = _prmw_stopped;
|
||||
PR_NotifyCondVar(group->mw_manage);
|
||||
|
|
@ -617,15 +638,17 @@ static void _MW_InitialRecv(PRCList *io_ready)
|
|||
{
|
||||
PRRecvWait *desc = (PRRecvWait*)io_ready;
|
||||
if ((NULL == desc->buffer.start)
|
||||
|| (0 == desc->buffer.length))
|
||||
|| (0 == desc->buffer.length)) {
|
||||
desc->bytesRecv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc->bytesRecv = (desc->fd->methods->recv)(
|
||||
desc->fd, desc->buffer.start,
|
||||
desc->buffer.length, 0, desc->timeout);
|
||||
if (desc->bytesRecv < 0) /* SetError should already be there */
|
||||
desc->fd, desc->buffer.start,
|
||||
desc->buffer.length, 0, desc->timeout);
|
||||
if (desc->bytesRecv < 0) { /* SetError should already be there */
|
||||
desc->outcome = PR_MW_FAILURE;
|
||||
}
|
||||
}
|
||||
} /* _MW_InitialRecv */
|
||||
#endif
|
||||
|
|
@ -636,9 +659,9 @@ static void NT_TimeProc(void *arg)
|
|||
_MDOverlapped *overlapped = (_MDOverlapped *)arg;
|
||||
PRRecvWait *desc = overlapped->data.mw.desc;
|
||||
PRFileDesc *bottom;
|
||||
|
||||
|
||||
if (InterlockedCompareExchange((LONG *)&desc->outcome,
|
||||
(LONG)PR_MW_TIMEOUT, (LONG)PR_MW_PENDING) != (LONG)PR_MW_PENDING)
|
||||
(LONG)PR_MW_TIMEOUT, (LONG)PR_MW_PENDING) != (LONG)PR_MW_PENDING)
|
||||
{
|
||||
/* This wait recv descriptor has already completed. */
|
||||
return;
|
||||
|
|
@ -712,7 +735,9 @@ PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
|
|||
PRFileDesc *bottom;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
if ((NULL == group) && (NULL == (group = MW_Init2())))
|
||||
{
|
||||
return rv;
|
||||
|
|
@ -744,15 +769,20 @@ PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
|
|||
** of the timing interval. As long as the list doesn't go empty,
|
||||
** it will maintain itself.
|
||||
*/
|
||||
if (0 == group->waiter->count)
|
||||
if (0 == group->waiter->count) {
|
||||
group->last_poll = PR_IntervalNow();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
hrv = MW_AddHashInternal(desc, group->waiter);
|
||||
if (_prmw_rehash != hrv) break;
|
||||
if (_prmw_rehash != hrv) {
|
||||
break;
|
||||
}
|
||||
hrv = MW_ExpandHashInternal(group); /* gruesome */
|
||||
if (_prmw_success != hrv) break;
|
||||
if (_prmw_success != hrv) {
|
||||
break;
|
||||
}
|
||||
} while (PR_TRUE);
|
||||
|
||||
#ifdef WINNT
|
||||
|
|
@ -777,9 +807,9 @@ PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
|
|||
if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
overlapped->data.mw.timer = CreateTimer(
|
||||
desc->timeout,
|
||||
NT_TimeProc,
|
||||
overlapped);
|
||||
desc->timeout,
|
||||
NT_TimeProc,
|
||||
overlapped);
|
||||
if (0 == overlapped->data.mw.timer)
|
||||
{
|
||||
NT_HashRemove(group, desc->fd);
|
||||
|
|
@ -801,7 +831,7 @@ PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
|
|||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
hFile = (HANDLE)bottom->secret->md.osfd;
|
||||
hFile = (HANDLE)bottom->secret->md.osfd;
|
||||
if (!bottom->secret->md.io_model_committed)
|
||||
{
|
||||
PRInt32 st;
|
||||
|
|
@ -810,16 +840,16 @@ PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
|
|||
bottom->secret->md.io_model_committed = PR_TRUE;
|
||||
}
|
||||
bResult = ReadFile(hFile,
|
||||
desc->buffer.start,
|
||||
(DWORD)desc->buffer.length,
|
||||
NULL,
|
||||
&overlapped->overlapped);
|
||||
desc->buffer.start,
|
||||
(DWORD)desc->buffer.length,
|
||||
NULL,
|
||||
&overlapped->overlapped);
|
||||
if (FALSE == bResult && (dwError = GetLastError()) != ERROR_IO_PENDING)
|
||||
{
|
||||
if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
if (InterlockedCompareExchange((LONG *)&desc->outcome,
|
||||
(LONG)PR_MW_FAILURE, (LONG)PR_MW_PENDING)
|
||||
(LONG)PR_MW_FAILURE, (LONG)PR_MW_PENDING)
|
||||
== (LONG)PR_MW_PENDING)
|
||||
{
|
||||
CancelTimer(overlapped->data.mw.timer);
|
||||
|
|
@ -840,11 +870,15 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
PRCList *io_ready = NULL;
|
||||
#ifdef WINNT
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
_MDOverlapped *overlapped;
|
||||
_MDOverlapped *overlapped;
|
||||
#endif
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if ((NULL == group) && (NULL == (group = MW_Init2()))) goto failed_init;
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
if ((NULL == group) && (NULL == (group = MW_Init2()))) {
|
||||
goto failed_init;
|
||||
}
|
||||
|
||||
PR_Lock(group->ml);
|
||||
|
||||
|
|
@ -890,7 +924,7 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
PR_REMOVE_LINK(io_ready);
|
||||
_PR_MD_UNLOCK(&group->mdlock);
|
||||
overlapped = (_MDOverlapped *)
|
||||
((char *)io_ready - offsetof(_MDOverlapped, data));
|
||||
((char *)io_ready - offsetof(_MDOverlapped, data));
|
||||
io_ready = &overlapped->data.mw.desc->internal;
|
||||
#else
|
||||
do
|
||||
|
|
@ -915,7 +949,9 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
** The polling function should only return w/ failure or
|
||||
** with some I/O ready.
|
||||
*/
|
||||
if (PR_FAILURE == _MW_PollInternal(group)) goto failed_poll;
|
||||
if (PR_FAILURE == _MW_PollInternal(group)) {
|
||||
goto failed_poll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -934,7 +970,7 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
** it is still full of if's with continue and goto.
|
||||
*/
|
||||
PRStatus st;
|
||||
do
|
||||
do
|
||||
{
|
||||
st = PR_WaitCondVar(group->io_complete, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (_prmw_running != group->state)
|
||||
|
|
@ -942,7 +978,9 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
goto aborted;
|
||||
}
|
||||
if (_MW_ABORTED(st) || (NULL == group->poller)) break;
|
||||
if (_MW_ABORTED(st) || (NULL == group->poller)) {
|
||||
break;
|
||||
}
|
||||
} while (PR_CLIST_IS_EMPTY(&group->io_ready));
|
||||
|
||||
/*
|
||||
|
|
@ -954,9 +992,10 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
if (_MW_ABORTED(st))
|
||||
{
|
||||
if ((NULL == group->poller
|
||||
|| !PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
&& group->waiting_threads > 1)
|
||||
|| !PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
&& group->waiting_threads > 1) {
|
||||
PR_NotifyCondVar(group->io_complete);
|
||||
}
|
||||
goto aborted;
|
||||
}
|
||||
|
||||
|
|
@ -966,13 +1005,15 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
** i/o ready, it has a higher priority. I want to
|
||||
** process the ready i/o first and wake up another
|
||||
** thread to be the new poller.
|
||||
*/
|
||||
*/
|
||||
if (NULL == group->poller)
|
||||
{
|
||||
if (PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
if (PR_CLIST_IS_EMPTY(&group->io_ready)) {
|
||||
continue;
|
||||
if (group->waiting_threads > 1)
|
||||
}
|
||||
if (group->waiting_threads > 1) {
|
||||
PR_NotifyCondVar(group->io_complete);
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_ASSERT(!PR_CLIST_IS_EMPTY(&group->io_ready));
|
||||
|
|
@ -1025,13 +1066,13 @@ failed_init:
|
|||
if (NULL != overlapped->data.mw.timer)
|
||||
{
|
||||
PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
|
||||
!= overlapped->data.mw.desc->timeout);
|
||||
!= overlapped->data.mw.desc->timeout);
|
||||
CancelTimer(overlapped->data.mw.timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
|
||||
== overlapped->data.mw.desc->timeout);
|
||||
== overlapped->data.mw.desc->timeout);
|
||||
}
|
||||
PR_DELETE(overlapped);
|
||||
#endif
|
||||
|
|
@ -1045,7 +1086,9 @@ PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *des
|
|||
PRRecvWait **recv_wait;
|
||||
#endif
|
||||
PRStatus rv = PR_SUCCESS;
|
||||
if (NULL == group) group = mw_state->group;
|
||||
if (NULL == group) {
|
||||
group = mw_state->group;
|
||||
}
|
||||
PR_ASSERT(NULL != group);
|
||||
if (NULL == group)
|
||||
{
|
||||
|
|
@ -1064,7 +1107,7 @@ PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *des
|
|||
|
||||
#ifdef WINNT
|
||||
if (InterlockedCompareExchange((LONG *)&desc->outcome,
|
||||
(LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) == (LONG)PR_MW_PENDING)
|
||||
(LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) == (LONG)PR_MW_PENDING)
|
||||
{
|
||||
PRFileDesc *bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom);
|
||||
|
|
@ -1097,7 +1140,9 @@ PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *des
|
|||
do
|
||||
{
|
||||
PRRecvWait *done = (PRRecvWait*)head;
|
||||
if (done == desc) goto unlock;
|
||||
if (done == desc) {
|
||||
goto unlock;
|
||||
}
|
||||
head = PR_NEXT_LINK(head);
|
||||
} while (head != &group->io_ready);
|
||||
}
|
||||
|
|
@ -1120,7 +1165,9 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
#endif
|
||||
|
||||
if (NULL == group) group = mw_state->group;
|
||||
if (NULL == group) {
|
||||
group = mw_state->group;
|
||||
}
|
||||
PR_ASSERT(NULL != group);
|
||||
if (NULL == group)
|
||||
{
|
||||
|
|
@ -1131,17 +1178,20 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
PR_Lock(group->ml);
|
||||
if (_prmw_stopped != group->state)
|
||||
{
|
||||
if (_prmw_running == group->state)
|
||||
group->state = _prmw_stopping; /* so nothing new comes in */
|
||||
if (0 == group->waiting_threads) /* is there anybody else? */
|
||||
group->state = _prmw_stopped; /* we can stop right now */
|
||||
if (_prmw_running == group->state) {
|
||||
group->state = _prmw_stopping; /* so nothing new comes in */
|
||||
}
|
||||
if (0 == group->waiting_threads) { /* is there anybody else? */
|
||||
group->state = _prmw_stopped; /* we can stop right now */
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_NotifyAllCondVar(group->new_business);
|
||||
PR_NotifyAllCondVar(group->io_complete);
|
||||
}
|
||||
while (_prmw_stopped != group->state)
|
||||
while (_prmw_stopped != group->state) {
|
||||
(void)PR_WaitCondVar(group->mw_manage, PR_INTERVAL_NO_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WINNT
|
||||
|
|
@ -1155,11 +1205,11 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
if (NULL != *desc)
|
||||
{
|
||||
if (InterlockedCompareExchange((LONG *)&(*desc)->outcome,
|
||||
(LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING)
|
||||
(LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING)
|
||||
== (LONG)PR_MW_PENDING)
|
||||
{
|
||||
PRFileDesc *bottom = PR_GetIdentitiesLayer(
|
||||
(*desc)->fd, PR_NSPR_IO_LAYER);
|
||||
(*desc)->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom);
|
||||
if (NULL == bottom)
|
||||
{
|
||||
|
|
@ -1173,7 +1223,7 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
|
||||
{
|
||||
fprintf(stderr, "closesocket failed: %d\n",
|
||||
WSAGetLastError());
|
||||
WSAGetLastError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1202,32 +1252,34 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
for (desc = &group->waiter->recv_wait; group->waiter->count > 0; ++desc)
|
||||
{
|
||||
PR_ASSERT(desc < &group->waiter->recv_wait + group->waiter->length);
|
||||
if (NULL != *desc)
|
||||
if (NULL != *desc) {
|
||||
_MW_DoneInternal(group, desc, PR_MW_INTERRUPT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* take first element of finished list and return it or NULL */
|
||||
if (PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
if (PR_CLIST_IS_EMPTY(&group->io_ready)) {
|
||||
PR_SetError(PR_GROUP_EMPTY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRCList *head = PR_LIST_HEAD(&group->io_ready);
|
||||
PR_REMOVE_AND_INIT_LINK(head);
|
||||
#ifdef WINNT
|
||||
overlapped = (_MDOverlapped *)
|
||||
((char *)head - offsetof(_MDOverlapped, data));
|
||||
((char *)head - offsetof(_MDOverlapped, data));
|
||||
head = &overlapped->data.mw.desc->internal;
|
||||
if (NULL != overlapped->data.mw.timer)
|
||||
{
|
||||
PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
|
||||
!= overlapped->data.mw.desc->timeout);
|
||||
!= overlapped->data.mw.desc->timeout);
|
||||
CancelTimer(overlapped->data.mw.timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
|
||||
== overlapped->data.mw.desc->timeout);
|
||||
== overlapped->data.mw.desc->timeout);
|
||||
}
|
||||
PR_DELETE(overlapped);
|
||||
#endif
|
||||
|
|
@ -1253,23 +1305,33 @@ PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */)
|
|||
}
|
||||
/* the wait group itself */
|
||||
wg->ml = PR_NewLock();
|
||||
if (NULL == wg->ml) goto failed_lock;
|
||||
if (NULL == wg->ml) {
|
||||
goto failed_lock;
|
||||
}
|
||||
wg->io_taken = PR_NewCondVar(wg->ml);
|
||||
if (NULL == wg->io_taken) goto failed_cvar0;
|
||||
if (NULL == wg->io_taken) {
|
||||
goto failed_cvar0;
|
||||
}
|
||||
wg->io_complete = PR_NewCondVar(wg->ml);
|
||||
if (NULL == wg->io_complete) goto failed_cvar1;
|
||||
if (NULL == wg->io_complete) {
|
||||
goto failed_cvar1;
|
||||
}
|
||||
wg->new_business = PR_NewCondVar(wg->ml);
|
||||
if (NULL == wg->new_business) goto failed_cvar2;
|
||||
if (NULL == wg->new_business) {
|
||||
goto failed_cvar2;
|
||||
}
|
||||
wg->mw_manage = PR_NewCondVar(wg->ml);
|
||||
if (NULL == wg->mw_manage) goto failed_cvar3;
|
||||
if (NULL == wg->mw_manage) {
|
||||
goto failed_cvar3;
|
||||
}
|
||||
|
||||
PR_INIT_CLIST(&wg->group_link);
|
||||
PR_INIT_CLIST(&wg->io_ready);
|
||||
|
||||
/* the waiters sequence */
|
||||
wg->waiter = (_PRWaiterHash*)PR_CALLOC(
|
||||
sizeof(_PRWaiterHash) +
|
||||
(_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*)));
|
||||
sizeof(_PRWaiterHash) +
|
||||
(_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*)));
|
||||
if (NULL == wg->waiter)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
|
|
@ -1309,14 +1371,16 @@ failed:
|
|||
PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
|
||||
{
|
||||
PRStatus rv = PR_SUCCESS;
|
||||
if (NULL == group) group = mw_state->group;
|
||||
if (NULL == group) {
|
||||
group = mw_state->group;
|
||||
}
|
||||
PR_ASSERT(NULL != group);
|
||||
if (NULL != group)
|
||||
{
|
||||
PR_Lock(group->ml);
|
||||
if ((group->waiting_threads == 0)
|
||||
&& (group->waiter->count == 0)
|
||||
&& PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
&& (group->waiter->count == 0)
|
||||
&& PR_CLIST_IS_EMPTY(&group->io_ready))
|
||||
{
|
||||
group->state = _prmw_stopped;
|
||||
}
|
||||
|
|
@ -1326,7 +1390,9 @@ PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
|
|||
rv = PR_FAILURE;
|
||||
}
|
||||
PR_Unlock(group->ml);
|
||||
if (PR_FAILURE == rv) return rv;
|
||||
if (PR_FAILURE == rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PR_Lock(mw_lock);
|
||||
PR_REMOVE_LINK(&group->group_link);
|
||||
|
|
@ -1347,7 +1413,9 @@ PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
|
|||
PR_DestroyCondVar(group->io_complete);
|
||||
PR_DestroyCondVar(group->io_taken);
|
||||
PR_DestroyLock(group->ml);
|
||||
if (group == mw_state->group) mw_state->group = NULL;
|
||||
if (group == mw_state->group) {
|
||||
mw_state->group = NULL;
|
||||
}
|
||||
PR_DELETE(group);
|
||||
}
|
||||
else
|
||||
|
|
@ -1368,7 +1436,9 @@ PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
|
|||
PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group)
|
||||
{
|
||||
PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator);
|
||||
if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
if (NULL == enumerator) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
enumerator->group = group;
|
||||
|
|
@ -1395,12 +1465,14 @@ PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup(
|
|||
PRMWaitEnumerator *enumerator, const PRRecvWait *previous)
|
||||
{
|
||||
PRRecvWait *result = NULL;
|
||||
|
||||
|
||||
/* entry point sanity checking */
|
||||
PR_ASSERT(NULL != enumerator);
|
||||
PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal);
|
||||
if ((NULL == enumerator)
|
||||
|| (_PR_ENUM_SEALED != enumerator->seal)) goto bad_argument;
|
||||
|| (_PR_ENUM_SEALED != enumerator->seal)) {
|
||||
goto bad_argument;
|
||||
}
|
||||
|
||||
/* beginning of enumeration */
|
||||
if (NULL == previous)
|
||||
|
|
@ -1424,11 +1496,14 @@ PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup(
|
|||
{
|
||||
PRThread *me = PR_GetCurrentThread();
|
||||
PR_ASSERT(me == enumerator->thread);
|
||||
if (me != enumerator->thread) goto bad_argument;
|
||||
if (me != enumerator->thread) {
|
||||
goto bad_argument;
|
||||
}
|
||||
|
||||
/* need to restart the enumeration */
|
||||
if (enumerator->p_timestamp != enumerator->group->p_timestamp)
|
||||
if (enumerator->p_timestamp != enumerator->group->p_timestamp) {
|
||||
return PR_EnumerateWaitGroup(enumerator, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* actually progress the enumeration */
|
||||
|
|
@ -1439,7 +1514,9 @@ PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup(
|
|||
#endif
|
||||
while (enumerator->index++ < enumerator->group->waiter->length)
|
||||
{
|
||||
if (NULL != (result = *(enumerator->waiter)++)) break;
|
||||
if (NULL != (result = *(enumerator->waiter)++)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(WINNT)
|
||||
_PR_MD_UNLOCK(&enumerator->group->mdlock);
|
||||
|
|
|
|||
|
|
@ -62,30 +62,30 @@ static PRIOMethods _pr_polevt_methods = {
|
|||
(PRSeek64FN)_PR_InvalidInt64,
|
||||
(PRFileInfoFN)_PR_InvalidStatus,
|
||||
(PRFileInfo64FN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
_pr_PolEvtPoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRConnectcontinueFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt
|
||||
};
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
|
|||
event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods);
|
||||
if (NULL == event) {
|
||||
goto errorExit;
|
||||
}
|
||||
}
|
||||
event->secret = PR_NEW(PRFilePrivate);
|
||||
if (event->secret == NULL) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
|
|
@ -147,9 +147,9 @@ PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
|
|||
fd[0] = fd[1] = NULL;
|
||||
goto errorExit;
|
||||
}
|
||||
/*
|
||||
* set the TCP_NODELAY option to reduce notification latency
|
||||
*/
|
||||
/*
|
||||
* set the TCP_NODELAY option to reduce notification latency
|
||||
*/
|
||||
socket_opt.option = PR_SockOpt_NoDelay;
|
||||
socket_opt.value.no_delay = PR_TRUE;
|
||||
rv = PR_SetSocketOption(fd[1], &socket_opt);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -30,7 +30,7 @@ typedef int (*_PRGetCharFN)(void *stream);
|
|||
/*
|
||||
* A function that pushes the character 'ch' back to 'stream'.
|
||||
*/
|
||||
typedef void (*_PRUngetCharFN)(void *stream, int ch);
|
||||
typedef void (*_PRUngetCharFN)(void *stream, int ch);
|
||||
|
||||
/*
|
||||
* The size specifier for the integer and floating point number
|
||||
|
|
@ -89,7 +89,7 @@ typedef struct {
|
|||
* 'str' is assumed to be a representation of the integer in
|
||||
* base 'base'.
|
||||
*
|
||||
* Warning:
|
||||
* Warning:
|
||||
* - Only handle base 8, 10, and 16.
|
||||
* - No overflow checking.
|
||||
*/
|
||||
|
|
@ -139,7 +139,7 @@ _pr_strtoull(const char *str, char **endptr, int base)
|
|||
cPtr += 2;
|
||||
} else {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_ASSERT(base != 0);
|
||||
LL_I2L(base64, base);
|
||||
|
|
@ -230,8 +230,8 @@ GetInt(ScanfState *state, int code)
|
|||
*p++ = ch;
|
||||
GET_IF_WITHIN_WIDTH(state, ch);
|
||||
if (WITHIN_WIDTH(state)
|
||||
&& (ch == 'x' || ch == 'X')
|
||||
&& (base == 0 || base == 16)) {
|
||||
&& (ch == 'x' || ch == 'X')
|
||||
&& (base == 0 || base == 16)) {
|
||||
base = 16;
|
||||
*p++ = ch;
|
||||
GET_IF_WITHIN_WIDTH(state, ch);
|
||||
|
|
@ -365,11 +365,7 @@ GetFloat(ScanfState *state)
|
|||
if (state->sizeSpec == _PR_size_l) {
|
||||
*va_arg(state->ap, PRFloat64 *) = dval;
|
||||
} else if (state->sizeSpec == _PR_size_L) {
|
||||
#if defined(OSF1) || defined(IRIX)
|
||||
*va_arg(state->ap, double *) = dval;
|
||||
#else
|
||||
*va_arg(state->ap, long double *) = dval;
|
||||
#endif
|
||||
} else {
|
||||
*va_arg(state->ap, float *) = (float) dval;
|
||||
}
|
||||
|
|
@ -482,45 +478,45 @@ Convert(ScanfState *state, const char *fmt)
|
|||
}
|
||||
break;
|
||||
case '[':
|
||||
{
|
||||
PRBool complement = PR_FALSE;
|
||||
const char *closeBracket;
|
||||
size_t n;
|
||||
{
|
||||
PRBool complement = PR_FALSE;
|
||||
const char *closeBracket;
|
||||
size_t n;
|
||||
|
||||
if (*++cPtr == '^') {
|
||||
complement = PR_TRUE;
|
||||
cPtr++;
|
||||
}
|
||||
closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');
|
||||
if (closeBracket == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
n = closeBracket - cPtr;
|
||||
if (state->width == 0) {
|
||||
state->width = INT_MAX;
|
||||
}
|
||||
if (state->assign) {
|
||||
cArg = va_arg(state->ap, char *);
|
||||
}
|
||||
for (; state->width > 0; state->width--) {
|
||||
ch = GET(state);
|
||||
if ((ch == EOF)
|
||||
|| (!complement && !memchr(cPtr, ch, n))
|
||||
|| (complement && memchr(cPtr, ch, n))) {
|
||||
UNGET(state, ch);
|
||||
break;
|
||||
}
|
||||
if (state->assign) {
|
||||
*cArg++ = ch;
|
||||
}
|
||||
}
|
||||
if (state->assign) {
|
||||
*cArg = '\0';
|
||||
state->converted = PR_TRUE;
|
||||
}
|
||||
cPtr = closeBracket;
|
||||
if (*++cPtr == '^') {
|
||||
complement = PR_TRUE;
|
||||
cPtr++;
|
||||
}
|
||||
break;
|
||||
closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');
|
||||
if (closeBracket == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
n = closeBracket - cPtr;
|
||||
if (state->width == 0) {
|
||||
state->width = INT_MAX;
|
||||
}
|
||||
if (state->assign) {
|
||||
cArg = va_arg(state->ap, char *);
|
||||
}
|
||||
for (; state->width > 0; state->width--) {
|
||||
ch = GET(state);
|
||||
if ((ch == EOF)
|
||||
|| (!complement && !memchr(cPtr, ch, n))
|
||||
|| (complement && memchr(cPtr, ch, n))) {
|
||||
UNGET(state, ch);
|
||||
break;
|
||||
}
|
||||
if (state->assign) {
|
||||
*cArg++ = ch;
|
||||
}
|
||||
}
|
||||
if (state->assign) {
|
||||
*cArg = '\0';
|
||||
state->converted = PR_TRUE;
|
||||
}
|
||||
cPtr = closeBracket;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -17,7 +17,7 @@
|
|||
** in cyclic dependency of initialization.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
|
||||
union memBlkHdrUn;
|
||||
|
||||
|
|
@ -55,12 +55,13 @@ static void pr_ZoneFree(void *ptr);
|
|||
|
||||
void
|
||||
_PR_DestroyZones(void)
|
||||
{
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!use_zone_allocator)
|
||||
if (!use_zone_allocator) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
for (j = 0; j < THREAD_POOLS; j++) {
|
||||
for (i = 0; i < MEM_ZONES; i++) {
|
||||
MemoryZone *mz = &zones[i][j];
|
||||
|
|
@ -72,9 +73,9 @@ _PR_DestroyZones(void)
|
|||
mz->elements--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
use_zone_allocator = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** pr_FindSymbolInProg
|
||||
|
|
@ -96,8 +97,9 @@ pr_FindSymbolInProg(const char *name)
|
|||
void *sym;
|
||||
|
||||
h = dlopen(0, RTLD_LAZY);
|
||||
if (h == NULL)
|
||||
if (h == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sym = dlsym(h, name);
|
||||
(void)dlclose(h);
|
||||
return sym;
|
||||
|
|
@ -113,8 +115,9 @@ pr_FindSymbolInProg(const char *name)
|
|||
shl_t h = NULL;
|
||||
void *sym;
|
||||
|
||||
if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1)
|
||||
if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
|
|
@ -157,17 +160,18 @@ _PR_InitZones(void)
|
|||
use_zone_allocator = (atoi(envp) == 1);
|
||||
}
|
||||
|
||||
if (!use_zone_allocator)
|
||||
if (!use_zone_allocator) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0; j < THREAD_POOLS; j++) {
|
||||
for (j = 0; j < THREAD_POOLS; j++) {
|
||||
for (i = 0; i < MEM_ZONES; i++) {
|
||||
MemoryZone *mz = &zones[i][j];
|
||||
int rv = pthread_mutex_init(&mz->lock, NULL);
|
||||
PR_ASSERT(0 == rv);
|
||||
if (rv != 0) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
mz->blockSize = 16 << ( 2 * i);
|
||||
}
|
||||
}
|
||||
|
|
@ -189,11 +193,11 @@ PR_FPrintZoneStats(PRFileDesc *debug_out)
|
|||
MemoryZone zone = *mz;
|
||||
if (zone.elements || zone.misses || zone.hits) {
|
||||
PR_fprintf(debug_out,
|
||||
"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n",
|
||||
j, i, zone.blockSize, zone.elements,
|
||||
zone.hits, zone.misses, zone.contention);
|
||||
"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n",
|
||||
j, i, zone.blockSize, zone.elements,
|
||||
zone.hits, zone.misses, zone.contention);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,8 +227,9 @@ pr_ZoneMalloc(PRUint32 size)
|
|||
wasLocked = mz->locked;
|
||||
pthread_mutex_lock(&mz->lock);
|
||||
mz->locked = 1;
|
||||
if (wasLocked)
|
||||
if (wasLocked) {
|
||||
mz->contention++;
|
||||
}
|
||||
if (mz->head) {
|
||||
mb = mz->head;
|
||||
PR_ASSERT(mb->s.magic == ZONE_MAGIC);
|
||||
|
|
@ -312,15 +317,16 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
|
|||
int ours;
|
||||
MemBlockHdr phony;
|
||||
|
||||
if (!oldptr)
|
||||
if (!oldptr) {
|
||||
return pr_ZoneMalloc(bytes);
|
||||
}
|
||||
mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb));
|
||||
if (mb->s.magic != ZONE_MAGIC) {
|
||||
/* Maybe this just came from ordinary malloc */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Warning: reallocing memory block %p from ordinary malloc\n",
|
||||
oldptr);
|
||||
"Warning: reallocing memory block %p from ordinary malloc\n",
|
||||
oldptr);
|
||||
#endif
|
||||
/*
|
||||
* We are going to realloc oldptr. If realloc succeeds, the
|
||||
|
|
@ -358,7 +364,7 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
|
|||
PR_ASSERT(mt->s.magic == ZONE_MAGIC);
|
||||
PR_ASSERT(mt->s.zone == mb->s.zone);
|
||||
PR_ASSERT(mt->s.blockSize == blockSize);
|
||||
|
||||
|
||||
if (bytes <= blockSize) {
|
||||
/* The block is already big enough. */
|
||||
mt->s.requestedSize = mb->s.requestedSize = bytes;
|
||||
|
|
@ -370,13 +376,16 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
|
|||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldptr && mb->s.requestedSize)
|
||||
|
||||
if (oldptr && mb->s.requestedSize) {
|
||||
memcpy(rv, oldptr, mb->s.requestedSize);
|
||||
if (ours)
|
||||
}
|
||||
if (ours) {
|
||||
pr_ZoneFree(oldptr);
|
||||
else if (oldptr)
|
||||
}
|
||||
else if (oldptr) {
|
||||
free(oldptr);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -388,8 +397,9 @@ pr_ZoneFree(void *ptr)
|
|||
size_t blockSize;
|
||||
PRUint32 wasLocked;
|
||||
|
||||
if (!ptr)
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb));
|
||||
|
||||
|
|
@ -397,7 +407,7 @@ pr_ZoneFree(void *ptr)
|
|||
/* maybe this came from ordinary malloc */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Warning: freeing memory block %p from ordinary malloc\n", ptr);
|
||||
"Warning: freeing memory block %p from ordinary malloc\n", ptr);
|
||||
#endif
|
||||
free(ptr);
|
||||
return;
|
||||
|
|
@ -419,8 +429,9 @@ pr_ZoneFree(void *ptr)
|
|||
wasLocked = mz->locked;
|
||||
pthread_mutex_lock(&mz->lock);
|
||||
mz->locked = 1;
|
||||
if (wasLocked)
|
||||
if (wasLocked) {
|
||||
mz->contention++;
|
||||
}
|
||||
mt->s.next = mb->s.next = mz->head; /* put on head of list */
|
||||
mz->head = mb;
|
||||
mz->elements++;
|
||||
|
|
@ -430,32 +441,40 @@ pr_ZoneFree(void *ptr)
|
|||
|
||||
PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)
|
||||
{
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
|
||||
{
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
return use_zone_allocator ?
|
||||
pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);
|
||||
pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)
|
||||
{
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
|
||||
return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void) PR_Free(void *ptr)
|
||||
{
|
||||
if (use_zone_allocator)
|
||||
if (use_zone_allocator) {
|
||||
pr_ZoneFree(ptr);
|
||||
else
|
||||
}
|
||||
else {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !defined(_PR_ZONE_ALLOCATOR) */
|
||||
|
|
@ -481,7 +500,7 @@ PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
|
|||
{
|
||||
#if defined (WIN16)
|
||||
return PR_MD_calloc( (size_t)nelem, (size_t)elsize );
|
||||
|
||||
|
||||
#else
|
||||
return calloc(nelem, elsize);
|
||||
#endif
|
||||
|
|
@ -519,7 +538,7 @@ PR_IMPLEMENT(void) PR_Free(void *ptr)
|
|||
** PR_AttachThread has been called (on a native thread that nspr has yet
|
||||
** to be told about) we could get royally screwed if the lock was busy
|
||||
** and we tried to context switch the thread away. In this scenario
|
||||
** PR_CURRENT_THREAD() == NULL
|
||||
** PR_CURRENT_THREAD() == NULL
|
||||
**
|
||||
** To avoid this unfortunate case, we use the low level locking
|
||||
** facilities for malloc protection instead of the slightly higher level
|
||||
|
|
@ -540,80 +559,61 @@ static PRBool _PR_malloc_initialised = PR_FALSE;
|
|||
#ifdef _PR_PTHREADS
|
||||
static pthread_mutex_t _PR_MD_malloc_crustylock;
|
||||
|
||||
#define _PR_Lock_Malloc() { \
|
||||
if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
PRStatus rv; \
|
||||
rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \
|
||||
PR_ASSERT(0 == rv); \
|
||||
}
|
||||
#define _PR_Lock_Malloc() { \
|
||||
if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
PRStatus rv; \
|
||||
rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \
|
||||
PR_ASSERT(0 == rv); \
|
||||
}
|
||||
|
||||
#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
PRStatus rv; \
|
||||
rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \
|
||||
PR_ASSERT(0 == rv); \
|
||||
} \
|
||||
}
|
||||
#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
PRStatus rv; \
|
||||
rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \
|
||||
PR_ASSERT(0 == rv); \
|
||||
} \
|
||||
}
|
||||
#else /* _PR_PTHREADS */
|
||||
static _MDLock _PR_MD_malloc_crustylock;
|
||||
|
||||
#ifdef IRIX
|
||||
#define _PR_Lock_Malloc() { \
|
||||
PRIntn _is; \
|
||||
if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
if (_PR_MD_GET_ATTACHED_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_GET_ATTACHED_THREAD())) \
|
||||
_PR_INTSOFF(_is); \
|
||||
_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
|
||||
}
|
||||
#define _PR_Lock_Malloc() { \
|
||||
PRIntn _is; \
|
||||
if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
if (_PR_MD_CURRENT_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_CURRENT_THREAD())) \
|
||||
_PR_INTSOFF(_is); \
|
||||
_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
|
||||
}
|
||||
|
||||
#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
|
||||
if (_PR_MD_GET_ATTACHED_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_GET_ATTACHED_THREAD())) \
|
||||
_PR_INTSON(_is); \
|
||||
} \
|
||||
}
|
||||
#else /* IRIX */
|
||||
#define _PR_Lock_Malloc() { \
|
||||
PRIntn _is; \
|
||||
if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
if (_PR_MD_CURRENT_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_CURRENT_THREAD())) \
|
||||
_PR_INTSOFF(_is); \
|
||||
_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
|
||||
}
|
||||
|
||||
#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
|
||||
if (_PR_MD_CURRENT_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_CURRENT_THREAD())) \
|
||||
_PR_INTSON(_is); \
|
||||
} \
|
||||
}
|
||||
#endif /* IRIX */
|
||||
#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \
|
||||
_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
|
||||
if (_PR_MD_CURRENT_THREAD() && \
|
||||
!_PR_IS_NATIVE_THREAD( \
|
||||
_PR_MD_CURRENT_THREAD())) \
|
||||
_PR_INTSON(_is); \
|
||||
} \
|
||||
}
|
||||
#endif /* _PR_PTHREADS */
|
||||
|
||||
PR_IMPLEMENT(PRStatus) _PR_MallocInit(void)
|
||||
{
|
||||
PRStatus rv = PR_SUCCESS;
|
||||
|
||||
if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS;
|
||||
if( PR_TRUE == _PR_malloc_initialised ) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef _PR_PTHREADS
|
||||
{
|
||||
int status;
|
||||
pthread_mutexattr_t mattr;
|
||||
int status;
|
||||
pthread_mutexattr_t mattr;
|
||||
|
||||
status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr);
|
||||
PR_ASSERT(0 == status);
|
||||
}
|
||||
#else /* _PR_PTHREADS */
|
||||
_MD_NEW_LOCK(&_PR_MD_malloc_crustylock);
|
||||
|
|
@ -636,22 +636,6 @@ void *malloc(size_t size)
|
|||
return p;
|
||||
}
|
||||
|
||||
#if defined(IRIX)
|
||||
void *memalign(size_t alignment, size_t size)
|
||||
{
|
||||
void *p;
|
||||
_PR_Lock_Malloc();
|
||||
p = _PR_UnlockedMemalign(alignment, size);
|
||||
_PR_Unlock_Malloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
void *valloc(size_t size)
|
||||
{
|
||||
return(memalign(sysconf(_SC_PAGESIZE),size));
|
||||
}
|
||||
#endif /* IRIX */
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
_PR_Lock_Malloc();
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
MOD_DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(MOD_DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(srcdir)/bsrcs.mk
|
||||
CSRCS += $(MDCSRCS)
|
||||
|
||||
TARGETS = $(OBJS)
|
||||
|
||||
INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
|
||||
|
||||
DEFINES += -D_NSPR_BUILD_
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
export:: $(TARGETS)
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INIT_CPUS();
|
||||
PR_EXTERN(void) _PR_MD_WAKEUP_CPUS();
|
||||
PR_EXTERN(void) _PR_MD_START_INTERRUPTS(void);
|
||||
PR_EXTERN(void) _PR_MD_STOP_INTERRUPTS(void);
|
||||
PR_EXTERN(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
|
||||
PR_EXTERN(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
|
||||
PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
|
||||
PR_EXTERN(void) _PR_MD_CLOCK_INTERRUPT(void);
|
||||
PR_EXTERN(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
|
||||
PR_EXTERN(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
|
||||
PR_EXTERN(PRInt32) _PR_MD_GET_INTSOFF(void);
|
||||
PR_EXTERN(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
|
||||
PR_EXTERN(_PRCPU*) _PR_MD_CURRENT_CPU(void);
|
||||
PR_EXTERN(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
|
||||
PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
|
||||
PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
|
||||
* PRInt32* pointer to a _PRSockLen_t* pointer.
|
||||
*/
|
||||
#define _PRSockLen_t int
|
||||
|
||||
/*
|
||||
** Global lock variable used to bracket calls into rusty libraries that
|
||||
** aren't thread safe (like libc, libX, etc).
|
||||
*/
|
||||
static PRLock *_pr_rename_lock = NULL;
|
||||
static PRMonitor *_pr_Xfe_mon = NULL;
|
||||
|
||||
/*
|
||||
* Variables used by the GC code, initialized in _MD_InitSegs().
|
||||
* _pr_zero_fd should be a static variable. Unfortunately, there is
|
||||
* still some Unix-specific code left in function PR_GrowSegment()
|
||||
* in file memory/prseg.c that references it, so it needs
|
||||
* to be a global variable for now.
|
||||
*/
|
||||
PRInt32 _pr_zero_fd = -1;
|
||||
static PRLock *_pr_md_lock = NULL;
|
||||
|
||||
sigset_t timer_set;
|
||||
|
||||
void _PR_UnixInit()
|
||||
{
|
||||
struct sigaction sigact;
|
||||
int rv;
|
||||
|
||||
sigemptyset(&timer_set);
|
||||
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
rv = sigaction(SIGPIPE, &sigact, 0);
|
||||
PR_ASSERT(0 == rv);
|
||||
|
||||
_pr_rename_lock = PR_NewLock();
|
||||
PR_ASSERT(NULL != _pr_rename_lock);
|
||||
_pr_Xfe_mon = PR_NewMonitor();
|
||||
PR_ASSERT(NULL != _pr_Xfe_mon);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
*
|
||||
* PR_Now --
|
||||
*
|
||||
* Returns the current time in microseconds since the epoch.
|
||||
* The epoch is midnight January 1, 1970 GMT.
|
||||
* The implementation is machine dependent. This is the Unix
|
||||
* implementation.
|
||||
* Cf. time_t time(time_t *tp)
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
PR_IMPLEMENT(PRTime)
|
||||
PR_Now(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
PRInt64 s, us, s2us;
|
||||
|
||||
GETTIMEOFDAY(&tv);
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_I2L(s, tv.tv_sec);
|
||||
LL_I2L(us, tv.tv_usec);
|
||||
LL_MUL(s, s, s2us);
|
||||
LL_ADD(s, s, us);
|
||||
return s;
|
||||
}
|
||||
|
||||
PRIntervalTime
|
||||
_PR_UNIX_GetInterval()
|
||||
{
|
||||
struct timeval time;
|
||||
PRIntervalTime ticks;
|
||||
|
||||
(void)GETTIMEOFDAY(&time); /* fallicy of course */
|
||||
ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */
|
||||
ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */
|
||||
return ticks;
|
||||
} /* _PR_SUNOS_GetInterval */
|
||||
|
||||
PRIntervalTime _PR_UNIX_TicksPerSecond()
|
||||
{
|
||||
return 1000; /* this needs some work :) */
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
|
||||
** safe. Unfortunately, neither is mozilla. To make these programs work
|
||||
** in a pre-emptive threaded environment, we need to use a lock.
|
||||
*/
|
||||
|
||||
void PR_XLock()
|
||||
{
|
||||
PR_EnterMonitor(_pr_Xfe_mon);
|
||||
}
|
||||
|
||||
void PR_XUnlock()
|
||||
{
|
||||
PR_ExitMonitor(_pr_Xfe_mon);
|
||||
}
|
||||
|
||||
PRBool PR_XIsLocked()
|
||||
{
|
||||
return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
void PR_XWait(int ms)
|
||||
{
|
||||
PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
|
||||
}
|
||||
|
||||
void PR_XNotify(void)
|
||||
{
|
||||
PR_Notify(_pr_Xfe_mon);
|
||||
}
|
||||
|
||||
void PR_XNotifyAll(void)
|
||||
{
|
||||
PR_NotifyAll(_pr_Xfe_mon);
|
||||
}
|
||||
|
||||
#if !defined(BEOS)
|
||||
#ifdef HAVE_BSD_FLOCK
|
||||
|
||||
#include <sys/file.h>
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_LOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = flock(f, LOCK_EX);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_TLOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = flock(f, LOCK_EX|LOCK_NB);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_UNLOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = flock(f, LOCK_UN);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#else
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_LOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = lockf(f, F_LOCK, 0);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_TLOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = lockf(f, F_TLOCK, 0);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_UNLOCKFILE (PRInt32 f)
|
||||
{
|
||||
PRInt32 rv;
|
||||
rv = lockf(f, F_ULOCK, 0);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_GETHOSTNAME (char *name, PRUint32 namelen)
|
||||
{
|
||||
PRIntn rv;
|
||||
|
||||
rv = gethostname(name, namelen);
|
||||
if (0 == rv) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
_PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,873 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
** Global lock variable used to bracket calls into rusty libraries that
|
||||
** aren't thread safe (like libc, libX, etc).
|
||||
*/
|
||||
static PRLock *_pr_rename_lock = NULL;
|
||||
|
||||
void
|
||||
_MD_InitIO (void)
|
||||
{
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_open_dir (_MDDir *md,const char *name)
|
||||
{
|
||||
int err;
|
||||
|
||||
md->d = opendir(name);
|
||||
if (!md->d) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_OPENDIR_ERROR(err);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
char*
|
||||
_MD_read_dir (_MDDir *md, PRIntn flags)
|
||||
{
|
||||
struct dirent *de;
|
||||
int err;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* XXX: readdir() is not MT-safe
|
||||
*/
|
||||
_MD_ERRNO() = 0;
|
||||
de = readdir(md->d);
|
||||
|
||||
if (!de) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_READDIR_ERROR(err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((flags & PR_SKIP_DOT) &&
|
||||
(de->d_name[0] == '.') && (de->d_name[1] == 0))
|
||||
continue;
|
||||
|
||||
if ((flags & PR_SKIP_DOT_DOT) &&
|
||||
(de->d_name[0] == '.') && (de->d_name[1] == '.') &&
|
||||
(de->d_name[2] == 0))
|
||||
continue;
|
||||
|
||||
if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.'))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
return de->d_name;
|
||||
}
|
||||
|
||||
|
||||
PRInt32
|
||||
_MD_close_dir (_MDDir *md)
|
||||
{
|
||||
int rv = 0, err;
|
||||
|
||||
if (md->d) {
|
||||
rv = closedir(md->d);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_CLOSEDIR_ERROR(err);
|
||||
}
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
void
|
||||
_MD_make_nonblock (PRFileDesc *fd)
|
||||
{
|
||||
int blocking = 1;
|
||||
setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking));
|
||||
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
|
||||
if (-1 == rv) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported)
|
||||
{
|
||||
if (imported) {
|
||||
fd->secret->inheritable = _PR_TRI_UNKNOWN;
|
||||
} else {
|
||||
int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
|
||||
if (flags == -1) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
|
||||
return;
|
||||
}
|
||||
fd->secret->inheritable = (flags & FD_CLOEXEC) ?
|
||||
_PR_TRI_TRUE : _PR_TRI_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_MD_query_fd_inheritable (PRFileDesc *fd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
|
||||
flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
|
||||
PR_ASSERT(-1 != flags);
|
||||
fd->secret->inheritable = (flags & FD_CLOEXEC) ?
|
||||
_PR_TRI_FALSE : _PR_TRI_TRUE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_open (const char *name, PRIntn flags, PRIntn mode)
|
||||
{
|
||||
PRInt32 osflags;
|
||||
PRInt32 rv, err;
|
||||
|
||||
if (flags & PR_RDWR) {
|
||||
osflags = O_RDWR;
|
||||
} else if (flags & PR_WRONLY) {
|
||||
osflags = O_WRONLY;
|
||||
} else {
|
||||
osflags = O_RDONLY;
|
||||
}
|
||||
|
||||
if (flags & PR_EXCL)
|
||||
osflags |= O_EXCL;
|
||||
if (flags & PR_APPEND)
|
||||
osflags |= O_APPEND;
|
||||
if (flags & PR_TRUNCATE)
|
||||
osflags |= O_TRUNC;
|
||||
if (flags & PR_SYNC) {
|
||||
/* Ummmm. BeOS doesn't appear to
|
||||
support sync in any way shape or
|
||||
form. */
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
** On creations we hold the 'create' lock in order to enforce
|
||||
** the semantics of PR_Rename. (see the latter for more details)
|
||||
*/
|
||||
if (flags & PR_CREATE_FILE)
|
||||
{
|
||||
osflags |= O_CREAT ;
|
||||
if (NULL !=_pr_rename_lock)
|
||||
PR_Lock(_pr_rename_lock);
|
||||
}
|
||||
|
||||
rv = open(name, osflags, mode);
|
||||
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_OPEN_ERROR(err);
|
||||
}
|
||||
|
||||
if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
|
||||
PR_Unlock(_pr_rename_lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_close_file (PRInt32 osfd)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = close(osfd);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_CLOSE_ERROR(err);
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
||||
rv = read( osfd, buf, amount );
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_READ_ERROR(err);
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
||||
rv = write( osfd, buf, amount );
|
||||
|
||||
if( rv < 0 ) {
|
||||
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_WRITE_ERROR(err);
|
||||
}
|
||||
return( rv );
|
||||
}
|
||||
|
||||
#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */
|
||||
PRInt32
|
||||
_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32
|
||||
_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = lseek (fd->secret->md.osfd, offset, whence);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_LSEEK_ERROR(err);
|
||||
}
|
||||
return( rv );
|
||||
}
|
||||
|
||||
PRInt64
|
||||
_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
/* According to the BeOS headers, lseek accepts a
|
||||
* variable of type off_t for the offset, and off_t
|
||||
* is defined to be a 64-bit value. So no special
|
||||
* cracking needs to be done on "offset".
|
||||
*/
|
||||
|
||||
rv = lseek (fd->secret->md.osfd, offset, whence);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_LSEEK_ERROR(err);
|
||||
}
|
||||
return( rv );
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_fsync (PRFileDesc *fd)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = fsync(fd->secret->md.osfd);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_FSYNC_ERROR(err);
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_delete (const char *name)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = unlink(name);
|
||||
if (rv == -1)
|
||||
{
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_UNLINK_ERROR(err);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_getfileinfo (const char *fn, PRFileInfo *info)
|
||||
{
|
||||
struct stat sb;
|
||||
PRInt32 rv, err;
|
||||
PRInt64 s, s2us;
|
||||
|
||||
rv = stat(fn, &sb);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_STAT_ERROR(err);
|
||||
} else if (info) {
|
||||
if (S_IFREG & sb.st_mode)
|
||||
info->type = PR_FILE_FILE;
|
||||
else if (S_IFDIR & sb.st_mode)
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
info->type = PR_FILE_OTHER;
|
||||
|
||||
/* Must truncate file size for the 32 bit
|
||||
version */
|
||||
info->size = (sb.st_size & 0xffffffff);
|
||||
LL_I2L(s, sb.st_mtime);
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->modifyTime = s;
|
||||
LL_I2L(s, sb.st_ctime);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->creationTime = s;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info)
|
||||
{
|
||||
struct stat sb;
|
||||
PRInt32 rv, err;
|
||||
PRInt64 s, s2us;
|
||||
|
||||
rv = stat(fn, &sb);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_STAT_ERROR(err);
|
||||
} else if (info) {
|
||||
if (S_IFREG & sb.st_mode)
|
||||
info->type = PR_FILE_FILE;
|
||||
else if (S_IFDIR & sb.st_mode)
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
info->type = PR_FILE_OTHER;
|
||||
|
||||
/* For the 64 bit version we can use
|
||||
* the native st_size without modification
|
||||
*/
|
||||
info->size = sb.st_size;
|
||||
LL_I2L(s, sb.st_mtime);
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->modifyTime = s;
|
||||
LL_I2L(s, sb.st_ctime);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->creationTime = s;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info)
|
||||
{
|
||||
struct stat sb;
|
||||
PRInt64 s, s2us;
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = fstat(fd->secret->md.osfd, &sb);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_FSTAT_ERROR(err);
|
||||
} else if (info) {
|
||||
if (info) {
|
||||
if (S_IFREG & sb.st_mode)
|
||||
info->type = PR_FILE_FILE ;
|
||||
else if (S_IFDIR & sb.st_mode)
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
info->type = PR_FILE_OTHER;
|
||||
/* Use lower 32 bits of file size */
|
||||
info->size = ( sb.st_size & 0xffffffff);
|
||||
LL_I2L(s, sb.st_mtime);
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->modifyTime = s;
|
||||
LL_I2L(s, sb.st_ctime);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->creationTime = s;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info)
|
||||
{
|
||||
struct stat sb;
|
||||
PRInt64 s, s2us;
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = fstat(fd->secret->md.osfd, &sb);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_FSTAT_ERROR(err);
|
||||
} else if (info) {
|
||||
if (info) {
|
||||
if (S_IFREG & sb.st_mode)
|
||||
info->type = PR_FILE_FILE ;
|
||||
else if (S_IFDIR & sb.st_mode)
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
info->type = PR_FILE_OTHER;
|
||||
info->size = sb.st_size;
|
||||
LL_I2L(s, sb.st_mtime);
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->modifyTime = s;
|
||||
LL_I2L(s, sb.st_ctime);
|
||||
LL_MUL(s, s, s2us);
|
||||
info->creationTime = s;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_rename (const char *from, const char *to)
|
||||
{
|
||||
PRInt32 rv = -1, err;
|
||||
|
||||
/*
|
||||
** This is trying to enforce the semantics of WINDOZE' rename
|
||||
** operation. That means one is not allowed to rename over top
|
||||
** of an existing file. Holding a lock across these two function
|
||||
** and the open function is known to be a bad idea, but ....
|
||||
*/
|
||||
if (NULL != _pr_rename_lock)
|
||||
PR_Lock(_pr_rename_lock);
|
||||
if (0 == access(to, F_OK))
|
||||
PR_SetError(PR_FILE_EXISTS_ERROR, 0);
|
||||
else
|
||||
{
|
||||
rv = rename(from, to);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_RENAME_ERROR(err);
|
||||
}
|
||||
}
|
||||
if (NULL != _pr_rename_lock)
|
||||
PR_Unlock(_pr_rename_lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_access (const char *name, PRIntn how)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
int checkFlags;
|
||||
struct stat buf;
|
||||
|
||||
switch (how) {
|
||||
case PR_ACCESS_WRITE_OK:
|
||||
checkFlags = S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
break;
|
||||
|
||||
case PR_ACCESS_READ_OK:
|
||||
checkFlags = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
break;
|
||||
|
||||
case PR_ACCESS_EXISTS:
|
||||
/* we don't need to examine st_mode. */
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = stat(name, &buf);
|
||||
if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) {
|
||||
PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_STAT_ERROR(err);
|
||||
}
|
||||
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_stat (const char *name, struct stat *buf)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_mkdir (const char *name, PRIntn mode)
|
||||
{
|
||||
status_t rv;
|
||||
int err;
|
||||
|
||||
/*
|
||||
** This lock is used to enforce rename semantics as described
|
||||
** in PR_Rename. Look there for more fun details.
|
||||
*/
|
||||
if (NULL !=_pr_rename_lock)
|
||||
PR_Lock(_pr_rename_lock);
|
||||
|
||||
rv = mkdir(name, mode);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_MKDIR_ERROR(err);
|
||||
}
|
||||
if (NULL !=_pr_rename_lock)
|
||||
PR_Unlock(_pr_rename_lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_rmdir (const char *name)
|
||||
{
|
||||
int rv, err;
|
||||
|
||||
rv = rmdir(name);
|
||||
if (rv == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_RMDIR_ERROR(err);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv = 0;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
/*
|
||||
* This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
|
||||
*/
|
||||
fd_set rd, wt, ex;
|
||||
PRFileDesc *bottom;
|
||||
PRPollDesc *pd, *epd;
|
||||
PRInt32 maxfd = -1, ready, err;
|
||||
PRIntervalTime remaining, elapsed, start;
|
||||
|
||||
struct timeval tv, *tvp = NULL;
|
||||
|
||||
if (_PR_PENDING_INTERRUPT(me))
|
||||
{
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == npds) {
|
||||
PR_Sleep(timeout);
|
||||
return rv;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wt);
|
||||
FD_ZERO(&ex);
|
||||
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
{
|
||||
PRInt16 in_flags_read = 0, in_flags_write = 0;
|
||||
PRInt16 out_flags_read = 0, out_flags_write = 0;
|
||||
|
||||
if ((NULL != pd->fd) && (0 != pd->in_flags))
|
||||
{
|
||||
if (pd->in_flags & PR_POLL_READ)
|
||||
{
|
||||
in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_WRITE)
|
||||
{
|
||||
in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
|
||||
}
|
||||
if ((0 != (in_flags_read & out_flags_read))
|
||||
|| (0 != (in_flags_write & out_flags_write)))
|
||||
{
|
||||
/* this one's ready right now */
|
||||
if (0 == ready)
|
||||
{
|
||||
/*
|
||||
* We will have to return without calling the
|
||||
* system poll/select function. So zero the
|
||||
* out_flags fields of all the poll descriptors
|
||||
* before this one.
|
||||
*/
|
||||
PRPollDesc *prev;
|
||||
for (prev = pds; prev < pd; prev++)
|
||||
{
|
||||
prev->out_flags = 0;
|
||||
}
|
||||
}
|
||||
ready += 1;
|
||||
pd->out_flags = out_flags_read | out_flags_write;
|
||||
}
|
||||
else
|
||||
{
|
||||
pd->out_flags = 0; /* pre-condition */
|
||||
|
||||
/* make sure this is an NSPR supported stack */
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom); /* what to do about that? */
|
||||
if ((NULL != bottom)
|
||||
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
|
||||
{
|
||||
if (0 == ready)
|
||||
{
|
||||
PRInt32 osfd = bottom->secret->md.osfd;
|
||||
if (osfd > maxfd) maxfd = osfd;
|
||||
if (in_flags_read & PR_POLL_READ)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_READ_SYS_READ;
|
||||
FD_SET(osfd, &rd);
|
||||
}
|
||||
if (in_flags_read & PR_POLL_WRITE)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
|
||||
FD_SET(osfd, &wt);
|
||||
}
|
||||
if (in_flags_write & PR_POLL_READ)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
|
||||
FD_SET(osfd, &rd);
|
||||
}
|
||||
if (in_flags_write & PR_POLL_WRITE)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
|
||||
FD_SET(osfd, &wt);
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 == ready)
|
||||
{
|
||||
PRPollDesc *prev;
|
||||
for (prev = pds; prev < pd; prev++)
|
||||
{
|
||||
prev->out_flags = 0;
|
||||
}
|
||||
}
|
||||
ready += 1; /* this will cause an abrupt return */
|
||||
pd->out_flags = PR_POLL_NVAL; /* bogii */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pd->out_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != ready) return ready; /* no need to block */
|
||||
|
||||
remaining = timeout;
|
||||
start = PR_IntervalNow();
|
||||
|
||||
retry:
|
||||
if (timeout != PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
PRInt32 ticksPerSecond = PR_TicksPerSecond();
|
||||
tv.tv_sec = remaining / ticksPerSecond;
|
||||
tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
|
||||
|
||||
if (ready == -1 && errno == EINTR)
|
||||
{
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
|
||||
else
|
||||
{
|
||||
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
|
||||
if (elapsed > timeout) ready = 0; /* timed out */
|
||||
else
|
||||
{
|
||||
remaining = timeout - elapsed;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Now to unravel the select sets back into the client's poll
|
||||
** descriptor list. Is this possibly an area for pissing away
|
||||
** a few cycles or what?
|
||||
*/
|
||||
if (ready > 0)
|
||||
{
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
{
|
||||
PRInt16 out_flags = 0;
|
||||
if ((NULL != pd->fd) && (0 != pd->in_flags))
|
||||
{
|
||||
PRInt32 osfd;
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom);
|
||||
|
||||
osfd = bottom->secret->md.osfd;
|
||||
|
||||
if (FD_ISSET(osfd, &rd))
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_READ)
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (FD_ISSET(osfd, &wt))
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
|
||||
|
||||
/* Workaround for nonblocking connects under net_server */
|
||||
#ifndef BONE_VERSION
|
||||
if (out_flags)
|
||||
{
|
||||
/* check if it is a pending connect */
|
||||
int i = 0, j = 0;
|
||||
PR_Lock( _connectLock );
|
||||
for( i = 0; i < connectCount; i++ )
|
||||
{
|
||||
if(connectList[i].osfd == osfd)
|
||||
{
|
||||
int connectError;
|
||||
int connectResult;
|
||||
|
||||
connectResult = connect(connectList[i].osfd,
|
||||
&connectList[i].addr,
|
||||
connectList[i].addrlen);
|
||||
connectError = errno;
|
||||
|
||||
if(connectResult < 0 )
|
||||
{
|
||||
if(connectError == EINTR || connectError == EWOULDBLOCK ||
|
||||
connectError == EINPROGRESS || connectError == EALREADY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == (connectCount - 1))
|
||||
{
|
||||
connectList[i].osfd = -1;
|
||||
} else {
|
||||
for(j = i; j < connectCount; j++ )
|
||||
{
|
||||
memcpy( &connectList[j], &connectList[j+1],
|
||||
sizeof(connectList[j]));
|
||||
}
|
||||
}
|
||||
connectCount--;
|
||||
|
||||
bottom->secret->md.connectReturnValue = connectResult;
|
||||
bottom->secret->md.connectReturnError = connectError;
|
||||
bottom->secret->md.connectValueValid = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PR_Unlock( _connectLock );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
pd->out_flags = out_flags;
|
||||
if (out_flags) ready++;
|
||||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
else if (ready < 0)
|
||||
{
|
||||
err = _MD_ERRNO();
|
||||
if (err == EBADF)
|
||||
{
|
||||
/* Find the bad fds */
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
{
|
||||
pd->out_flags = 0;
|
||||
if ((NULL != pd->fd) && (0 != pd->in_flags))
|
||||
{
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
|
||||
{
|
||||
pd->out_flags = PR_POLL_NVAL;
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
else _PR_MD_MAP_SELECT_ERROR(err);
|
||||
}
|
||||
|
||||
return ready;
|
||||
} /* _MD_pr_poll */
|
||||
|
||||
/*
|
||||
* File locking.
|
||||
*/
|
||||
|
||||
PRStatus
|
||||
_MD_lockfile (PRInt32 osfd)
|
||||
{
|
||||
PRInt32 rv;
|
||||
struct flock linfo;
|
||||
|
||||
linfo.l_type =
|
||||
linfo.l_whence = SEEK_SET;
|
||||
linfo.l_start = 0;
|
||||
linfo.l_len = 0;
|
||||
|
||||
rv = fcntl(osfd, F_SETLKW, &linfo);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_tlockfile (PRInt32 osfd)
|
||||
{
|
||||
PRInt32 rv;
|
||||
struct flock linfo;
|
||||
|
||||
linfo.l_type =
|
||||
linfo.l_whence = SEEK_SET;
|
||||
linfo.l_start = 0;
|
||||
linfo.l_len = 0;
|
||||
|
||||
rv = fcntl(osfd, F_SETLK, &linfo);
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_unlockfile (PRInt32 osfd)
|
||||
{
|
||||
PRInt32 rv;
|
||||
struct flock linfo;
|
||||
|
||||
linfo.l_type =
|
||||
linfo.l_whence = SEEK_SET;
|
||||
linfo.l_start = 0;
|
||||
linfo.l_len = 0;
|
||||
|
||||
rv = fcntl(osfd, F_UNLCK, &linfo);
|
||||
|
||||
if (rv == 0)
|
||||
return PR_SUCCESS;
|
||||
|
||||
_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
PR_EXTERN(void) _PR_MD_INIT_SEGS(void);
|
||||
PR_EXTERN(PRStatus) _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
|
||||
PR_EXTERN(void) _PR_MD_FREE_SEGMENT(PRSegment *seg);
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
PRLock *_connectLock = NULL;
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
/* Workaround for nonblocking connects under net_server */
|
||||
PRUint32 connectCount = 0;
|
||||
ConnectListNode connectList[64];
|
||||
#endif
|
||||
|
||||
void
|
||||
_MD_cleanup_before_exit (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_MD_exit (PRIntn status)
|
||||
{
|
||||
exit(status);
|
||||
}
|
||||
|
||||
void
|
||||
_MD_early_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
static PRLock *monitor = NULL;
|
||||
|
||||
void
|
||||
_MD_final_init (void)
|
||||
{
|
||||
_connectLock = PR_NewLock();
|
||||
PR_ASSERT(NULL != _connectLock);
|
||||
#ifndef BONE_VERSION
|
||||
/* Workaround for nonblocking connects under net_server */
|
||||
connectCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_MD_AtomicInit (void)
|
||||
{
|
||||
if (monitor == NULL) {
|
||||
monitor = PR_NewLock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This is exceedingly messy. atomic_add returns the last value, NSPR expects the new value.
|
||||
** We just add or subtract 1 from the result. The actual memory update is atomic.
|
||||
*/
|
||||
|
||||
PRInt32
|
||||
_MD_AtomicAdd( PRInt32 *ptr, PRInt32 val )
|
||||
{
|
||||
return( ( atomic_add( (long *)ptr, val ) ) + val );
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_AtomicIncrement( PRInt32 *val )
|
||||
{
|
||||
return( ( atomic_add( (long *)val, 1 ) ) + 1 );
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_AtomicDecrement( PRInt32 *val )
|
||||
{
|
||||
return( ( atomic_add( (long *)val, -1 ) ) - 1 );
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_AtomicSet( PRInt32 *val, PRInt32 newval )
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
if (!_pr_initialized) {
|
||||
_PR_ImplicitInitialization();
|
||||
}
|
||||
PR_Lock(monitor);
|
||||
rv = *val;
|
||||
*val = newval;
|
||||
PR_Unlock(monitor);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
PR_EXTERN(PRStatus)
|
||||
_PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size)
|
||||
{
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EXTERN(PRInt32)
|
||||
_PR_MD_GET_MEM_MAP_ALIGNMENT(void)
|
||||
{
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_EXTERN(void *)
|
||||
_PR_MD_MEM_MAP(PRFileMap *fmap, PRInt64 offset, PRUint32 len)
|
||||
{
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_EXTERN(PRStatus)
|
||||
_PR_MD_MEM_UNMAP(void *addr, PRUint32 size)
|
||||
{
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_EXTERN(PRStatus)
|
||||
_PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap)
|
||||
{
|
||||
PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -1,911 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/*
|
||||
* Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
|
||||
* PRInt32* pointer to a _PRSockLen_t* pointer.
|
||||
*/
|
||||
#define _PRSockLen_t int
|
||||
|
||||
|
||||
/*
|
||||
** Global lock variable used to bracket calls into rusty libraries that
|
||||
** aren't thread safe (like libc, libX, etc).
|
||||
*/
|
||||
static PRLock *_pr_rename_lock = NULL;
|
||||
static PRMonitor *_pr_Xfe_mon = NULL;
|
||||
|
||||
#define READ_FD 1
|
||||
#define WRITE_FD 2
|
||||
|
||||
/*
|
||||
** This is a support routine to handle "deferred" i/o on sockets.
|
||||
** It uses "select", so it is subject to all of the BeOS limitations
|
||||
** (only READ notification, only sockets)
|
||||
*/
|
||||
|
||||
/*
|
||||
* socket_io_wait --
|
||||
*
|
||||
* wait for socket i/o, periodically checking for interrupt
|
||||
*
|
||||
*/
|
||||
|
||||
static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv = -1;
|
||||
struct timeval tv;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRIntervalTime epoch, now, elapsed, remaining;
|
||||
PRBool wait_for_remaining;
|
||||
PRInt32 syserror;
|
||||
fd_set rd_wr;
|
||||
|
||||
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.
|
||||
*/
|
||||
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&rd_wr);
|
||||
do {
|
||||
FD_SET(osfd, &rd_wr);
|
||||
if (fd_type == READ_FD)
|
||||
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
|
||||
else
|
||||
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
|
||||
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
|
||||
#ifdef BONE_VERSION
|
||||
_PR_MD_MAP_SELECT_ERROR(syserror);
|
||||
#else
|
||||
if (syserror == EBADF) {
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
|
||||
} else {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, syserror);
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
FD_ZERO(&rd_wr);
|
||||
do {
|
||||
/*
|
||||
* We block in _MD_SELECT 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.
|
||||
*/
|
||||
wait_for_remaining = PR_TRUE;
|
||||
tv.tv_sec = PR_IntervalToSeconds(remaining);
|
||||
if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
|
||||
wait_for_remaining = PR_FALSE;
|
||||
tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
|
||||
tv.tv_usec = 0;
|
||||
} else {
|
||||
tv.tv_usec = PR_IntervalToMicroseconds(
|
||||
remaining -
|
||||
PR_SecondsToInterval(tv.tv_sec));
|
||||
}
|
||||
FD_SET(osfd, &rd_wr);
|
||||
if (fd_type == READ_FD)
|
||||
rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
|
||||
else
|
||||
rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
|
||||
/*
|
||||
* we don't consider EINTR a real error
|
||||
*/
|
||||
if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
|
||||
#ifdef BONE_VERSION
|
||||
_PR_MD_MAP_SELECT_ERROR(syserror);
|
||||
#else
|
||||
if (syserror == EBADF) {
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
|
||||
} else {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, syserror);
|
||||
}
|
||||
#endif
|
||||
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_SELECT 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_SELECT timed out, we know how much time
|
||||
* we spent in blocking, so we can avoid a
|
||||
* PR_IntervalNow() call.
|
||||
*/
|
||||
if (rv == 0) {
|
||||
if (wait_for_remaining) {
|
||||
now += remaining;
|
||||
} else {
|
||||
now += PR_SecondsToInterval(tv.tv_sec)
|
||||
+ PR_MicrosecondsToInterval(tv.tv_usec);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) {
|
||||
_PR_MD_MAP_RECV_ERROR(EPIPE);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
/*
|
||||
** Gah, stupid hack. If reading a zero amount, instantly return success.
|
||||
** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of
|
||||
** mozilla use to check for socket availability.
|
||||
*/
|
||||
|
||||
if( 0 == amount ) return(0);
|
||||
#endif
|
||||
|
||||
while ((rv = recv(osfd, buf, amount, flags)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
/* If socket was supposed to be blocking,
|
||||
wait a while for the condition to be
|
||||
satisfied. */
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
continue;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_RECV_ERROR(err);
|
||||
}
|
||||
|
||||
done:
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_recvfrom (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
|
||||
PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
while ((*addrlen = PR_NETADDR_SIZE(addr)),
|
||||
((rv = recvfrom(osfd, buf, amount, flags,
|
||||
(struct sockaddr *) addr,
|
||||
(_PRSockLen_t *)addrlen)) == -1)) {
|
||||
err = _MD_ERRNO();
|
||||
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
goto done;
|
||||
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_RECVFROM_ERROR(err);
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv != -1) {
|
||||
/* ignore the sa_len field of struct sockaddr */
|
||||
if (addr) {
|
||||
addr->raw.family = ((struct sockaddr *) addr)->sa_family;
|
||||
}
|
||||
}
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE)
|
||||
{
|
||||
_PR_MD_MAP_SEND_ERROR(EPIPE);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((rv = send(osfd, buf, amount, flags)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
if( _PR_PENDING_INTERRUPT(me)) {
|
||||
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* in UNIX implementations, you could do a socket_io_wait here.
|
||||
* but since BeOS doesn't yet support WRITE notification in select,
|
||||
* you're spanked.
|
||||
*/
|
||||
snooze( 10000L );
|
||||
continue;
|
||||
#else /* BONE_VERSION */
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
|
||||
goto done;
|
||||
#endif
|
||||
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next writev() call will return EWOULDBLOCK.
|
||||
*/
|
||||
if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
|
||||
&& (timeout != PR_INTERVAL_NO_WAIT)) {
|
||||
if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
|
||||
rv = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#endif /* BONE_VERSION */
|
||||
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_SEND_ERROR(err);
|
||||
}
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
done:
|
||||
#endif
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
|
||||
const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
PRNetAddr addrCopy;
|
||||
|
||||
addrCopy = *addr;
|
||||
((struct sockaddr *) &addrCopy)->sa_len = addrlen;
|
||||
((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
|
||||
|
||||
while ((rv = sendto(osfd, buf, amount, flags,
|
||||
(struct sockaddr *) &addrCopy, addrlen)) == -1) {
|
||||
#else
|
||||
while ((rv = sendto(osfd, buf, amount, flags,
|
||||
(struct sockaddr *) addr, addrlen)) == -1) {
|
||||
#endif
|
||||
err = _MD_ERRNO();
|
||||
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
|
||||
goto done;
|
||||
#endif
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_SENDTO_ERROR(err);
|
||||
}
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
done:
|
||||
#endif
|
||||
return(rv);
|
||||
}
|
||||
|
||||
#ifdef BONE_VERSION
|
||||
|
||||
PRInt32 _MD_writev(
|
||||
PRFileDesc *fd, const PRIOVec *iov,
|
||||
PRInt32 iov_size, PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRInt32 index, amount = 0;
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
struct iovec osiov[PR_MAX_IOVECTOR_SIZE];
|
||||
|
||||
/* Ensured by PR_Writev */
|
||||
PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE);
|
||||
|
||||
/*
|
||||
* We can't pass iov to writev because PRIOVec and struct iovec
|
||||
* may not be binary compatible. Make osiov a copy of iov and
|
||||
* pass osiov to writev.
|
||||
*/
|
||||
for (index = 0; index < iov_size; index++) {
|
||||
osiov[index].iov_base = iov[index].iov_base;
|
||||
osiov[index].iov_len = iov[index].iov_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the total number of bytes to be sent; needed for
|
||||
* optimization later.
|
||||
* We could avoid this if this number was passed in; but it is
|
||||
* probably not a big deal because iov_size is usually small (less than
|
||||
* 3)
|
||||
*/
|
||||
if (!fd->secret->nonblocking) {
|
||||
for (index=0; index<iov_size; index++) {
|
||||
amount += iov[index].iov_len;
|
||||
}
|
||||
}
|
||||
|
||||
while ((rv = writev(osfd, osiov, iov_size)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
|
||||
goto done;
|
||||
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next writev() call will return EWOULDBLOCK.
|
||||
*/
|
||||
if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
|
||||
&& (timeout != PR_INTERVAL_NO_WAIT)) {
|
||||
if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
|
||||
rv = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_WRITEV_ERROR(err);
|
||||
}
|
||||
done:
|
||||
return(rv);
|
||||
}
|
||||
|
||||
#endif /* BONE_VERSION */
|
||||
|
||||
PRInt32
|
||||
_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
while ((rv = accept(osfd, (struct sockaddr *) addr,
|
||||
(_PRSockLen_t *)addrlen)) == -1) {
|
||||
err = _MD_ERRNO();
|
||||
|
||||
if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
/* If it's SUPPOSED to be a blocking thread, wait
|
||||
* a while to see if the triggering condition gets
|
||||
* satisfied.
|
||||
*/
|
||||
/* Assume that we're always using a native thread */
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_ACCEPT_ERROR(err);
|
||||
} else if (addr != NULL) {
|
||||
/* bug 134099 */
|
||||
err = getpeername(rv, (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
|
||||
}
|
||||
done:
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv != -1) {
|
||||
/* Mask off the first byte of struct sockaddr (the length field) */
|
||||
if (addr) {
|
||||
addr->raw.family = ((struct sockaddr *) addr)->sa_family;
|
||||
}
|
||||
}
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
fd->secret->md.connectValueValid = PR_FALSE;
|
||||
#endif
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
PRNetAddr addrCopy;
|
||||
|
||||
addrCopy = *addr;
|
||||
((struct sockaddr *) &addrCopy)->sa_len = addrlen;
|
||||
((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
|
||||
#endif
|
||||
|
||||
/* (Copied from unix.c)
|
||||
* We initiate the connection setup by making a nonblocking connect()
|
||||
* call. If the connect() call fails, there are two cases we handle
|
||||
* specially:
|
||||
* 1. The connect() call was interrupted by a signal. In this case
|
||||
* we simply retry connect().
|
||||
* 2. The NSPR socket is nonblocking and connect() fails with
|
||||
* EINPROGRESS. We first wait until the socket becomes writable.
|
||||
* Then we try to find out whether the connection setup succeeded
|
||||
* or failed.
|
||||
*/
|
||||
|
||||
retry:
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
|
||||
#else
|
||||
if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
|
||||
#endif
|
||||
err = _MD_ERRNO();
|
||||
#ifndef BONE_VERSION
|
||||
fd->secret->md.connectReturnValue = rv;
|
||||
fd->secret->md.connectReturnError = err;
|
||||
fd->secret->md.connectValueValid = PR_TRUE;
|
||||
#endif
|
||||
if( err == EINTR ) {
|
||||
|
||||
if( _PR_PENDING_INTERRUPT(me)) {
|
||||
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
#ifndef BONE_VERSION
|
||||
snooze( 100000L );
|
||||
#endif
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) {
|
||||
|
||||
/*
|
||||
** There's no timeout on this connect, but that's not
|
||||
** a big deal, since the connect times out anyways
|
||||
** after 30 seconds. Just sleep for 1/10th of a second
|
||||
** and retry until we go through or die.
|
||||
*/
|
||||
|
||||
if( _PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if( fd->secret->nonblocking && ((err == EAGAIN) || (err == EINPROGRESS))) {
|
||||
PR_Lock(_connectLock);
|
||||
if (connectCount < sizeof(connectList)/sizeof(connectList[0])) {
|
||||
connectList[connectCount].osfd = osfd;
|
||||
memcpy(&connectList[connectCount].addr, addr, addrlen);
|
||||
connectList[connectCount].addrlen = addrlen;
|
||||
connectList[connectCount].timeout = timeout;
|
||||
connectCount++;
|
||||
PR_Unlock(_connectLock);
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
} else {
|
||||
PR_Unlock(_connectLock);
|
||||
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#else /* BONE_VERSION */
|
||||
if(!fd->secret->nonblocking && (err == EINTR)) {
|
||||
|
||||
rv = socket_io_wait(osfd, WRITE_FD, timeout);
|
||||
if (rv == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(rv == 1);
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
err = _MD_beos_get_nonblocking_connect_error(osfd);
|
||||
if (err != 0) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_bind (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
PRNetAddr addrCopy;
|
||||
|
||||
addrCopy = *addr;
|
||||
((struct sockaddr *) &addrCopy)->sa_len = addrlen;
|
||||
((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
|
||||
rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
|
||||
#else
|
||||
rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
|
||||
#endif
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_BIND_ERROR(err);
|
||||
}
|
||||
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_listen (PRFileDesc *fd, PRIntn backlog)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
/* Bug workaround! Setting listen to 0 on Be accepts no connections.
|
||||
** On most UN*Xes this sets the default.
|
||||
*/
|
||||
|
||||
if( backlog == 0 ) backlog = 5;
|
||||
#endif
|
||||
|
||||
rv = listen(fd->secret->md.osfd, backlog);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_LISTEN_ERROR(err);
|
||||
}
|
||||
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_shutdown (PRFileDesc *fd, PRIntn how)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
if (how == PR_SHUTDOWN_SEND)
|
||||
fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE;
|
||||
else if (how == PR_SHUTDOWN_RCV)
|
||||
fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_READ;
|
||||
else if (how == PR_SHUTDOWN_BOTH) {
|
||||
fd->secret->md.sock_state = (BE_SOCK_SHUTDOWN_WRITE | BE_SOCK_SHUTDOWN_READ);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else /* BONE_VERSION */
|
||||
rv = shutdown(fd->secret->md.osfd, how);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_SHUTDOWN_ERROR(err);
|
||||
}
|
||||
return(rv);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_socketpair (int af, int type, int flags, PRInt32 *osfd)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_close_socket (PRInt32 osfd)
|
||||
{
|
||||
#ifdef BONE_VERSION
|
||||
close( osfd );
|
||||
#else
|
||||
closesocket( osfd );
|
||||
#endif
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_getsockname (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = getsockname(fd->secret->md.osfd,
|
||||
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv == 0) {
|
||||
/* ignore the sa_len field of struct sockaddr */
|
||||
if (addr) {
|
||||
addr->raw.family = ((struct sockaddr *) addr)->sa_family;
|
||||
}
|
||||
}
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETSOCKNAME_ERROR(err);
|
||||
}
|
||||
|
||||
return rv==0?PR_SUCCESS:PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_getpeername (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = getpeername(fd->secret->md.osfd,
|
||||
(struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
|
||||
|
||||
#ifdef _PR_HAVE_SOCKADDR_LEN
|
||||
if (rv == 0) {
|
||||
/* ignore the sa_len field of struct sockaddr */
|
||||
if (addr) {
|
||||
addr->raw.family = ((struct sockaddr *) addr)->sa_family;
|
||||
}
|
||||
}
|
||||
#endif /* _PR_HAVE_SOCKADDR_LEN */
|
||||
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETPEERNAME_ERROR(err);
|
||||
}
|
||||
return rv==0?PR_SUCCESS:PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_getsockopt (PRFileDesc *fd, PRInt32 level,
|
||||
PRInt32 optname, char* optval, PRInt32* optlen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = getsockopt(fd->secret->md.osfd, level, optname,
|
||||
optval, (_PRSockLen_t *)optlen);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETSOCKOPT_ERROR(err);
|
||||
}
|
||||
|
||||
return rv==0?PR_SUCCESS:PR_FAILURE;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_setsockopt (PRFileDesc *fd, PRInt32 level,
|
||||
PRInt32 optname, const char* optval, PRInt32 optlen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
|
||||
if (rv < 0) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_SETSOCKOPT_ERROR(err);
|
||||
}
|
||||
return rv==0?PR_SUCCESS:PR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr,
|
||||
void *buf, PRInt32 amount, PRIntervalTime timeout)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
PRInt32
|
||||
_MD_socket (int af, int type, int flags)
|
||||
{
|
||||
PRInt32 osfd, err;
|
||||
|
||||
osfd = socket( af, type, 0 );
|
||||
|
||||
if( -1 == osfd ) {
|
||||
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_SOCKET_ERROR( err );
|
||||
}
|
||||
|
||||
return( osfd );
|
||||
}
|
||||
#else
|
||||
PRInt32
|
||||
_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
|
||||
{
|
||||
PRInt32 osfd, err;
|
||||
|
||||
osfd = socket(domain, type, proto);
|
||||
|
||||
if (osfd == -1) {
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_SOCKET_ERROR(err);
|
||||
}
|
||||
|
||||
return(osfd);
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32
|
||||
_MD_socketavailable (PRFileDesc *fd)
|
||||
{
|
||||
#ifdef BONE_VERSION
|
||||
PRInt32 result;
|
||||
|
||||
if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
|
||||
_PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_MD_get_socket_error (void)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_gethostname (char *name, PRUint32 namelen)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
||||
rv = gethostname(name, namelen);
|
||||
if (rv == 0)
|
||||
{
|
||||
err = _MD_ERRNO();
|
||||
_PR_MD_MAP_GETHOSTNAME_ERROR(err);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef BONE_VERSION
|
||||
PRInt32
|
||||
_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd)
|
||||
{
|
||||
int rv;
|
||||
int flags = 0;
|
||||
|
||||
rv = recv(fd->secret->md.osfd, NULL, 0, flags);
|
||||
PR_ASSERT(-1 == rv || 0 == rv);
|
||||
if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
return errno;
|
||||
}
|
||||
return 0; /* no error */
|
||||
}
|
||||
#else
|
||||
PRInt32
|
||||
_MD_beos_get_nonblocking_connect_error(int osfd)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
// int err;
|
||||
// _PRSockLen_t optlen = sizeof(err);
|
||||
// if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
|
||||
// return errno;
|
||||
// } else {
|
||||
// return err;
|
||||
// }
|
||||
}
|
||||
#endif /* BONE_VERSION */
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define _PR_SIGNALED_EXITSTATUS 256
|
||||
|
||||
PRProcess*
|
||||
_MD_create_process (const char *path, char *const *argv,
|
||||
char *const *envp, const PRProcessAttr *attr)
|
||||
{
|
||||
PRProcess *process;
|
||||
int nEnv, idx;
|
||||
char *const *childEnvp;
|
||||
char **newEnvp = NULL;
|
||||
int flags;
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
process = PR_NEW(PRProcess);
|
||||
if (!process) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
childEnvp = envp;
|
||||
if (attr && attr->fdInheritBuffer) {
|
||||
if (NULL == childEnvp) {
|
||||
childEnvp = environ;
|
||||
}
|
||||
for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
|
||||
}
|
||||
newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
|
||||
if (NULL == newEnvp) {
|
||||
PR_DELETE(process);
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
for (idx = 0; idx < nEnv; idx++) {
|
||||
newEnvp[idx] = childEnvp[idx];
|
||||
if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) {
|
||||
newEnvp[idx] = attr->fdInheritBuffer;
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
newEnvp[idx++] = attr->fdInheritBuffer;
|
||||
}
|
||||
newEnvp[idx] = NULL;
|
||||
childEnvp = newEnvp;
|
||||
}
|
||||
|
||||
process->md.pid = fork();
|
||||
|
||||
if ((pid_t) -1 == process->md.pid) {
|
||||
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
|
||||
PR_DELETE(process);
|
||||
if (newEnvp) {
|
||||
PR_DELETE(newEnvp);
|
||||
}
|
||||
return NULL;
|
||||
} else if (0 == process->md.pid) { /* the child process */
|
||||
/*
|
||||
* If the child process needs to exit, it must call _exit().
|
||||
* Do not call exit(), because exit() will flush and close
|
||||
* the standard I/O file descriptors, and hence corrupt
|
||||
* the parent process's standard I/O data structures.
|
||||
*/
|
||||
|
||||
if (attr) {
|
||||
/* the osfd's to redirect stdin, stdout, and stderr to */
|
||||
int in_osfd = -1, out_osfd = -1, err_osfd = -1;
|
||||
|
||||
if (attr->stdinFd
|
||||
&& attr->stdinFd->secret->md.osfd != 0) {
|
||||
in_osfd = attr->stdinFd->secret->md.osfd;
|
||||
if (dup2(in_osfd, 0) != 0) {
|
||||
_exit(1); /* failed */
|
||||
}
|
||||
flags = fcntl(0, F_GETFL, 0);
|
||||
if (flags & O_NONBLOCK) {
|
||||
fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
if (attr->stdoutFd
|
||||
&& attr->stdoutFd->secret->md.osfd != 1) {
|
||||
out_osfd = attr->stdoutFd->secret->md.osfd;
|
||||
if (dup2(out_osfd, 1) != 1) {
|
||||
_exit(1); /* failed */
|
||||
}
|
||||
flags = fcntl(1, F_GETFL, 0);
|
||||
if (flags & O_NONBLOCK) {
|
||||
fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
if (attr->stderrFd
|
||||
&& attr->stderrFd->secret->md.osfd != 2) {
|
||||
err_osfd = attr->stderrFd->secret->md.osfd;
|
||||
if (dup2(err_osfd, 2) != 2) {
|
||||
_exit(1); /* failed */
|
||||
}
|
||||
flags = fcntl(2, F_GETFL, 0);
|
||||
if (flags & O_NONBLOCK) {
|
||||
fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
if (in_osfd != -1) {
|
||||
close(in_osfd);
|
||||
}
|
||||
if (out_osfd != -1 && out_osfd != in_osfd) {
|
||||
close(out_osfd);
|
||||
}
|
||||
if (err_osfd != -1 && err_osfd != in_osfd
|
||||
&& err_osfd != out_osfd) {
|
||||
close(err_osfd);
|
||||
}
|
||||
if (attr->currentDirectory) {
|
||||
if (chdir(attr->currentDirectory) < 0) {
|
||||
_exit(1); /* failed */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (childEnvp) {
|
||||
(void)execve(path, argv, childEnvp);
|
||||
} else {
|
||||
/* Inherit the environment of the parent. */
|
||||
(void)execv(path, argv);
|
||||
}
|
||||
/* Whoops! It returned. That's a bad sign. */
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
if (newEnvp) {
|
||||
PR_DELETE(newEnvp);
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_detach_process (PRProcess *process)
|
||||
{
|
||||
/* If we kept a process table like unix does,
|
||||
* we'd remove the entry here.
|
||||
* Since we dont', just delete the process variable
|
||||
*/
|
||||
PR_DELETE(process);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_wait_process (PRProcess *process, PRInt32 *exitCode)
|
||||
{
|
||||
PRStatus retVal = PR_SUCCESS;
|
||||
int ret, status;
|
||||
|
||||
/* Ignore interruptions */
|
||||
do {
|
||||
ret = waitpid(process->md.pid, &status, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
/*
|
||||
* waitpid() cannot return 0 because we did not invoke it
|
||||
* with the WNOHANG option.
|
||||
*/
|
||||
PR_ASSERT(0 != ret);
|
||||
|
||||
if (ret < 0) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/* If child process exited normally, return child exit code */
|
||||
if (WIFEXITED(status)) {
|
||||
*exitCode = WEXITSTATUS(status);
|
||||
} else {
|
||||
PR_ASSERT(WIFSIGNALED(status));
|
||||
*exitCode = _PR_SIGNALED_EXITSTATUS;
|
||||
}
|
||||
|
||||
PR_DELETE(process);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
_MD_kill_process (PRProcess *process)
|
||||
{
|
||||
PRErrorCode prerror;
|
||||
PRInt32 oserror;
|
||||
|
||||
if (kill(process->md.pid, SIGKILL) == 0) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
oserror = errno;
|
||||
switch (oserror) {
|
||||
case EPERM:
|
||||
prerror = PR_NO_ACCESS_RIGHTS_ERROR;
|
||||
break;
|
||||
case ESRCH:
|
||||
prerror = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
default:
|
||||
prerror = PR_UNKNOWN_ERROR;
|
||||
break;
|
||||
}
|
||||
PR_SetError(prerror, oserror);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include "primpl.h"
|
||||
|
||||
extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
|
||||
{
|
||||
struct timeval tv;
|
||||
int n = 0;
|
||||
int s;
|
||||
|
||||
GETTIMEOFDAY(&tv);
|
||||
|
||||
if ( size > 0 ) {
|
||||
s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
|
||||
size -= s;
|
||||
n += s;
|
||||
}
|
||||
if ( size > 0 ) {
|
||||
s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
|
||||
size -= s;
|
||||
n += s;
|
||||
}
|
||||
|
||||
return n;
|
||||
} /* end _PR_MD_GetRandomNoise() */
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
_MD_init_segs (void)
|
||||
{
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_alloc_segment (PRSegment *seg, PRUint32 size, void *vaddr)
|
||||
{
|
||||
return PR_NOT_IMPLEMENTED_ERROR;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
_MD_free_segment (PRSegment *seg)
|
||||
{
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
# this file lists the source files to be compiled (used in Makefile) and
|
||||
# then enumerated as object files (in objs.mk) for inclusion in the NSPR
|
||||
# shared library
|
||||
|
||||
MDCSRCS = \
|
||||
beos.c \
|
||||
beos_errors.c \
|
||||
bfile.c \
|
||||
bmisc.c \
|
||||
bnet.c \
|
||||
bproc.c \
|
||||
brng.c \
|
||||
bseg.c \
|
||||
btime.c \
|
||||
bmmap.c \
|
||||
$(NULL)
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "primpl.h"
|
||||
#include <kernel/OS.h>
|
||||
|
||||
static bigtime_t start;
|
||||
|
||||
PRTime
|
||||
_MD_now (void)
|
||||
{
|
||||
return (PRTime)real_time_clock_usecs();
|
||||
}
|
||||
|
||||
void
|
||||
_MD_interval_init (void)
|
||||
{
|
||||
/* grab the base interval time */
|
||||
start = real_time_clock_usecs();
|
||||
}
|
||||
|
||||
PRIntervalTime
|
||||
_MD_get_interval (void)
|
||||
{
|
||||
return( (PRIntervalTime) real_time_clock_usecs() / 10 );
|
||||
|
||||
#if 0
|
||||
/* return the number of tens of microseconds that have elapsed since
|
||||
we were initialized */
|
||||
bigtime_t now = real_time_clock_usecs();
|
||||
now -= start;
|
||||
now /= 10;
|
||||
return (PRIntervalTime)now;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRIntervalTime
|
||||
_MD_interval_per_sec (void)
|
||||
{
|
||||
return 100000L;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This makefile appends to the variable OBJS the platform-dependent
|
||||
# object modules that will be part of the nspr20 library.
|
||||
|
||||
include $(srcdir)/md/beos/bsrcs.mk
|
||||
|
||||
OBJS += $(MDCSRCS:%.c=md/beos/$(OBJDIR)/%.$(OBJ_SUFFIX))
|
||||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@
|
|||
* until right after we unlock the lock. This way the awakened threads
|
||||
* have a better chance to reaquire the lock.
|
||||
*/
|
||||
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
|
|
@ -30,7 +30,7 @@ static void
|
|||
AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv)
|
||||
{
|
||||
PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
|
||||
|| (cv->waitTail == NULL && cv->waitHead == NULL));
|
||||
|| (cv->waitTail == NULL && cv->waitHead == NULL));
|
||||
cv->nwait += 1;
|
||||
thred->md.inCVWaitQueue = PR_TRUE;
|
||||
thred->md.next = NULL;
|
||||
|
|
@ -78,7 +78,7 @@ md_UnlockAndPostNotifies(
|
|||
lock->notified.link = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* Figure out how many threads we need to wake up.
|
||||
*/
|
||||
notified = &post; /* this is where we start */
|
||||
|
|
@ -87,7 +87,7 @@ md_UnlockAndPostNotifies(
|
|||
_MDCVar *cv = notified->cv[index].cv;
|
||||
PRThread *thred;
|
||||
int i;
|
||||
|
||||
|
||||
/* Fast special case: no waiting threads */
|
||||
if (cv->waitHead == NULL) {
|
||||
notified->cv[index].notifyHead = NULL;
|
||||
|
|
@ -155,7 +155,9 @@ md_UnlockAndPostNotifies(
|
|||
}
|
||||
prev = notified;
|
||||
notified = notified->link;
|
||||
if (&post != prev) PR_DELETE(prev);
|
||||
if (&post != prev) {
|
||||
PR_DELETE(prev);
|
||||
}
|
||||
} while (NULL != notified);
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ md_UnlockAndPostNotifies(
|
|||
* MP systems don't contend for a lock that they can't have.
|
||||
*/
|
||||
static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
|
||||
PRBool broadcast)
|
||||
PRBool broadcast)
|
||||
{
|
||||
PRIntn index = 0;
|
||||
_MDNotified *notified = &lock->notified;
|
||||
|
|
@ -182,7 +184,9 @@ static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
|
|||
}
|
||||
}
|
||||
/* if not full, enter new CV in this array */
|
||||
if (notified->length < _MD_CV_NOTIFIED_LENGTH) break;
|
||||
if (notified->length < _MD_CV_NOTIFIED_LENGTH) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* if there's no link, create an empty array and link it */
|
||||
if (NULL == notified->link) {
|
||||
|
|
@ -215,7 +219,7 @@ _PR_MD_NEW_CV(_MDCVar *cv)
|
|||
* when the PRCondVar structure is created.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void _PR_MD_FREE_CV(_MDCVar *cv)
|
||||
{
|
||||
|
|
@ -232,7 +236,7 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
|
|||
PRThread *thred = _PR_MD_CURRENT_THREAD();
|
||||
ULONG rv, count;
|
||||
ULONG msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ?
|
||||
SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout);
|
||||
SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout);
|
||||
|
||||
/*
|
||||
* If we have pending notifies, post them now.
|
||||
|
|
@ -241,7 +245,7 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
|
|||
md_UnlockAndPostNotifies(lock, thred, cv);
|
||||
} else {
|
||||
AddThreadToCVWaitQueueInternal(thred, cv);
|
||||
DosReleaseMutexSem(lock->mutex);
|
||||
DosReleaseMutexSem(lock->mutex);
|
||||
}
|
||||
|
||||
/* Wait for notification or timeout; don't really care which */
|
||||
|
|
@ -256,42 +260,42 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
|
|||
|
||||
if(rv == ERROR_TIMEOUT)
|
||||
{
|
||||
if (thred->md.inCVWaitQueue) {
|
||||
PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
|
||||
|| (cv->waitTail == NULL && cv->waitHead == NULL));
|
||||
cv->nwait -= 1;
|
||||
thred->md.inCVWaitQueue = PR_FALSE;
|
||||
if (cv->waitHead == thred) {
|
||||
cv->waitHead = thred->md.next;
|
||||
if (cv->waitHead == NULL) {
|
||||
cv->waitTail = NULL;
|
||||
} else {
|
||||
cv->waitHead->md.prev = NULL;
|
||||
}
|
||||
} else {
|
||||
PR_ASSERT(thred->md.prev != NULL);
|
||||
thred->md.prev->md.next = thred->md.next;
|
||||
if (thred->md.next != NULL) {
|
||||
thred->md.next->md.prev = thred->md.prev;
|
||||
} else {
|
||||
PR_ASSERT(cv->waitTail == thred);
|
||||
cv->waitTail = thred->md.prev;
|
||||
}
|
||||
}
|
||||
thred->md.next = thred->md.prev = NULL;
|
||||
} else {
|
||||
/*
|
||||
* This thread must have been notified, but the
|
||||
* SemRelease call happens after SemRequest
|
||||
* times out. Wait on the semaphore again to make it
|
||||
* non-signaled. We assume this wait won't take long.
|
||||
*/
|
||||
rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
|
||||
if (rv == NO_ERROR) {
|
||||
DosResetEventSem(thred->md.blocked_sema, &count);
|
||||
}
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
}
|
||||
if (thred->md.inCVWaitQueue) {
|
||||
PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
|
||||
|| (cv->waitTail == NULL && cv->waitHead == NULL));
|
||||
cv->nwait -= 1;
|
||||
thred->md.inCVWaitQueue = PR_FALSE;
|
||||
if (cv->waitHead == thred) {
|
||||
cv->waitHead = thred->md.next;
|
||||
if (cv->waitHead == NULL) {
|
||||
cv->waitTail = NULL;
|
||||
} else {
|
||||
cv->waitHead->md.prev = NULL;
|
||||
}
|
||||
} else {
|
||||
PR_ASSERT(thred->md.prev != NULL);
|
||||
thred->md.prev->md.next = thred->md.next;
|
||||
if (thred->md.next != NULL) {
|
||||
thred->md.next->md.prev = thred->md.prev;
|
||||
} else {
|
||||
PR_ASSERT(cv->waitTail == thred);
|
||||
cv->waitTail = thred->md.prev;
|
||||
}
|
||||
}
|
||||
thred->md.next = thred->md.prev = NULL;
|
||||
} else {
|
||||
/*
|
||||
* This thread must have been notified, but the
|
||||
* SemRelease call happens after SemRequest
|
||||
* times out. Wait on the semaphore again to make it
|
||||
* non-signaled. We assume this wait won't take long.
|
||||
*/
|
||||
rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
|
||||
if (rv == NO_ERROR) {
|
||||
DosResetEventSem(thred->md.blocked_sema, &count);
|
||||
}
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
}
|
||||
}
|
||||
PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#include "primpl.h"
|
||||
|
||||
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
||||
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
||||
{
|
||||
CONTEXTRECORD context;
|
||||
context.ContextFlags = CONTEXT_INTEGER;
|
||||
|
|
@ -34,7 +34,7 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
}
|
||||
|
||||
/* This function is not used right now, but is left as a reference.
|
||||
* If you ever need to get the fiberID from the currently running fiber,
|
||||
* If you ever need to get the fiberID from the currently running fiber,
|
||||
* this is it.
|
||||
*/
|
||||
void *
|
||||
|
|
@ -43,8 +43,8 @@ GetMyFiberID()
|
|||
void *fiberData = 0;
|
||||
|
||||
/* A pointer to our tib entry is found at FS:[18]
|
||||
* At offset 10h is the fiberData pointer. The context of the
|
||||
* fiber is stored in there.
|
||||
* At offset 10h is the fiberData pointer. The context of the
|
||||
* fiber is stored in there.
|
||||
*/
|
||||
#ifdef HAVE_ASM
|
||||
__asm {
|
||||
|
|
@ -53,6 +53,6 @@ GetMyFiberID()
|
|||
mov [fiberData], EAX
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return fiberData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ static PRBool useHighResTimer = PR_FALSE;
|
|||
PRIntervalTime _os2_ticksPerSec = -1;
|
||||
PRIntn _os2_bitShift = 0;
|
||||
PRInt32 _os2_highMask = 0;
|
||||
|
||||
|
||||
void
|
||||
_PR_MD_INTERVAL_INIT()
|
||||
{
|
||||
|
|
@ -23,8 +23,9 @@ _PR_MD_INTERVAL_INIT()
|
|||
APIRET rc;
|
||||
|
||||
if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) {
|
||||
if (atoi(envp) == 1)
|
||||
return;
|
||||
if (atoi(envp) == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */
|
||||
|
|
@ -59,8 +60,8 @@ _PR_MD_GET_INTERVAL()
|
|||
*/
|
||||
top = timestamp.ulHi & _os2_highMask;
|
||||
top = top << (32 - _os2_bitShift);
|
||||
timestamp.ulLo = timestamp.ulLo >> _os2_bitShift;
|
||||
timestamp.ulLo = timestamp.ulLo + top;
|
||||
timestamp.ulLo = timestamp.ulLo >> _os2_bitShift;
|
||||
timestamp.ulLo = timestamp.ulLo + top;
|
||||
return (PRUint32)timestamp.ulLo;
|
||||
} else {
|
||||
ULONG msCount = -1;
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ struct _MDLock _pr_ioq_lock;
|
|||
static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */
|
||||
|
||||
typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction,
|
||||
LONGLONG cbFile, ULONG ulAttribute,
|
||||
ULONG fsOpenFlags, ULONG fsOpenMode,
|
||||
PEAOP2 peaop2);
|
||||
LONGLONG cbFile, ULONG ulAttribute,
|
||||
ULONG fsOpenFlags, ULONG fsOpenMode,
|
||||
PEAOP2 peaop2);
|
||||
|
||||
typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock,
|
||||
PFILELOCKL pflLock, ULONG timeout,
|
||||
ULONG flags);
|
||||
PFILELOCKL pflLock, ULONG timeout,
|
||||
ULONG flags);
|
||||
|
||||
typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method,
|
||||
PLONGLONG ibActual);
|
||||
PLONGLONG ibActual);
|
||||
|
||||
DosOpenLType myDosOpenL;
|
||||
DosSetFileLocksLType myDosSetFileLocksL;
|
||||
|
|
@ -45,7 +45,7 @@ _PR_MD_INIT_IO()
|
|||
HMODULE module;
|
||||
|
||||
sock_init();
|
||||
|
||||
|
||||
rc = DosLoadModule(NULL, 0, "DOSCALL1", &module);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
|
|
@ -76,10 +76,10 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
|
|||
ULONG count;
|
||||
|
||||
PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
|
||||
SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
|
||||
SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
|
||||
rv = DosWaitEventSem(thread->md.blocked_sema, msecs);
|
||||
DosResetEventSem(thread->md.blocked_sema, &count);
|
||||
switch(rv)
|
||||
DosResetEventSem(thread->md.blocked_sema, &count);
|
||||
switch(rv)
|
||||
{
|
||||
case NO_ERROR:
|
||||
return PR_SUCCESS;
|
||||
|
|
@ -87,7 +87,7 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
|
|||
case ERROR_TIMEOUT:
|
||||
_PR_THREAD_LOCK(thread);
|
||||
if (thread->state == _PR_IO_WAIT) {
|
||||
;
|
||||
;
|
||||
} else {
|
||||
if (thread->wait.cvar != NULL) {
|
||||
thread->wait.cvar = NULL;
|
||||
|
|
@ -99,7 +99,7 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
|
|||
*/
|
||||
_PR_THREAD_UNLOCK(thread);
|
||||
rv = DosWaitEventSem(thread->md.blocked_sema, 0);
|
||||
DosResetEventSem(thread->md.blocked_sema, &count);
|
||||
DosResetEventSem(thread->md.blocked_sema, &count);
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
@ -113,13 +113,15 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
|
|||
PRStatus
|
||||
_PR_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if ( _PR_IS_NATIVE_THREAD(thread) )
|
||||
if ( _PR_IS_NATIVE_THREAD(thread) )
|
||||
{
|
||||
if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR)
|
||||
if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) {
|
||||
return PR_FAILURE;
|
||||
else
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -132,7 +134,7 @@ _PR_MD_WAKEUP_WAITER(PRThread *thread)
|
|||
* The NSPR open flags (osflags) are translated into flags for OS/2
|
||||
*
|
||||
* Mode seems to be passed in as a unix style file permissions argument
|
||||
* as in 0666, in the case of opening the logFile.
|
||||
* as in 0666, in the case of opening the logFile.
|
||||
*
|
||||
*/
|
||||
PRInt32
|
||||
|
|
@ -149,7 +151,7 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
|
|||
* All the pointer arguments (&file, &actionTaken and name) have to be in
|
||||
* low memory for DosOpen to use them.
|
||||
* The following moves name to low memory.
|
||||
*/
|
||||
*/
|
||||
if ((ULONG)name >= 0x20000000)
|
||||
{
|
||||
size_t len = strlen(name) + 1;
|
||||
|
|
@ -159,14 +161,19 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH;
|
||||
if (osflags & PR_SYNC) {
|
||||
access |= OPEN_FLAGS_WRITE_THROUGH;
|
||||
}
|
||||
|
||||
if (osflags & PR_RDONLY)
|
||||
if (osflags & PR_RDONLY) {
|
||||
access |= OPEN_ACCESS_READONLY;
|
||||
else if (osflags & PR_WRONLY)
|
||||
}
|
||||
else if (osflags & PR_WRONLY) {
|
||||
access |= OPEN_ACCESS_WRITEONLY;
|
||||
else if(osflags & PR_RDWR)
|
||||
}
|
||||
else if(osflags & PR_RDWR) {
|
||||
access |= OPEN_ACCESS_READWRITE;
|
||||
}
|
||||
|
||||
if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
|
||||
{
|
||||
|
|
@ -174,41 +181,45 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
|
|||
}
|
||||
else if (osflags & PR_CREATE_FILE)
|
||||
{
|
||||
if (osflags & PR_TRUNCATE)
|
||||
if (osflags & PR_TRUNCATE) {
|
||||
flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
|
||||
else
|
||||
}
|
||||
else {
|
||||
flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (osflags & PR_TRUNCATE)
|
||||
if (osflags & PR_TRUNCATE) {
|
||||
flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
|
||||
else
|
||||
}
|
||||
else {
|
||||
flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (isWSEB)
|
||||
{
|
||||
rc = myDosOpenL((char*)name,
|
||||
&file, /* file handle if successful */
|
||||
&actionTaken, /* reason for failure */
|
||||
0, /* initial size of new file */
|
||||
FILE_NORMAL, /* file system attributes */
|
||||
flags, /* Open flags */
|
||||
access, /* Open mode and rights */
|
||||
0); /* OS/2 Extended Attributes */
|
||||
rc = myDosOpenL((char*)name,
|
||||
&file, /* file handle if successful */
|
||||
&actionTaken, /* reason for failure */
|
||||
0, /* initial size of new file */
|
||||
FILE_NORMAL, /* file system attributes */
|
||||
flags, /* Open flags */
|
||||
access, /* Open mode and rights */
|
||||
0); /* OS/2 Extended Attributes */
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = DosOpen((char*)name,
|
||||
&file, /* file handle if successful */
|
||||
&actionTaken, /* reason for failure */
|
||||
0, /* initial size of new file */
|
||||
FILE_NORMAL, /* file system attributes */
|
||||
flags, /* Open flags */
|
||||
access, /* Open mode and rights */
|
||||
0); /* OS/2 Extended Attributes */
|
||||
rc = DosOpen((char*)name,
|
||||
&file, /* file handle if successful */
|
||||
&actionTaken, /* reason for failure */
|
||||
0, /* initial size of new file */
|
||||
FILE_NORMAL, /* file system attributes */
|
||||
flags, /* Open flags */
|
||||
access, /* Open mode and rights */
|
||||
0); /* OS/2 Extended Attributes */
|
||||
};
|
||||
if (rc == ERROR_TOO_MANY_OPEN_FILES) {
|
||||
ULONG CurMaxFH = 0;
|
||||
|
|
@ -223,7 +234,7 @@ _PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
|
|||
|
||||
if (rc != NO_ERROR) {
|
||||
_PR_MD_MAP_OPEN_ERROR(rc);
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (PRInt32)file;
|
||||
|
|
@ -239,17 +250,18 @@ _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
|
|||
(PVOID)buf,
|
||||
len,
|
||||
&bytes);
|
||||
|
||||
if (rv != NO_ERROR)
|
||||
|
||||
if (rv != NO_ERROR)
|
||||
{
|
||||
/* ERROR_HANDLE_EOF can only be returned by async io */
|
||||
PR_ASSERT(rv != ERROR_HANDLE_EOF);
|
||||
if (rv == ERROR_BROKEN_PIPE)
|
||||
if (rv == ERROR_BROKEN_PIPE) {
|
||||
return 0;
|
||||
else {
|
||||
_PR_MD_MAP_READ_ERROR(rv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_PR_MD_MAP_READ_ERROR(rv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return (PRInt32)bytes;
|
||||
}
|
||||
|
|
@ -258,14 +270,14 @@ PRInt32
|
|||
_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
|
||||
{
|
||||
PRInt32 bytes;
|
||||
int rv;
|
||||
int rv;
|
||||
|
||||
rv = DosWrite((HFILE)fd->secret->md.osfd,
|
||||
(PVOID)buf,
|
||||
len,
|
||||
(PULONG)&bytes);
|
||||
|
||||
if (rv != NO_ERROR)
|
||||
if (rv != NO_ERROR)
|
||||
{
|
||||
_PR_MD_MAP_WRITE_ERROR(rv);
|
||||
return -1;
|
||||
|
|
@ -288,11 +300,12 @@ _PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
|
|||
|
||||
rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation);
|
||||
|
||||
if (rv != NO_ERROR) {
|
||||
_PR_MD_MAP_LSEEK_ERROR(rv);
|
||||
return -1;
|
||||
} else
|
||||
return newLocation;
|
||||
if (rv != NO_ERROR) {
|
||||
_PR_MD_MAP_LSEEK_ERROR(rv);
|
||||
return -1;
|
||||
} else {
|
||||
return newLocation;
|
||||
}
|
||||
}
|
||||
|
||||
PRInt64
|
||||
|
|
@ -306,14 +319,14 @@ _PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
|
|||
rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation);
|
||||
rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation);
|
||||
|
||||
if (rv != NO_ERROR) {
|
||||
_PR_MD_MAP_LSEEK_ERROR(rv);
|
||||
hi = newLocation = -1;
|
||||
}
|
||||
if (rv != NO_ERROR) {
|
||||
_PR_MD_MAP_LSEEK_ERROR(rv);
|
||||
hi = newLocation = -1;
|
||||
}
|
||||
|
||||
result.lo = newLocation;
|
||||
result.hi = hi;
|
||||
return result;
|
||||
return result;
|
||||
|
||||
#else
|
||||
PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32);
|
||||
|
|
@ -322,19 +335,19 @@ _PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
|
|||
PRUint64 newLocationL;
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case PR_SEEK_SET:
|
||||
where = FILE_BEGIN;
|
||||
break;
|
||||
case PR_SEEK_CUR:
|
||||
where = FILE_CURRENT;
|
||||
break;
|
||||
case PR_SEEK_END:
|
||||
where = FILE_END;
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
{
|
||||
case PR_SEEK_SET:
|
||||
where = FILE_BEGIN;
|
||||
break;
|
||||
case PR_SEEK_CUR:
|
||||
where = FILE_CURRENT;
|
||||
break;
|
||||
case PR_SEEK_END:
|
||||
where = FILE_END;
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
if (isWSEB)
|
||||
{
|
||||
|
|
@ -344,12 +357,12 @@ _PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
|
|||
{
|
||||
rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation);
|
||||
}
|
||||
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
_PR_MD_MAP_LSEEK_ERROR(rc);
|
||||
return -1;
|
||||
_PR_MD_MAP_LSEEK_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (isWSEB)
|
||||
{
|
||||
return newLocationL;
|
||||
|
|
@ -373,10 +386,10 @@ _PR_MD_FSYNC(PRFileDesc *fd)
|
|||
PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd);
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
if (rc != ERROR_ACCESS_DENIED) {
|
||||
_PR_MD_MAP_FSYNC_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
if (rc != ERROR_ACCESS_DENIED) {
|
||||
_PR_MD_MAP_FSYNC_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -385,10 +398,11 @@ PRInt32
|
|||
_MD_CloseFile(PRInt32 osfd)
|
||||
{
|
||||
PRInt32 rv;
|
||||
|
||||
|
||||
rv = DosClose((HFILE)osfd);
|
||||
if (rv != NO_ERROR)
|
||||
_PR_MD_MAP_CLOSE_ERROR(rv);
|
||||
if (rv != NO_ERROR) {
|
||||
_PR_MD_MAP_CLOSE_ERROR(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -400,10 +414,10 @@ _MD_CloseFile(PRInt32 osfd)
|
|||
void FlipSlashes(char *cp, int len)
|
||||
{
|
||||
while (--len >= 0) {
|
||||
if (cp[0] == '/') {
|
||||
cp[0] = PR_DIRECTORY_SEPARATOR;
|
||||
}
|
||||
cp++;
|
||||
if (cp[0] == '/') {
|
||||
cp[0] = PR_DIRECTORY_SEPARATOR;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,17 +431,17 @@ void FlipSlashes(char *cp, int len)
|
|||
PRInt32
|
||||
_PR_MD_CLOSE_DIR(_MDDir *d)
|
||||
{
|
||||
PRInt32 rc;
|
||||
PRInt32 rc;
|
||||
|
||||
if ( d ) {
|
||||
rc = DosFindClose(d->d_hdl);
|
||||
if(rc == NO_ERROR){
|
||||
d->magic = (PRUint32)-1;
|
||||
return PR_SUCCESS;
|
||||
} else {
|
||||
_PR_MD_MAP_CLOSEDIR_ERROR(rc);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
rc = DosFindClose(d->d_hdl);
|
||||
if(rc == NO_ERROR) {
|
||||
d->magic = (PRUint32)-1;
|
||||
return PR_SUCCESS;
|
||||
} else {
|
||||
_PR_MD_MAP_CLOSEDIR_ERROR(rc);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
|
|
@ -469,7 +483,7 @@ _PR_MD_OPEN_DIR(_MDDir *d, const char *name)
|
|||
FIL_STANDARD);
|
||||
}
|
||||
if ( rc != NO_ERROR ) {
|
||||
_PR_MD_MAP_OPENDIR_ERROR(rc);
|
||||
_PR_MD_MAP_OPENDIR_ERROR(rc);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
d->firstEntry = PR_TRUE;
|
||||
|
|
@ -486,42 +500,46 @@ _PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
|
|||
USHORT fileAttr;
|
||||
|
||||
if ( d ) {
|
||||
while (1) {
|
||||
if (d->firstEntry) {
|
||||
d->firstEntry = PR_FALSE;
|
||||
rv = NO_ERROR;
|
||||
} else {
|
||||
rv = DosFindNext(d->d_hdl,
|
||||
&(d->d_entry),
|
||||
sizeof(d->d_entry),
|
||||
&numFiles);
|
||||
}
|
||||
if (rv != NO_ERROR) {
|
||||
break;
|
||||
}
|
||||
fileName = GetFileFromDIR(d);
|
||||
fileAttr = GetFileAttr(d);
|
||||
if ( (flags & PR_SKIP_DOT) &&
|
||||
(fileName[0] == '.') && (fileName[1] == '\0'))
|
||||
while (1) {
|
||||
if (d->firstEntry) {
|
||||
d->firstEntry = PR_FALSE;
|
||||
rv = NO_ERROR;
|
||||
} else {
|
||||
rv = DosFindNext(d->d_hdl,
|
||||
&(d->d_entry),
|
||||
sizeof(d->d_entry),
|
||||
&numFiles);
|
||||
}
|
||||
if (rv != NO_ERROR) {
|
||||
break;
|
||||
}
|
||||
fileName = GetFileFromDIR(d);
|
||||
fileAttr = GetFileAttr(d);
|
||||
if ( (flags & PR_SKIP_DOT) &&
|
||||
(fileName[0] == '.') && (fileName[1] == '\0')) {
|
||||
continue;
|
||||
if ( (flags & PR_SKIP_DOT_DOT) &&
|
||||
(fileName[0] == '.') && (fileName[1] == '.') &&
|
||||
(fileName[2] == '\0'))
|
||||
}
|
||||
if ( (flags & PR_SKIP_DOT_DOT) &&
|
||||
(fileName[0] == '.') && (fileName[1] == '.') &&
|
||||
(fileName[2] == '\0')) {
|
||||
continue;
|
||||
/*
|
||||
* XXX
|
||||
* Is this the correct definition of a hidden file on OS/2?
|
||||
*/
|
||||
if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN))
|
||||
}
|
||||
/*
|
||||
* XXX
|
||||
* Is this the correct definition of a hidden file on OS/2?
|
||||
*/
|
||||
if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN)) {
|
||||
return fileName;
|
||||
else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN))
|
||||
}
|
||||
else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN)) {
|
||||
continue;
|
||||
return fileName;
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
PR_ASSERT(NO_ERROR != rv);
|
||||
_PR_MD_MAP_READDIR_ERROR(rv);
|
||||
_PR_MD_MAP_READDIR_ERROR(rv);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -533,7 +551,7 @@ _PR_MD_DELETE(const char *name)
|
|||
if(rc == NO_ERROR) {
|
||||
return 0;
|
||||
} else {
|
||||
_PR_MD_MAP_DELETE_ERROR(rc);
|
||||
_PR_MD_MAP_DELETE_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -558,7 +576,7 @@ _PR_MD_STAT(const char *fn, struct stat *info)
|
|||
* can be handled by _stat() on NT but not on Win95.
|
||||
*
|
||||
* We remove the backslash or slash at the end and
|
||||
* try again.
|
||||
* try again.
|
||||
*
|
||||
* Not sure if this happens on OS/2 or not,
|
||||
* but it doesn't hurt to be careful.
|
||||
|
|
@ -566,7 +584,7 @@ _PR_MD_STAT(const char *fn, struct stat *info)
|
|||
|
||||
int len = strlen(fn);
|
||||
if (len > 0 && len <= _MAX_PATH
|
||||
&& (fn[len - 1] == '\\' || fn[len - 1] == '/')) {
|
||||
&& (fn[len - 1] == '\\' || fn[len - 1] == '/')) {
|
||||
char newfn[_MAX_PATH + 1];
|
||||
|
||||
strcpy(newfn, fn);
|
||||
|
|
@ -587,15 +605,18 @@ _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
|
|||
struct stat sb;
|
||||
PRInt32 rv;
|
||||
PRInt64 s, s2us;
|
||||
|
||||
|
||||
if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) {
|
||||
if (info) {
|
||||
if (S_IFREG & sb.st_mode)
|
||||
if (S_IFREG & sb.st_mode) {
|
||||
info->type = PR_FILE_FILE ;
|
||||
else if (S_IFDIR & sb.st_mode)
|
||||
}
|
||||
else if (S_IFDIR & sb.st_mode) {
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
}
|
||||
else {
|
||||
info->type = PR_FILE_OTHER;
|
||||
}
|
||||
info->size = sb.st_size;
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
LL_I2L(s, sb.st_mtime);
|
||||
|
|
@ -622,7 +643,7 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
|
|||
LL_UI2L(info->size,info32.size);
|
||||
info->modifyTime = info32.modifyTime;
|
||||
info->creationTime = info32.creationTime;
|
||||
|
||||
|
||||
if (isWSEB)
|
||||
{
|
||||
APIRET rc ;
|
||||
|
|
@ -648,33 +669,35 @@ _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
|
|||
PRInt32
|
||||
_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
|
||||
{
|
||||
/* For once, the VAC compiler/library did a nice thing.
|
||||
* The file handle used by the C runtime is the same one
|
||||
* returned by the OS when you call DosOpen(). This means
|
||||
* that you can take an OS HFILE and use it with C file
|
||||
* functions. The only caveat is that you have to call
|
||||
* _setmode() first to initialize some junk. This is
|
||||
* immensely useful because I did not have a clue how to
|
||||
* implement this function otherwise. The windows folks
|
||||
* took the source from the Microsoft C library source, but
|
||||
* IBM wasn't kind enough to ship the source with VAC.
|
||||
* On second thought, the needed function could probably
|
||||
* be gotten from the OS/2 GNU library source, but the
|
||||
* point is now moot.
|
||||
*/
|
||||
struct stat hinfo;
|
||||
/* For once, the VAC compiler/library did a nice thing.
|
||||
* The file handle used by the C runtime is the same one
|
||||
* returned by the OS when you call DosOpen(). This means
|
||||
* that you can take an OS HFILE and use it with C file
|
||||
* functions. The only caveat is that you have to call
|
||||
* _setmode() first to initialize some junk. This is
|
||||
* immensely useful because I did not have a clue how to
|
||||
* implement this function otherwise. The windows folks
|
||||
* took the source from the Microsoft C library source, but
|
||||
* IBM wasn't kind enough to ship the source with VAC.
|
||||
* On second thought, the needed function could probably
|
||||
* be gotten from the OS/2 GNU library source, but the
|
||||
* point is now moot.
|
||||
*/
|
||||
struct stat hinfo;
|
||||
PRInt64 s, s2us;
|
||||
|
||||
_setmode(fd->secret->md.osfd, O_BINARY);
|
||||
if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) {
|
||||
_PR_MD_MAP_FSTAT_ERROR(errno);
|
||||
_PR_MD_MAP_FSTAT_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hinfo.st_mode & S_IFDIR)
|
||||
if (hinfo.st_mode & S_IFDIR) {
|
||||
info->type = PR_FILE_DIRECTORY;
|
||||
else
|
||||
}
|
||||
else {
|
||||
info->type = PR_FILE_FILE;
|
||||
}
|
||||
|
||||
info->size = hinfo.st_size;
|
||||
LL_I2L(s2us, PR_USEC_PER_SEC);
|
||||
|
|
@ -695,13 +718,13 @@ _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
|
|||
PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
|
||||
if (0 == rv)
|
||||
{
|
||||
info->type = info32.type;
|
||||
LL_UI2L(info->size,info32.size);
|
||||
|
||||
info->modifyTime = info32.modifyTime;
|
||||
info->creationTime = info32.creationTime;
|
||||
info->type = info32.type;
|
||||
LL_UI2L(info->size,info32.size);
|
||||
|
||||
info->modifyTime = info32.modifyTime;
|
||||
info->creationTime = info32.creationTime;
|
||||
}
|
||||
|
||||
|
||||
if (isWSEB)
|
||||
{
|
||||
APIRET rc ;
|
||||
|
|
@ -728,12 +751,12 @@ _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
|
|||
PRInt32
|
||||
_PR_MD_RENAME(const char *from, const char *to)
|
||||
{
|
||||
PRInt32 rc;
|
||||
PRInt32 rc;
|
||||
/* Does this work with dot-relative pathnames? */
|
||||
if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) {
|
||||
return 0;
|
||||
} else {
|
||||
_PR_MD_MAP_RENAME_ERROR(rc);
|
||||
_PR_MD_MAP_RENAME_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -741,35 +764,36 @@ _PR_MD_RENAME(const char *from, const char *to)
|
|||
PRInt32
|
||||
_PR_MD_ACCESS(const char *name, PRAccessHow how)
|
||||
{
|
||||
PRInt32 rv;
|
||||
PRInt32 rv;
|
||||
switch (how) {
|
||||
case PR_ACCESS_WRITE_OK:
|
||||
rv = access(name, 02);
|
||||
break;
|
||||
case PR_ACCESS_READ_OK:
|
||||
rv = access(name, 04);
|
||||
break;
|
||||
case PR_ACCESS_EXISTS:
|
||||
return access(name, 00);
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
case PR_ACCESS_WRITE_OK:
|
||||
rv = access(name, 02);
|
||||
break;
|
||||
case PR_ACCESS_READ_OK:
|
||||
rv = access(name, 04);
|
||||
break;
|
||||
case PR_ACCESS_EXISTS:
|
||||
return access(name, 00);
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_ACCESS_ERROR(errno);
|
||||
}
|
||||
if (rv < 0)
|
||||
_PR_MD_MAP_ACCESS_ERROR(errno);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
_PR_MD_MKDIR(const char *name, PRIntn mode)
|
||||
{
|
||||
PRInt32 rc;
|
||||
PRInt32 rc;
|
||||
/* XXXMB - how to translate the "mode"??? */
|
||||
if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
|
||||
return 0;
|
||||
} else {
|
||||
_PR_MD_MAP_MKDIR_ERROR(rc);
|
||||
_PR_MD_MAP_MKDIR_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -777,11 +801,11 @@ _PR_MD_MKDIR(const char *name, PRIntn mode)
|
|||
PRInt32
|
||||
_PR_MD_RMDIR(const char *name)
|
||||
{
|
||||
PRInt32 rc;
|
||||
PRInt32 rc;
|
||||
if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) {
|
||||
return 0;
|
||||
} else {
|
||||
_PR_MD_MAP_RMDIR_ERROR(rc);
|
||||
_PR_MD_MAP_RMDIR_ERROR(rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -792,7 +816,7 @@ _PR_MD_LOCKFILE(PRInt32 f)
|
|||
PRInt32 rv;
|
||||
FILELOCK lock, unlock;
|
||||
FILELOCKL lockL, unlockL;
|
||||
|
||||
|
||||
lock.lOffset = 0;
|
||||
lockL.lOffset = 0;
|
||||
lock.lRange = 0xffffffff;
|
||||
|
|
@ -811,20 +835,20 @@ _PR_MD_LOCKFILE(PRInt32 f)
|
|||
{
|
||||
if (isWSEB)
|
||||
{
|
||||
rv = myDosSetFileLocksL( (HFILE) f,
|
||||
&unlockL, &lockL,
|
||||
0, 0);
|
||||
rv = myDosSetFileLocksL( (HFILE) f,
|
||||
&unlockL, &lockL,
|
||||
0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = DosSetFileLocks( (HFILE) f,
|
||||
&unlock, &lock,
|
||||
0, 0);
|
||||
rv = DosSetFileLocks( (HFILE) f,
|
||||
&unlock, &lock,
|
||||
0, 0);
|
||||
}
|
||||
if ( rv != NO_ERROR )
|
||||
if ( rv != NO_ERROR )
|
||||
{
|
||||
DosSleep( 50 ); /* Sleep() a few milisecs and try again. */
|
||||
}
|
||||
}
|
||||
} /* end for() */
|
||||
return PR_SUCCESS;
|
||||
} /* end _PR_MD_LOCKFILE() */
|
||||
|
|
@ -842,7 +866,7 @@ _PR_MD_UNLOCKFILE(PRInt32 f)
|
|||
PRInt32 rv;
|
||||
FILELOCK lock, unlock;
|
||||
FILELOCKL lockL, unlockL;
|
||||
|
||||
|
||||
lock.lOffset = 0;
|
||||
lockL.lOffset = 0;
|
||||
lock.lRange = 0;
|
||||
|
|
@ -851,20 +875,20 @@ _PR_MD_UNLOCKFILE(PRInt32 f)
|
|||
unlockL.lOffset = 0;
|
||||
unlock.lRange = 0xffffffff;
|
||||
unlockL.lRange = 0xffffffffffffffff;
|
||||
|
||||
|
||||
if (isWSEB)
|
||||
{
|
||||
rv = myDosSetFileLocksL( (HFILE) f,
|
||||
&unlockL, &lockL,
|
||||
0, 0);
|
||||
&unlockL, &lockL,
|
||||
0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = DosSetFileLocks( (HFILE) f,
|
||||
&unlock, &lock,
|
||||
0, 0);
|
||||
&unlock, &lock,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
|
||||
if ( rv != NO_ERROR )
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
|
|
@ -890,10 +914,12 @@ _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
|
|||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if (inheritable)
|
||||
flags &= ~OPEN_FLAGS_NOINHERIT;
|
||||
else
|
||||
flags |= OPEN_FLAGS_NOINHERIT;
|
||||
if (inheritable) {
|
||||
flags &= ~OPEN_FLAGS_NOINHERIT;
|
||||
}
|
||||
else {
|
||||
flags |= OPEN_FLAGS_NOINHERIT;
|
||||
}
|
||||
|
||||
/* Mask off flags DosSetFHState don't want. */
|
||||
flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ PR_Now(void)
|
|||
LL_MUL(ms, ms, ms2us);
|
||||
LL_MUL(s, s, s2us);
|
||||
LL_ADD(s, s, ms);
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ static int assembleCmdLine(char *const *argv, char **cmdLine)
|
|||
strcat(*cmdLine, " ");
|
||||
}
|
||||
strcat(*cmdLine, *arg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -150,15 +150,16 @@ static int assembleEnvBlock(char **envp, char **envBlock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR)
|
||||
return -1;
|
||||
if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
curEnv = ppib->pib_pchenv;
|
||||
|
||||
cwdStart = curEnv;
|
||||
while (*cwdStart) {
|
||||
if (cwdStart[0] == '=' && cwdStart[1] != '\0'
|
||||
&& cwdStart[2] == ':' && cwdStart[3] == '=') {
|
||||
&& cwdStart[2] == ':' && cwdStart[3] == '=') {
|
||||
break;
|
||||
}
|
||||
cwdStart += strlen(cwdStart) + 1;
|
||||
|
|
@ -168,7 +169,7 @@ static int assembleEnvBlock(char **envp, char **envBlock)
|
|||
cwdEnd += strlen(cwdEnd) + 1;
|
||||
while (*cwdEnd) {
|
||||
if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
|
||||
|| cwdEnd[2] != ':' || cwdEnd[3] != '=') {
|
||||
|| cwdEnd[2] != ':' || cwdEnd[3] != '=') {
|
||||
break;
|
||||
}
|
||||
cwdEnd += strlen(cwdEnd) + 1;
|
||||
|
|
@ -221,7 +222,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
char *cmdLine = NULL;
|
||||
char **newEnvp = NULL;
|
||||
char *envBlock = NULL;
|
||||
|
||||
|
||||
STARTDATA startData = {0};
|
||||
APIRET rc;
|
||||
ULONG ulAppType = 0;
|
||||
|
|
@ -250,7 +251,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
|
||||
if (assembleCmdLine(argv, &cmdLine) == -1) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto errorExit;
|
||||
|
|
@ -260,7 +261,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
/*
|
||||
* DosQueryAppType() fails if path (the char* in the first argument) is in
|
||||
* high memory. If that is the case, the following moves it to low memory.
|
||||
*/
|
||||
*/
|
||||
if ((ULONG)path >= 0x20000000) {
|
||||
size_t len = strlen(path) + 1;
|
||||
char *copy = (char *)alloca(len);
|
||||
|
|
@ -268,7 +269,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
path = copy;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (envp == NULL) {
|
||||
newEnvp = NULL;
|
||||
} else {
|
||||
|
|
@ -287,27 +288,27 @@ PRProcess * _PR_CreateOS2Process(
|
|||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
|
||||
rc = DosQueryAppType(path, &ulAppType);
|
||||
if (rc != NO_ERROR) {
|
||||
char *pszDot = strrchr(path, '.');
|
||||
if (pszDot) {
|
||||
/* If it is a CMD file, launch the users command processor */
|
||||
if (!stricmp(pszDot, ".cmd")) {
|
||||
rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec);
|
||||
if (!rc) {
|
||||
strcpy(pszFormatString, "/C %s %s");
|
||||
strcpy(pszEXEName, pszComSpec);
|
||||
ulAppType = FAPPTYP_WINDOWCOMPAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
char *pszDot = strrchr(path, '.');
|
||||
if (pszDot) {
|
||||
/* If it is a CMD file, launch the users command processor */
|
||||
if (!stricmp(pszDot, ".cmd")) {
|
||||
rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec);
|
||||
if (!rc) {
|
||||
strcpy(pszFormatString, "/C %s %s");
|
||||
strcpy(pszEXEName, pszComSpec);
|
||||
ulAppType = FAPPTYP_WINDOWCOMPAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ulAppType == 0) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
goto errorExit;
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
|
||||
if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
|
||||
startData.SessionType = SSF_TYPE_PM;
|
||||
}
|
||||
|
|
@ -317,16 +318,16 @@ PRProcess * _PR_CreateOS2Process(
|
|||
else {
|
||||
startData.SessionType = SSF_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
|
||||
{
|
||||
strcpy(pszEXEName, "WINOS2.COM");
|
||||
startData.SessionType = PROG_31_STDSEAMLESSVDM;
|
||||
strcpy(pszFormatString, "/3 %s %s");
|
||||
}
|
||||
|
||||
|
||||
startData.InheritOpt = SSF_INHERTOPT_SHELL;
|
||||
|
||||
|
||||
if (pszEXEName[0]) {
|
||||
pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
|
||||
sprintf(pszFormatResult, pszFormatString, path, cmdLine);
|
||||
|
|
@ -336,13 +337,13 @@ PRProcess * _PR_CreateOS2Process(
|
|||
startData.PgmInputs = cmdLine;
|
||||
}
|
||||
startData.PgmName = pszEXEName;
|
||||
|
||||
|
||||
startData.Length = sizeof(startData);
|
||||
startData.Related = SSF_RELATED_INDEPENDENT;
|
||||
startData.ObjectBuffer = pszObjectBuffer;
|
||||
startData.ObjectBuffLen = CCHMAXPATH;
|
||||
startData.Environment = envBlock;
|
||||
|
||||
|
||||
if (attr) {
|
||||
/* On OS/2, there is really no way to pass file handles for stdin,
|
||||
* stdout, and stderr to a new process. Instead, we can make it
|
||||
|
|
@ -407,7 +408,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
}
|
||||
|
||||
proc->md.pid = procInfo.codeTerminate;
|
||||
} else {
|
||||
} else {
|
||||
/*
|
||||
* If no STDIN/STDOUT redirection is not needed, use DosStartSession
|
||||
* to create a new, independent session
|
||||
|
|
@ -418,7 +419,7 @@ PRProcess * _PR_CreateOS2Process(
|
|||
PR_SetError(PR_UNKNOWN_ERROR, rc);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
|
||||
proc->md.pid = pid;
|
||||
}
|
||||
|
||||
|
|
@ -453,7 +454,7 @@ errorExit:
|
|||
|
||||
PRStatus _PR_DetachOS2Process(PRProcess *process)
|
||||
{
|
||||
/* On OS/2, a process is either created as a child or not.
|
||||
/* On OS/2, a process is either created as a child or not.
|
||||
* You can't 'detach' it later on.
|
||||
*/
|
||||
PR_DELETE(process);
|
||||
|
|
@ -464,18 +465,18 @@ PRStatus _PR_DetachOS2Process(PRProcess *process)
|
|||
* XXX: This will currently only work on a child process.
|
||||
*/
|
||||
PRStatus _PR_WaitOS2Process(PRProcess *process,
|
||||
PRInt32 *exitCode)
|
||||
PRInt32 *exitCode)
|
||||
{
|
||||
ULONG ulRetVal;
|
||||
RESULTCODES results;
|
||||
PID pidEnded = 0;
|
||||
|
||||
ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT,
|
||||
ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT,
|
||||
&results,
|
||||
&pidEnded, process->md.pid);
|
||||
|
||||
if (ulRetVal != NO_ERROR) {
|
||||
printf("\nDosWaitChild rc = %lu\n", ulRetVal);
|
||||
printf("\nDosWaitChild rc = %lu\n", ulRetVal);
|
||||
PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -485,9 +486,9 @@ PRStatus _PR_WaitOS2Process(PRProcess *process,
|
|||
|
||||
PRStatus _PR_KillOS2Process(PRProcess *process)
|
||||
{
|
||||
ULONG ulRetVal;
|
||||
ULONG ulRetVal;
|
||||
if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) {
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
|
||||
return PR_FAILURE;
|
||||
|
|
@ -501,7 +502,7 @@ PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
|
|||
if (0 == rv) {
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
_PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
|
||||
_PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +510,7 @@ void
|
|||
_PR_MD_WAKEUP_CPUS( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
|
|
|
|||
|
|
@ -16,16 +16,17 @@
|
|||
|
||||
PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count )
|
||||
{
|
||||
int i;
|
||||
PRBool isSet = PR_FALSE;
|
||||
int i;
|
||||
PRBool isSet = PR_FALSE;
|
||||
|
||||
for( i = start; i < start+count; i++ )
|
||||
{
|
||||
if( socks[i] == osfd )
|
||||
isSet = PR_TRUE;
|
||||
}
|
||||
|
||||
return isSet;
|
||||
for( i = start; i < start+count; i++ )
|
||||
{
|
||||
if( socks[i] == osfd ) {
|
||||
isSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return isSet;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
wt = 0;
|
||||
ex = 0;
|
||||
socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
|
||||
|
||||
|
||||
if (!socks)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
|
|
@ -74,12 +75,12 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
if (pd->in_flags & PR_POLL_READ)
|
||||
{
|
||||
in_flags_read = (pd->fd->methods->poll)(
|
||||
pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
|
||||
pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_WRITE)
|
||||
{
|
||||
in_flags_write = (pd->fd->methods->poll)(
|
||||
pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
|
||||
pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
|
||||
}
|
||||
if ((0 != (in_flags_read & out_flags_read)) ||
|
||||
(0 != (in_flags_write & out_flags_write)))
|
||||
|
|
@ -115,8 +116,9 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
if (0 == ready)
|
||||
{
|
||||
PRInt32 osfd = bottom->secret->md.osfd;
|
||||
if (osfd > maxfd)
|
||||
if (osfd > maxfd) {
|
||||
maxfd = osfd;
|
||||
}
|
||||
if (in_flags_read & PR_POLL_READ)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_READ_SYS_READ;
|
||||
|
|
@ -124,7 +126,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
FD_SET(osfd, &rd);
|
||||
#else
|
||||
socks[rd] = osfd;
|
||||
rd++;
|
||||
rd++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_read & PR_POLL_WRITE)
|
||||
|
|
@ -134,7 +136,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
FD_SET(osfd, &wt);
|
||||
#else
|
||||
socks[npds+wt] = osfd;
|
||||
wt++;
|
||||
wt++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_write & PR_POLL_READ)
|
||||
|
|
@ -144,7 +146,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
FD_SET(osfd, &rd);
|
||||
#else
|
||||
socks[rd] = osfd;
|
||||
rd++;
|
||||
rd++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_write & PR_POLL_WRITE)
|
||||
|
|
@ -154,7 +156,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
|||
FD_SET(osfd, &wt);
|
||||
#else
|
||||
socks[npds+wt] = osfd;
|
||||
wt++;
|
||||
wt++;
|
||||
#endif
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_EXCEPT)
|
||||
|
|
@ -224,24 +226,28 @@ retry:
|
|||
msecs = PR_IntervalToMilliseconds(remaining);
|
||||
}
|
||||
|
||||
/* compact array */
|
||||
for( i = rd, j = npds; j < npds+wt; i++,j++ )
|
||||
/* compact array */
|
||||
for( i = rd, j = npds; j < npds+wt; i++,j++ ) {
|
||||
socks[i] = socks[j];
|
||||
for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
|
||||
}
|
||||
for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ ) {
|
||||
socks[i] = socks[j];
|
||||
|
||||
}
|
||||
|
||||
ready = os2_select(socks, rd, wt, ex, msecs);
|
||||
#endif
|
||||
|
||||
if (ready == -1 && errno == EINTR)
|
||||
{
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT)
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
|
||||
if (elapsed > timeout)
|
||||
ready = 0; /* timed out */
|
||||
if (elapsed > timeout) {
|
||||
ready = 0; /* timed out */
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining = timeout - elapsed;
|
||||
|
|
@ -272,38 +278,44 @@ retry:
|
|||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &rd))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, 0, rd) )
|
||||
if( IsSocketSet(osfd, socks, 0, rd) )
|
||||
#endif
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_READ)
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_READ) {
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
|
||||
}
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) {
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &wt))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, rd, wt) )
|
||||
if( IsSocketSet(osfd, socks, rd, wt) )
|
||||
#endif
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) {
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
|
||||
}
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) {
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &ex))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, rd+wt, ex) )
|
||||
if( IsSocketSet(osfd, socks, rd+wt, ex) )
|
||||
#endif
|
||||
{
|
||||
out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
}
|
||||
pd->out_flags = out_flags;
|
||||
if (out_flags) ready++;
|
||||
if (out_flags) {
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
|
|
@ -323,7 +335,7 @@ retry:
|
|||
{
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
|
||||
SO_TYPE, (char *) &optval, &optlen) == -1)
|
||||
SO_TYPE, (char *) &optval, &optlen) == -1)
|
||||
{
|
||||
PR_ASSERT(sock_errno() == ENOTSOCK);
|
||||
if (sock_errno() == ENOTSOCK)
|
||||
|
|
@ -336,8 +348,9 @@ retry:
|
|||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
else
|
||||
else {
|
||||
_PR_MD_MAP_SELECT_ERROR(err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BSD_SELECT
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
|
|||
QWORD qword = {0,0};
|
||||
|
||||
rc = DosTmrQueryTime(&qword);
|
||||
if (rc != NO_ERROR)
|
||||
return FALSE;
|
||||
if (rc != NO_ERROR) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*phigh = qword.ulHi;
|
||||
*plow = qword.ulLo;
|
||||
|
|
@ -35,8 +36,9 @@ extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size )
|
|||
int nBytes = 0;
|
||||
time_t sTime;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
if (size <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
clockTickTime(&high, &low);
|
||||
|
||||
|
|
@ -46,16 +48,18 @@ extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size )
|
|||
n += nBytes;
|
||||
size -= nBytes;
|
||||
|
||||
if (size <= 0)
|
||||
return n;
|
||||
if (size <= 0) {
|
||||
return n;
|
||||
}
|
||||
|
||||
nBytes = sizeof(high) > size ? size : sizeof(high);
|
||||
memcpy(((char *)buf) + n, &high, nBytes);
|
||||
n += nBytes;
|
||||
size -= nBytes;
|
||||
|
||||
if (size <= 0)
|
||||
return n;
|
||||
if (size <= 0) {
|
||||
return n;
|
||||
}
|
||||
|
||||
/* get the number of milliseconds that have elapsed since application started */
|
||||
val = clock();
|
||||
|
|
@ -65,8 +69,9 @@ extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size )
|
|||
n += nBytes;
|
||||
size -= nBytes;
|
||||
|
||||
if (size <= 0)
|
||||
return n;
|
||||
if (size <= 0) {
|
||||
return n;
|
||||
}
|
||||
|
||||
/* get the time in seconds since midnight Jan 1, 1970 */
|
||||
time(&sTime);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
void
|
||||
_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
|
||||
{
|
||||
int rv;
|
||||
int rv;
|
||||
|
||||
/* Our Sems don't support a value > 1 */
|
||||
PR_ASSERT(value <= 1);
|
||||
|
|
@ -26,9 +26,9 @@ _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
|
|||
void
|
||||
_PR_MD_DESTROY_SEM(_MDSemaphore *md)
|
||||
{
|
||||
int rv;
|
||||
rv = DosCloseEventSem(md->sem);
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
int rv;
|
||||
rv = DosCloseEventSem(md->sem);
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -38,10 +38,12 @@ _PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks)
|
|||
int rv;
|
||||
rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks));
|
||||
|
||||
if (rv == NO_ERROR)
|
||||
if (rv == NO_ERROR) {
|
||||
return PR_SUCCESS;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -53,9 +55,9 @@ _PR_MD_WAIT_SEM(_MDSemaphore *md)
|
|||
void
|
||||
_PR_MD_POST_SEM(_MDSemaphore *md)
|
||||
{
|
||||
int rv;
|
||||
rv = DosPostEventSem(md->sem);
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
int rv;
|
||||
rv = DosPostEventSem(md->sem);
|
||||
PR_ASSERT(rv == NO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes */
|
||||
/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */
|
||||
/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2 */
|
||||
/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info. */
|
||||
/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info. */
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ _PR_MD_SOCKET(int domain, int type, int flags)
|
|||
|
||||
osfd = socket(domain, type, flags);
|
||||
|
||||
if (osfd == -1)
|
||||
if (osfd == -1)
|
||||
{
|
||||
err = sock_errno();
|
||||
_PR_MD_MAP_SOCKET_ERROR(err);
|
||||
|
|
@ -101,19 +101,23 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
|
|||
FD_ZERO(&rd_wr);
|
||||
do {
|
||||
FD_SET(osfd, &rd_wr);
|
||||
if (fd_type == READ_FD)
|
||||
if (fd_type == READ_FD) {
|
||||
rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
|
||||
else
|
||||
}
|
||||
else {
|
||||
rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
|
||||
}
|
||||
#else
|
||||
lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
|
||||
lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
|
||||
do {
|
||||
socks[0] = osfd;
|
||||
if (fd_type == READ_FD)
|
||||
if (fd_type == READ_FD) {
|
||||
rv = os2_select(socks, 1, 0, 0, lTimeout);
|
||||
else
|
||||
}
|
||||
else {
|
||||
rv = os2_select(socks, 0, 1, 0, lTimeout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (rv == -1 && (syserror = sock_errno()) != EINTR) {
|
||||
_PR_MD_MAP_SELECT_ERROR(syserror);
|
||||
break;
|
||||
|
|
@ -148,14 +152,16 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
|
|||
tv.tv_usec = 0;
|
||||
} else {
|
||||
tv.tv_usec = PR_IntervalToMicroseconds(
|
||||
remaining -
|
||||
PR_SecondsToInterval(tv.tv_sec));
|
||||
remaining -
|
||||
PR_SecondsToInterval(tv.tv_sec));
|
||||
}
|
||||
FD_SET(osfd, &rd_wr);
|
||||
if (fd_type == READ_FD)
|
||||
if (fd_type == READ_FD) {
|
||||
rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
|
||||
else
|
||||
}
|
||||
else {
|
||||
rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
|
||||
}
|
||||
#else
|
||||
wait_for_remaining = PR_TRUE;
|
||||
lTimeout = PR_IntervalToMilliseconds(remaining);
|
||||
|
|
@ -164,10 +170,12 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
|
|||
lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
|
||||
}
|
||||
socks[0] = osfd;
|
||||
if (fd_type == READ_FD)
|
||||
if (fd_type == READ_FD) {
|
||||
rv = os2_select(socks, 1, 0, 0, lTimeout);
|
||||
else
|
||||
}
|
||||
else {
|
||||
rv = os2_select(socks, 0, 1, 0, lTimeout);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* we don't consider EINTR a real error
|
||||
|
|
@ -198,7 +206,7 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
|
|||
} else {
|
||||
#ifdef BSD_SELECT
|
||||
now += PR_SecondsToInterval(tv.tv_sec)
|
||||
+ PR_MicrosecondsToInterval(tv.tv_usec);
|
||||
+ PR_MicrosecondsToInterval(tv.tv_usec);
|
||||
#else
|
||||
now += PR_MillisecondsToInterval(lTimeout);
|
||||
#endif
|
||||
|
|
@ -217,7 +225,7 @@ socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
|
|||
}
|
||||
} while (rv == 0 || (rv == -1 && syserror == EINTR));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +245,10 @@ _MD_Accept(PRFileDesc *fd, PRNetAddr *addr,
|
|||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) {
|
||||
goto done;
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -253,7 +262,7 @@ done:
|
|||
}
|
||||
|
||||
PRInt32
|
||||
_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
|
||||
_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 rv, err;
|
||||
|
|
@ -263,17 +272,17 @@ _PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
|
|||
* modifies the sockaddr structure.
|
||||
* See Bugzilla bug 100776. */
|
||||
|
||||
/*
|
||||
* We initiate the connection setup by making a nonblocking connect()
|
||||
* call. If the connect() call fails, there are two cases we handle
|
||||
* specially:
|
||||
* 1. The connect() call was interrupted by a signal. In this case
|
||||
* we simply retry connect().
|
||||
* 2. The NSPR socket is nonblocking and connect() fails with
|
||||
* EINPROGRESS. We first wait until the socket becomes writable.
|
||||
* Then we try to find out whether the connection setup succeeded
|
||||
* or failed.
|
||||
*/
|
||||
/*
|
||||
* We initiate the connection setup by making a nonblocking connect()
|
||||
* call. If the connect() call fails, there are two cases we handle
|
||||
* specially:
|
||||
* 1. The connect() call was interrupted by a signal. In this case
|
||||
* we simply retry connect().
|
||||
* 2. The NSPR socket is nonblocking and connect() fails with
|
||||
* EINPROGRESS. We first wait until the socket becomes writable.
|
||||
* Then we try to find out whether the connection setup succeeded
|
||||
* or failed.
|
||||
*/
|
||||
|
||||
retry:
|
||||
if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1)
|
||||
|
|
@ -313,7 +322,7 @@ retry:
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +356,7 @@ _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
|
|||
|
||||
|
||||
PRInt32
|
||||
_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
|
||||
_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
|
|
@ -361,9 +370,10 @@ _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
|
|||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) {
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -391,20 +401,21 @@ _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
|
|||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) {
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next send() call will return EWOULDBLOCK.
|
||||
*/
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next send() call will return EWOULDBLOCK.
|
||||
*/
|
||||
if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
|
||||
&& (timeout != PR_INTERVAL_NO_WAIT))
|
||||
{
|
||||
|
|
@ -428,7 +439,7 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
|
|||
PRInt32 rv, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
while ((rv = sendto(osfd, buf, amount, flags,
|
||||
(struct sockaddr *) addr, addrlen)) == -1)
|
||||
(struct sockaddr *) addr, addrlen)) == -1)
|
||||
{
|
||||
err = sock_errno();
|
||||
if ((err == EWOULDBLOCK))
|
||||
|
|
@ -436,9 +447,10 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
|
|||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) {
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -461,16 +473,17 @@ _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
|
|||
|
||||
while( (*addrlen = PR_NETADDR_SIZE(addr)),
|
||||
((rv = recvfrom(osfd, buf, amount, flags,
|
||||
(struct sockaddr *) addr, (int *)addrlen)) == -1))
|
||||
(struct sockaddr *) addr, (int *)addrlen)) == -1))
|
||||
{
|
||||
err = sock_errno();
|
||||
if ((err == EWOULDBLOCK)) {
|
||||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
|
||||
if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) {
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -506,13 +519,13 @@ _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
|
|||
osiov[index].iov_len = iov[index].iov_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the total number of bytes to be sent; needed for
|
||||
* optimization later.
|
||||
* We could avoid this if this number was passed in; but it is
|
||||
* probably not a big deal because iov_size is usually small (less than
|
||||
* 3)
|
||||
*/
|
||||
/*
|
||||
* Calculate the total number of bytes to be sent; needed for
|
||||
* optimization later.
|
||||
* We could avoid this if this number was passed in; but it is
|
||||
* probably not a big deal because iov_size is usually small (less than
|
||||
* 3)
|
||||
*/
|
||||
if (!fd->secret->nonblocking) {
|
||||
for (index=0; index<iov_size; index++) {
|
||||
amount += iov[index].iov_len;
|
||||
|
|
@ -525,22 +538,23 @@ _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
|
|||
if (fd->secret->nonblocking) {
|
||||
break;
|
||||
}
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
|
||||
if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) {
|
||||
goto done;
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
|
||||
}
|
||||
} else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next writev() call will return EWOULDBLOCK.
|
||||
*/
|
||||
/*
|
||||
* optimization; if bytes sent is less than "amount" call
|
||||
* select before returning. This is because it is likely that
|
||||
* the next writev() call will return EWOULDBLOCK.
|
||||
*/
|
||||
if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
|
||||
&& (timeout != PR_INTERVAL_NO_WAIT)) {
|
||||
&& (timeout != PR_INTERVAL_NO_WAIT)) {
|
||||
if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
|
||||
rv = -1;
|
||||
goto done;
|
||||
|
|
@ -559,8 +573,9 @@ _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
|
|||
PRInt32 rv;
|
||||
|
||||
rv = shutdown(fd->secret->md.osfd, how);
|
||||
if (rv < 0)
|
||||
if (rv < 0) {
|
||||
_PR_MD_MAP_SHUTDOWN_ERROR(sock_errno());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +654,7 @@ _MD_MakeNonblock(PRFileDesc *fd)
|
|||
PRInt32 osfd = fd->secret->md.osfd;
|
||||
PRInt32 err;
|
||||
PRUint32 one = 1;
|
||||
|
||||
|
||||
if (osfd <= 2) {
|
||||
/* Don't mess around with stdin, stdout or stderr */
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -16,37 +16,37 @@ APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
|
|||
void
|
||||
_PR_MD_ENSURE_TLS(void)
|
||||
{
|
||||
if(!pThreadLocalStorage)
|
||||
{
|
||||
/* Allocate thread local storage (TLS). Note, that only 32 bytes can
|
||||
* be allocated at a time.
|
||||
*/
|
||||
int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
|
||||
PR_ASSERT(rc == NO_ERROR);
|
||||
memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS));
|
||||
}
|
||||
if(!pThreadLocalStorage)
|
||||
{
|
||||
/* Allocate thread local storage (TLS). Note, that only 32 bytes can
|
||||
* be allocated at a time.
|
||||
*/
|
||||
int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
|
||||
PR_ASSERT(rc == NO_ERROR);
|
||||
memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_PR_MD_EARLY_INIT()
|
||||
{
|
||||
HMODULE hmod;
|
||||
HMODULE hmod;
|
||||
|
||||
if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0)
|
||||
DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
|
||||
(PFN *)&QueryThreadContext);
|
||||
if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0)
|
||||
DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
|
||||
(PFN *)&QueryThreadContext);
|
||||
}
|
||||
|
||||
static void
|
||||
_pr_SetThreadMDHandle(PRThread *thread)
|
||||
{
|
||||
PTIB ptib;
|
||||
PPIB ppib;
|
||||
PRUword rc;
|
||||
PTIB ptib;
|
||||
PPIB ppib;
|
||||
PRUword rc;
|
||||
|
||||
rc = DosGetInfoBlocks(&ptib, &ppib);
|
||||
rc = DosGetInfoBlocks(&ptib, &ppib);
|
||||
|
||||
thread->md.handle = ptib->tib_ptib2->tib2_ultid;
|
||||
thread->md.handle = ptib->tib_ptib2->tib2_ultid;
|
||||
}
|
||||
|
||||
/* On OS/2, some system function calls seem to change the FPU control word,
|
||||
|
|
@ -134,15 +134,15 @@ PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg)
|
|||
PRStatus
|
||||
_PR_MD_INIT_THREAD(PRThread *thread)
|
||||
{
|
||||
APIRET rv;
|
||||
APIRET rv;
|
||||
|
||||
if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
|
||||
_pr_SetThreadMDHandle(thread);
|
||||
}
|
||||
if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
|
||||
_pr_SetThreadMDHandle(thread);
|
||||
}
|
||||
|
||||
/* Create the blocking IO semaphore */
|
||||
rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0);
|
||||
return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE;
|
||||
/* Create the blocking IO semaphore */
|
||||
rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0);
|
||||
return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
|
||||
typedef struct param_store
|
||||
|
|
@ -169,20 +169,20 @@ ExcpStartFunc(void* arg)
|
|||
}
|
||||
|
||||
PRStatus
|
||||
_PR_MD_CREATE_THREAD(PRThread *thread,
|
||||
void (*start)(void *),
|
||||
PRThreadPriority priority,
|
||||
PRThreadScope scope,
|
||||
PRThreadState state,
|
||||
PRUint32 stackSize)
|
||||
_PR_MD_CREATE_THREAD(PRThread *thread,
|
||||
void (*start)(void *),
|
||||
PRThreadPriority priority,
|
||||
PRThreadScope scope,
|
||||
PRThreadState state,
|
||||
PRUint32 stackSize)
|
||||
{
|
||||
PARAMSTORE* params = PR_Malloc(sizeof(PARAMSTORE));
|
||||
params->start = start;
|
||||
params->thread = thread;
|
||||
thread->md.handle = thread->id = (TID) _beginthread(ExcpStartFunc,
|
||||
NULL,
|
||||
thread->stack->stackSize,
|
||||
params);
|
||||
NULL,
|
||||
thread->stack->stackSize,
|
||||
params);
|
||||
if(thread->md.handle == -1) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -232,7 +232,7 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
|
|||
PR_ASSERT(rv == NO_ERROR);
|
||||
if (rv != NO_ERROR) {
|
||||
PR_LOG(_pr_thread_lm, PR_LOG_MIN,
|
||||
("PR_SetThreadPriority: can't set thread priority\n"));
|
||||
("PR_SetThreadPriority: can't set thread priority\n"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -268,41 +268,41 @@ _PR_MD_EXIT(PRIntn status)
|
|||
}
|
||||
|
||||
#ifdef HAVE_THREAD_AFFINITY
|
||||
PR_EXTERN(PRInt32)
|
||||
PR_EXTERN(PRInt32)
|
||||
_PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
|
||||
{
|
||||
/* Can we do this on OS/2? Only on SMP versions? */
|
||||
PR_NOT_REACHED("Not implemented");
|
||||
return 0;
|
||||
/* Can we do this on OS/2? Only on SMP versions? */
|
||||
PR_NOT_REACHED("Not implemented");
|
||||
return 0;
|
||||
|
||||
/* This is what windows does:
|
||||
int rv;
|
||||
/* This is what windows does:
|
||||
int rv;
|
||||
|
||||
rv = SetThreadAffinityMask(thread->md.handle, mask);
|
||||
rv = SetThreadAffinityMask(thread->md.handle, mask);
|
||||
|
||||
return rv?0:-1;
|
||||
*/
|
||||
return rv?0:-1;
|
||||
*/
|
||||
}
|
||||
|
||||
PR_EXTERN(PRInt32)
|
||||
_PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
|
||||
{
|
||||
/* Can we do this on OS/2? Only on SMP versions? */
|
||||
PR_NOT_REACHED("Not implemented");
|
||||
return 0;
|
||||
/* Can we do this on OS/2? Only on SMP versions? */
|
||||
PR_NOT_REACHED("Not implemented");
|
||||
return 0;
|
||||
|
||||
/* This is what windows does:
|
||||
PRInt32 rv, system_mask;
|
||||
/* This is what windows does:
|
||||
PRInt32 rv, system_mask;
|
||||
|
||||
rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
|
||||
|
||||
return rv?0:-1;
|
||||
*/
|
||||
rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
|
||||
|
||||
return rv?0:-1;
|
||||
*/
|
||||
}
|
||||
#endif /* HAVE_THREAD_AFFINITY */
|
||||
|
||||
void
|
||||
_PR_MD_SUSPEND_CPU(_PRCPU *cpu)
|
||||
_PR_MD_SUSPEND_CPU(_PRCPU *cpu)
|
||||
{
|
||||
_PR_MD_SUSPEND_THREAD(cpu->thread);
|
||||
}
|
||||
|
|
@ -317,13 +317,13 @@ void
|
|||
_PR_MD_SUSPEND_THREAD(PRThread *thread)
|
||||
{
|
||||
if (_PR_IS_NATIVE_THREAD(thread)) {
|
||||
APIRET rc;
|
||||
APIRET rc;
|
||||
|
||||
/* XXXMB - DosSuspendThread() is not a blocking call; how do we
|
||||
* know when the thread is *REALLY* suspended?
|
||||
*/
|
||||
rc = DosSuspendThread(thread->md.handle);
|
||||
PR_ASSERT(rc == NO_ERROR);
|
||||
rc = DosSuspendThread(thread->md.handle);
|
||||
PR_ASSERT(rc == NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef XP_BEOS
|
||||
#include <OS.h>
|
||||
#endif
|
||||
|
||||
PRInt32 _pr_pageShift;
|
||||
|
|
@ -24,14 +21,14 @@ PRInt32 _pr_pageSize;
|
|||
*/
|
||||
static void GetPageSize(void)
|
||||
{
|
||||
PRInt32 pageSize;
|
||||
PRInt32 pageSize;
|
||||
|
||||
/* Get page size */
|
||||
#ifdef XP_UNIX
|
||||
#if defined BSDI || defined AIX \
|
||||
|| defined LINUX || defined __GNU__ || defined __GLIBC__ \
|
||||
|| defined FREEBSD || defined NETBSD || defined OPENBSD \
|
||||
|| defined DARWIN || defined SYMBIAN
|
||||
|| defined DARWIN
|
||||
_pr_pageSize = getpagesize();
|
||||
#elif defined(HPUX)
|
||||
/* I have no idea. Don't get me started. --Rob */
|
||||
|
|
@ -41,10 +38,6 @@ static void GetPageSize(void)
|
|||
#endif
|
||||
#endif /* XP_UNIX */
|
||||
|
||||
#ifdef XP_BEOS
|
||||
_pr_pageSize = B_PAGE_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef XP_PC
|
||||
#ifdef _WIN32
|
||||
SYSTEM_INFO info;
|
||||
|
|
@ -55,14 +48,14 @@ static void GetPageSize(void)
|
|||
#endif
|
||||
#endif /* XP_PC */
|
||||
|
||||
pageSize = _pr_pageSize;
|
||||
PR_CEILING_LOG2(_pr_pageShift, pageSize);
|
||||
pageSize = _pr_pageSize;
|
||||
PR_CEILING_LOG2(_pr_pageShift, pageSize);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRInt32) PR_GetPageShift(void)
|
||||
{
|
||||
if (!_pr_pageSize) {
|
||||
GetPageSize();
|
||||
GetPageSize();
|
||||
}
|
||||
return _pr_pageShift;
|
||||
}
|
||||
|
|
@ -70,7 +63,7 @@ PR_IMPLEMENT(PRInt32) PR_GetPageShift(void)
|
|||
PR_IMPLEMENT(PRInt32) PR_GetPageSize(void)
|
||||
{
|
||||
if (!_pr_pageSize) {
|
||||
GetPageSize();
|
||||
GetPageSize();
|
||||
}
|
||||
return _pr_pageSize;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
||||
|
|
@ -73,7 +73,7 @@ int _pr_aix_send_file_use_disabled = 0;
|
|||
void _MD_EarlyInit(void)
|
||||
{
|
||||
void *main_app_handle;
|
||||
char *evp;
|
||||
char *evp;
|
||||
|
||||
main_app_handle = dlopen(NULL, RTLD_NOW);
|
||||
PR_ASSERT(NULL != main_app_handle);
|
||||
|
|
@ -85,10 +85,11 @@ void _MD_EarlyInit(void)
|
|||
}
|
||||
dlclose(main_app_handle);
|
||||
|
||||
if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) {
|
||||
if (1 == atoi(evp))
|
||||
_pr_aix_send_file_use_disabled = 1;
|
||||
}
|
||||
if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) {
|
||||
if (1 == atoi(evp)) {
|
||||
_pr_aix_send_file_use_disabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(AIX_TIMERS)
|
||||
_MD_AixIntervalInit();
|
||||
|
|
@ -110,13 +111,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +131,7 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PR_IMPLEMENT(PRStatus)
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
|
|
@ -145,7 +146,7 @@ PR_IMPLEMENT(PRStatus)
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -193,17 +194,17 @@ int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
|
|||
if (!aix_select_fcn) {
|
||||
void *aix_handle;
|
||||
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
aix_select_fcn = (int(*)())dlsym(aix_handle,"select");
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
aix_select_fcn = (int(*)())dlsym(aix_handle,"select");
|
||||
dlclose(aix_handle);
|
||||
if (!aix_select_fcn) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
if (!aix_select_fcn) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rv = (*aix_select_fcn)(width, r, w, e, t);
|
||||
return rv;
|
||||
|
|
@ -216,17 +217,17 @@ int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
|
|||
if (!aix_poll_fcn) {
|
||||
void *aix_handle;
|
||||
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll");
|
||||
aix_handle = dlopen("/unix", RTLD_NOW);
|
||||
if (!aix_handle) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll");
|
||||
dlclose(aix_handle);
|
||||
if (!aix_poll_fcn) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
if (!aix_poll_fcn) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rv = (*aix_poll_fcn)(listptr, nfds, timeout);
|
||||
return rv;
|
||||
|
|
@ -251,51 +252,51 @@ void _pr_aix_dummy()
|
|||
|
||||
#include "pratom.h"
|
||||
|
||||
#define _PR_AIX_ATOMIC_LOCK -1
|
||||
#define _PR_AIX_ATOMIC_LOCK -1
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
|
||||
{
|
||||
PRStackElem *addr;
|
||||
boolean_t locked = TRUE;
|
||||
PRStackElem *addr;
|
||||
boolean_t locked = TRUE;
|
||||
|
||||
/* Is it safe to cast a pointer to an int? */
|
||||
PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
|
||||
do {
|
||||
while ((addr = stack->prstk_head.prstk_elem_next) ==
|
||||
(PRStackElem *)_PR_AIX_ATOMIC_LOCK)
|
||||
;
|
||||
locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int) addr, _PR_AIX_ATOMIC_LOCK);
|
||||
} while (locked == TRUE);
|
||||
stack_elem->prstk_elem_next = addr;
|
||||
_clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem);
|
||||
/* Is it safe to cast a pointer to an int? */
|
||||
PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
|
||||
do {
|
||||
while ((addr = stack->prstk_head.prstk_elem_next) ==
|
||||
(PRStackElem *)_PR_AIX_ATOMIC_LOCK)
|
||||
;
|
||||
locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int) addr, _PR_AIX_ATOMIC_LOCK);
|
||||
} while (locked == TRUE);
|
||||
stack_elem->prstk_elem_next = addr;
|
||||
_clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem);
|
||||
return;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStackElem *)
|
||||
PR_StackPop(PRStack *stack)
|
||||
{
|
||||
PRStackElem *element;
|
||||
boolean_t locked = TRUE;
|
||||
PRStackElem *element;
|
||||
boolean_t locked = TRUE;
|
||||
|
||||
/* Is it safe to cast a pointer to an int? */
|
||||
PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
|
||||
do {
|
||||
while ((element = stack->prstk_head.prstk_elem_next) ==
|
||||
(PRStackElem *) _PR_AIX_ATOMIC_LOCK)
|
||||
;
|
||||
locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int)element, _PR_AIX_ATOMIC_LOCK);
|
||||
} while (locked == TRUE);
|
||||
/* Is it safe to cast a pointer to an int? */
|
||||
PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
|
||||
do {
|
||||
while ((element = stack->prstk_head.prstk_elem_next) ==
|
||||
(PRStackElem *) _PR_AIX_ATOMIC_LOCK)
|
||||
;
|
||||
locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int)element, _PR_AIX_ATOMIC_LOCK);
|
||||
} while (locked == TRUE);
|
||||
|
||||
if (element == NULL) {
|
||||
_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL);
|
||||
} else {
|
||||
_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int) element->prstk_elem_next);
|
||||
}
|
||||
return element;
|
||||
if (element == NULL) {
|
||||
_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL);
|
||||
} else {
|
||||
_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
|
||||
(int) element->prstk_elem_next);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
#endif /* _PR_HAVE_ATOMIC_CAS */
|
||||
#endif /* _PR_HAVE_ATOMIC_CAS */
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* File: aixwrap.c
|
||||
* File: aixwrap.c
|
||||
* Description:
|
||||
* This file contains a single function, _MD_SELECT(), which simply
|
||||
* invokes the select() function. This file is used in an ugly
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
|
|
@ -45,7 +45,7 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PRStatus
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -60,7 +60,7 @@ PRStatus
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -82,6 +82,6 @@ _MD_CREATE_THREAD(
|
|||
PRUint32 stackSize)
|
||||
{
|
||||
PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for BSDI.");
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#if !defined(_PR_PTHREADS)
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PRStatus
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -83,7 +83,7 @@ PRStatus
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ _MD_CREATE_THREAD(
|
|||
PRUint32 stackSize)
|
||||
{
|
||||
PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin.");
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) sigsetjmp(CONTEXT(t), 1);
|
||||
(void) sigsetjmp(CONTEXT(t), 1);
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PRStatus
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -60,7 +60,7 @@ PRStatus
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -82,6 +82,6 @@ _MD_CREATE_THREAD(
|
|||
PRUint32 stackSize)
|
||||
{
|
||||
PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD.");
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ void _MD_EarlyInit(void)
|
|||
|
||||
if(!setjmp(jb)) {
|
||||
newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE);
|
||||
oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE);
|
||||
oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE);
|
||||
memcpy(newstack, oldstack, BACKTRACE_SIZE);
|
||||
*(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE);
|
||||
longjmp(jb, 1);
|
||||
|
|
@ -98,13 +98,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PRStatus
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -133,7 +133,7 @@ PRStatus
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -208,7 +208,7 @@ strchr(const char *s, int c)
|
|||
* A.09.07, and B.10.10) dumps core if called with:
|
||||
* 1. First operand with address = 1(mod 4).
|
||||
* 2. Size = 1(mod 4)
|
||||
* 3. Last byte of the second operand is the last byte of the page and
|
||||
* 3. Last byte of the second operand is the last byte of the page and
|
||||
* next page is not accessible(not mapped or protected)
|
||||
* Thus, using the following naive version (tons of optimizations are
|
||||
* possible;^)
|
||||
|
|
@ -217,13 +217,15 @@ strchr(const char *s, int c)
|
|||
int memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
register unsigned char *p1 = (unsigned char *) s1,
|
||||
*p2 = (unsigned char *) s2;
|
||||
*p2 = (unsigned char *) s2;
|
||||
|
||||
while (n-- > 0) {
|
||||
register int r = ((int) ((unsigned int) *p1))
|
||||
- ((int) ((unsigned int) *p2));
|
||||
if (r) return r;
|
||||
register int r = ((int) ((unsigned int) *p1))
|
||||
- ((int) ((unsigned int) *p2));
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
p1++; p2++;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,13 +13,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -43,13 +43,13 @@ _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
|
|||
PRStatus
|
||||
_MD_InitializeThread(PRThread *thread)
|
||||
{
|
||||
/*
|
||||
* set the pointers to the stack-pointer and frame-pointer words in the
|
||||
* context structure; this is for debugging use.
|
||||
*/
|
||||
thread->md.sp = _MD_GET_SP_PTR(thread);
|
||||
thread->md.fp = _MD_GET_FP_PTR(thread);
|
||||
return PR_SUCCESS;
|
||||
/*
|
||||
* set the pointers to the stack-pointer and frame-pointer words in the
|
||||
* context structure; this is for debugging use.
|
||||
*/
|
||||
thread->md.sp = _MD_GET_SP_PTR(thread);
|
||||
thread->md.fp = _MD_GET_FP_PTR(thread);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -64,7 +64,7 @@ PRStatus
|
|||
_MD_WAKEUP_WAITER(PRThread *thread)
|
||||
{
|
||||
if (thread) {
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -86,6 +86,6 @@ _MD_CREATE_THREAD(
|
|||
PRUint32 stackSize)
|
||||
{
|
||||
PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux.");
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* ! _PR_PTHREADS */
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
/* Fake this out */
|
||||
int socketpair (int foo, int foo2, int foo3, int sv[2])
|
||||
{
|
||||
printf("error in socketpair\n");
|
||||
exit (-1);
|
||||
printf("error in socketpair\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
void _MD_EarlyInit(void)
|
||||
|
|
@ -22,13 +22,13 @@ PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
|
|||
{
|
||||
#ifndef _PR_PTHREADS
|
||||
if (isCurrent) {
|
||||
(void) setjmp(CONTEXT(t));
|
||||
(void) setjmp(CONTEXT(t));
|
||||
}
|
||||
|
||||
*np = sizeof(CONTEXT(t)) / sizeof(PRWord);
|
||||
return (PRWord *) CONTEXT(t);
|
||||
#else
|
||||
*np = 0;
|
||||
return NULL;
|
||||
*np = 0;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue