зеркало из https://github.com/mozilla/gecko-dev.git
More mozilla/nsprpub updates, including:
- Patch for MkLinux and glibc 2.1. Removed the MKLINUX macro. This patch is contributed by Tom Rini <trini@kernel.crashing.org>. - Patch to make the emulated threads work on ARM/Linux. Contributed by raff@netwinder.org.
This commit is contained in:
Родитель
c5b5342df7
Коммит
6462b9a6d7
|
@ -79,8 +79,7 @@ PLATFORM_FLAGS += -D_ALPHA_ -D__alpha -mieee
|
|||
PORT_FLAGS += -D_XOPEN_SOURCE
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),ppc)
|
||||
PLATFORM_FLAGS += -DMKLINUX
|
||||
OS_INCLUDES += -I/usr/local/include
|
||||
PORT_FLAGS += -D_XOPEN_SOURCE
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),x86)
|
||||
PLATFORM_FLAGS += -mno-486 -Di386
|
||||
|
@ -99,7 +98,7 @@ PLATFORM_FLAGS += -m68020-40
|
|||
endif
|
||||
|
||||
#
|
||||
# Linux ppc and 2.0 have shared libraries.
|
||||
# Linux 2.x has shared libraries.
|
||||
#
|
||||
|
||||
MKSHLIB = $(LD) $(DSO_LDOPTS) -soname $(@:$(OBJDIR)/%.so=%.so)
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "prmem.h"
|
||||
#include "prbit.h"
|
||||
#include "prlog.h"
|
||||
#include "prmon.h"
|
||||
#include "prinit.h"
|
||||
|
||||
static PLArena *arena_freelist;
|
||||
|
||||
|
@ -40,6 +42,48 @@ static PLArenaStats *arena_stats_list;
|
|||
|
||||
#define PL_ARENA_DEFAULT_ALIGN sizeof(double)
|
||||
|
||||
static PRMonitor *arenaLock;
|
||||
static PRCallOnceType once;
|
||||
|
||||
/*
|
||||
** InitializeArenas() -- Initialize arena operations.
|
||||
**
|
||||
** InitializeArenas() is called exactly once and only once from
|
||||
** LockArena(). This function creates the arena protection
|
||||
** monitor: arenaLock.
|
||||
**
|
||||
** Note: If the arenaLock cannot be created, InitializeArenas()
|
||||
** fails quietly, returning only PR_FAILURE. This percolates up
|
||||
** to the application using the Arena API. He gets no arena
|
||||
** from PL_ArenaAllocate(). It's up to him to fail gracefully
|
||||
** or recover.
|
||||
**
|
||||
*/
|
||||
static PRStatus InitializeArenas( void )
|
||||
{
|
||||
PR_ASSERT( arenaLock == NULL );
|
||||
arenaLock = PR_NewMonitor();
|
||||
if ( arenaLock == NULL )
|
||||
return PR_FAILURE;
|
||||
else
|
||||
return PR_SUCCESS;
|
||||
} /* end ArenaInitialize() */
|
||||
|
||||
static PRStatus LockArena( void )
|
||||
{
|
||||
PRStatus rc = PR_CallOnce( &once, InitializeArenas );
|
||||
|
||||
if ( PR_FAILURE != rc )
|
||||
PR_EnterMonitor( arenaLock );
|
||||
return(rc);
|
||||
} /* end LockArena() */
|
||||
|
||||
static void UnlockArena( void )
|
||||
{
|
||||
PR_ExitMonitor( arenaLock );
|
||||
return;
|
||||
} /* end UnlockArena() */
|
||||
|
||||
PR_IMPLEMENT(void) PL_InitArenaPool(
|
||||
PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align)
|
||||
{
|
||||
|
@ -74,6 +118,8 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
|
|||
if (nb >= 60000U)
|
||||
return 0;
|
||||
#endif /* WIN16 */
|
||||
if ( PR_FAILURE == LockArena())
|
||||
return(0);
|
||||
ap = &arena_freelist;
|
||||
for (a = pool->current; a->avail + nb > a->limit; pool->current = a) {
|
||||
if (a->next) { /* move to next arena */
|
||||
|
@ -94,7 +140,10 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
|
|||
sz += sizeof *a + pool->mask; /* header and alignment slop */
|
||||
b = (PLArena*)PR_MALLOC(sz);
|
||||
if (!b)
|
||||
{
|
||||
UnlockArena();
|
||||
return 0;
|
||||
}
|
||||
a = a->next = b;
|
||||
a->next = 0;
|
||||
a->limit = (PRUword)a + sz;
|
||||
|
@ -103,6 +152,7 @@ PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
|
|||
claim:
|
||||
a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1);
|
||||
}
|
||||
UnlockArena();
|
||||
p = (void *)a->avail;
|
||||
a->avail += nb;
|
||||
return p;
|
||||
|
@ -153,9 +203,11 @@ static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree)
|
|||
do {
|
||||
ap = &(*ap)->next;
|
||||
} while (*ap);
|
||||
LockArena();
|
||||
*ap = arena_freelist;
|
||||
arena_freelist = a;
|
||||
head->next = 0;
|
||||
UnlockArena();
|
||||
}
|
||||
|
||||
pool->current = head;
|
||||
|
@ -219,11 +271,13 @@ PR_IMPLEMENT(void) PL_ArenaFinish()
|
|||
{
|
||||
PLArena *a, *next;
|
||||
|
||||
LockArena();
|
||||
for (a = arena_freelist; a; a = next) {
|
||||
next = a->next;
|
||||
PR_DELETE(a);
|
||||
}
|
||||
arena_freelist = NULL;
|
||||
UnlockArena();
|
||||
}
|
||||
|
||||
#ifdef PL_ARENAMETER
|
||||
|
|
|
@ -96,6 +96,7 @@ static const char *tags[] =
|
|||
"PR_END_OF_FILE_ERROR",
|
||||
"PR_FILE_SEEK_ERROR",
|
||||
"PR_FILE_IS_BUSY_ERROR",
|
||||
"<unused error code>",
|
||||
"PR_IN_PROGRESS_ERROR",
|
||||
"PR_ALREADY_INITIATED_ERROR",
|
||||
"PR_GROUP_EMPTY_ERROR",
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
** File: arena.c
|
||||
** Description: Testing arenas
|
||||
**
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "nspr.h"
|
||||
#include "plarena.h"
|
||||
#include "plgetopt.h"
|
||||
|
||||
PRLogModuleInfo *tLM;
|
||||
PRIntn threadCount = 0;
|
||||
PRMonitor *tMon;
|
||||
PRBool failed_already = PR_FALSE;
|
||||
|
||||
/* Arguments from the command line with default values */
|
||||
PRIntn debug_mode = 0;
|
||||
PRIntn poolMin = 4096;
|
||||
PRIntn poolMax = (100 * 4096);
|
||||
PRIntn arenaMin = 40;
|
||||
PRIntn arenaMax = (100 * 40);
|
||||
PRIntn stressIterations = 15;
|
||||
PRIntn maxAlloc = (1024 * 1024);
|
||||
PRIntn stressThreads = 4;
|
||||
|
||||
/*
|
||||
** Test arena Mark and Release.
|
||||
*/
|
||||
static void MarkAndRelease( void )
|
||||
{
|
||||
PLArenaPool ap;
|
||||
void *ptr;
|
||||
void *mark;
|
||||
|
||||
PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
|
||||
PL_ARENA_ALLOCATE( ptr, &ap, 512 );
|
||||
|
||||
mark = PL_ARENA_MARK( &ap );
|
||||
|
||||
PL_ARENA_ALLOCATE( ptr, &ap, 512 );
|
||||
|
||||
PL_ARENA_RELEASE( &ap, mark );
|
||||
PL_ARENA_ALLOCATE( ptr, &ap, 512 );
|
||||
|
||||
if ( ptr != mark )
|
||||
{
|
||||
failed_already = PR_TRUE;
|
||||
PR_LOG( tLM, PR_LOG_ERROR, ("Mark and Release failed: expected %p, got %p\n", mark, ptr));
|
||||
}
|
||||
else
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("Mark and Release passed\n"));
|
||||
|
||||
return;
|
||||
} /* end MarkAndRelease() */
|
||||
|
||||
/*
|
||||
** RandSize() returns a random number in the range
|
||||
** min..max, rounded to the next doubleword
|
||||
**
|
||||
*/
|
||||
static PRIntn RandSize( PRIntn min, PRIntn max )
|
||||
{
|
||||
PRIntn sz = (rand() % (max -min)) + min + sizeof(double);
|
||||
|
||||
sz &= ~sizeof(double)-1;
|
||||
|
||||
return(sz);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** StressThread()
|
||||
** A bunch of these beat on individual arenas
|
||||
** This tests the free_list protection.
|
||||
**
|
||||
*/
|
||||
static void PR_CALLBACK StressThread( void *arg )
|
||||
{
|
||||
PLArenaPool ap;
|
||||
PRIntn i;
|
||||
PRIntn sz;
|
||||
void *ptr;
|
||||
PRThread *tp = PR_GetCurrentThread();
|
||||
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread()));
|
||||
PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double));
|
||||
|
||||
for ( i = 0; i < stressIterations; i++ )
|
||||
{
|
||||
PRIntn allocated = 0;
|
||||
|
||||
while ( allocated < maxAlloc )
|
||||
{
|
||||
sz = RandSize( arenaMin, arenaMax );
|
||||
PL_ARENA_ALLOCATE( ptr, &ap, sz );
|
||||
if ( ptr == NULL )
|
||||
{
|
||||
PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
|
||||
break;
|
||||
}
|
||||
allocated += sz;
|
||||
}
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp));
|
||||
PL_FreeArenaPool( &ap );
|
||||
}
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp));
|
||||
PL_FinishArenaPool( &ap );
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp));
|
||||
|
||||
/* That's all folks! let's quit */
|
||||
PR_EnterMonitor(tMon);
|
||||
threadCount--;
|
||||
PR_Notify(tMon);
|
||||
PR_ExitMonitor(tMon);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Stress()
|
||||
** Flog the hell out of arenas multi-threaded.
|
||||
** Do NOT pass an individual arena to another thread.
|
||||
**
|
||||
*/
|
||||
static void Stress( void )
|
||||
{
|
||||
PRThread *tt;
|
||||
PRIntn i;
|
||||
|
||||
tMon = PR_NewMonitor();
|
||||
|
||||
for ( i = 0 ; i < stressThreads ; i++ )
|
||||
{
|
||||
PR_EnterMonitor(tMon);
|
||||
tt = PR_CreateThread(PR_USER_THREAD,
|
||||
StressThread,
|
||||
NULL,
|
||||
PR_PRIORITY_NORMAL,
|
||||
PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0);
|
||||
threadCount++;
|
||||
PR_ExitMonitor(tMon);
|
||||
}
|
||||
|
||||
/* Wait for all threads to exit */
|
||||
PR_EnterMonitor(tMon);
|
||||
while ( threadCount != 0 )
|
||||
{
|
||||
PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
|
||||
}
|
||||
PR_ExitMonitor(tMon);
|
||||
PR_DestroyMonitor(tMon);
|
||||
|
||||
return;
|
||||
} /* end Stress() */
|
||||
|
||||
/*
|
||||
** EvaluateResults()
|
||||
** uses failed_already to display results and set program
|
||||
** exit code.
|
||||
*/
|
||||
static PRIntn EvaluateResults(void)
|
||||
{
|
||||
PRIntn rc = 0;
|
||||
|
||||
if ( failed_already == PR_TRUE )
|
||||
{
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n"));
|
||||
rc =1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n"));
|
||||
}
|
||||
return(rc);
|
||||
} /* EvaluateResults() */
|
||||
|
||||
void Help( void )
|
||||
{
|
||||
printf("arena [options]\n");
|
||||
printf("where options are:\n");
|
||||
printf("-p <n> minimum size of an arena pool. Default(%d)\n", poolMin);
|
||||
printf("-P <n> maximum size of an arena pool. Default(%d)\n", poolMax);
|
||||
printf("-a <n> minimum size of an arena allocation. Default(%d)\n", arenaMin);
|
||||
printf("-A <n> maximum size of an arena allocation. Default(%d)\n", arenaMax);
|
||||
printf("-i <n> number of iterations in a stress thread. Default(%d)\n", stressIterations);
|
||||
printf("-s <n> maximum allocation for a single stress thread. Default(%d)\n", maxAlloc);
|
||||
printf("-t <n> number of stress threads. Default(%d)\n", stressThreads );
|
||||
printf("-d enable debug mode\n");
|
||||
printf("\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PRIntn main(PRIntn argc, char *argv[])
|
||||
{
|
||||
PLOptStatus os;
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:");
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
{
|
||||
if (PL_OPT_BAD == os) continue;
|
||||
switch (opt->option)
|
||||
{
|
||||
case 'a': /* arena Min size */
|
||||
arenaMin = atol( opt->value );
|
||||
break;
|
||||
case 'A': /* arena Max size */
|
||||
arenaMax = atol( opt->value );
|
||||
break;
|
||||
case 'p': /* pool Min size */
|
||||
poolMin = atol( opt->value );
|
||||
break;
|
||||
case 'P': /* pool Max size */
|
||||
poolMax = atol( opt->value );
|
||||
break;
|
||||
case 'i': /* Iterations in stress tests */
|
||||
stressIterations = atol( opt->value );
|
||||
break;
|
||||
case 's': /* storage to get per iteration */
|
||||
maxAlloc = atol( opt->value );
|
||||
break;
|
||||
case 't': /* Number of stress threads to create */
|
||||
stressThreads = atol( opt->value );
|
||||
break;
|
||||
case 'd': /* debug mode */
|
||||
debug_mode = 1;
|
||||
break;
|
||||
case 'h': /* help */
|
||||
default:
|
||||
Help();
|
||||
} /* end switch() */
|
||||
} /* end while() */
|
||||
PL_DestroyOptState(opt);
|
||||
|
||||
srand( (unsigned)time( NULL ) ); /* seed random number generator */
|
||||
tLM = PR_NewLogModule("testcase");
|
||||
|
||||
MarkAndRelease();
|
||||
|
||||
Stress();
|
||||
|
||||
return(EvaluateResults());
|
||||
} /* end main() */
|
||||
|
||||
/* arena.c */
|
|
@ -59,10 +59,6 @@
|
|||
#define HAVE_DLL
|
||||
#define USE_DLFCN
|
||||
|
||||
#if !defined(MKLINUX) && !defined(NEED_TIME_R)
|
||||
#define NEED_TIME_R
|
||||
#endif
|
||||
|
||||
#define USE_SETJMP
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#define _PR_POLL_AVAILABLE
|
||||
|
@ -89,8 +85,17 @@ extern void _MD_CleanupBeforeExit(void);
|
|||
#define CONTEXT(_th) ((_th)->md.context)
|
||||
|
||||
#ifdef __powerpc__
|
||||
/* PowerPC based MkLinux */
|
||||
/*
|
||||
* PowerPC based MkLinux
|
||||
*
|
||||
* On the PowerPC, the new style jmp_buf isn't used until glibc
|
||||
* 2.1.
|
||||
*/
|
||||
#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
|
||||
#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1]
|
||||
#else
|
||||
#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0]
|
||||
#endif /* __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 */
|
||||
#define _MD_SET_FP(_t, val)
|
||||
#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
|
||||
#define _MD_GET_FP_PTR(_t) ((void *) 0)
|
||||
|
@ -194,6 +199,18 @@ extern void _MD_CleanupBeforeExit(void);
|
|||
#error "Linux/MIPS pre-glibc2 not supported yet"
|
||||
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
|
||||
|
||||
#elif defined(__arm__)
|
||||
/* ARM/Linux */
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20]
|
||||
#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val))
|
||||
#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
|
||||
#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19])
|
||||
#define _MD_SP_TYPE __ptr_t
|
||||
#else
|
||||
#error "ARM/Linux pre-glibc2 not supported yet"
|
||||
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
|
||||
|
||||
#else
|
||||
|
||||
#error "Unknown CPU architecture"
|
||||
|
|
|
@ -340,7 +340,6 @@ extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
|
|||
fd_set *exceptfds, struct timeval *timeout);
|
||||
#define _MD_SELECT _select
|
||||
|
||||
#include <stropts.h>
|
||||
#include <poll.h>
|
||||
#define _MD_POLL _poll
|
||||
extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
|
||||
|
|
|
@ -44,11 +44,11 @@ PR_BEGIN_EXTERN_C
|
|||
** The format of the version string is
|
||||
** "<major version>.<minor version> <build date>"
|
||||
*/
|
||||
#define PR_VERSION "3.0 yyyymmdd"
|
||||
#define PR_VERSION "3.0 19981002"
|
||||
#define PR_VMAJOR 3
|
||||
#define PR_VMINOR 0
|
||||
#define PR_VPATCH 0
|
||||
#define PR_BETA PR_TRUE
|
||||
#define PR_BETA PR_FALSE
|
||||
|
||||
/*
|
||||
** PRVersionCheck
|
||||
|
|
|
@ -25,14 +25,19 @@
|
|||
#include "prclist.h"
|
||||
#include "prthread.h"
|
||||
|
||||
#define _PR_HASH_OFFSET 75013
|
||||
#define MAX_POLLING_INTERVAL 100
|
||||
#define _PR_POLL_COUNT_FUDGE 64
|
||||
#define MAX_POLLING_INTERVAL 100
|
||||
#define _PR_DEFAULT_HASH_LENGTH 59
|
||||
|
||||
#define _MW_REHASH(a, i, m) _MW_HASH((PRUptrdiff)(a) + (i) + _PR_HASH_OFFSET, m)
|
||||
/*
|
||||
* Our hash table resolves collisions by open addressing with
|
||||
* double hashing. See Cormen, Leiserson, and Rivest,
|
||||
* Introduction to Algorithms, p. 232, The MIT Press, 1990.
|
||||
*/
|
||||
|
||||
#define _MW_HASH(a, m) ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m))
|
||||
#define _MW_HASH2(a, m) (1 + ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m - 2)))
|
||||
#define _MW_ABORTED(_rv) \
|
||||
((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
|
||||
|
||||
|
|
|
@ -32,6 +32,13 @@ PR_BEGIN_EXTERN_C
|
|||
** [<sep><root_component><sep>]*(<component><sep>)<leaf_name>
|
||||
*/
|
||||
|
||||
PR_EXTERN(char) PR_GetDirectorySeparator(void);
|
||||
|
||||
/*
|
||||
** OBSOLETE -- the function name is misspelled.
|
||||
** Use PR_GetDirectorySeparator instead.
|
||||
*/
|
||||
|
||||
PR_EXTERN(char) PR_GetDirectorySepartor(void);
|
||||
|
||||
|
||||
|
|
|
@ -507,6 +507,8 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
HANDLE readEnd, writeEnd;
|
||||
SECURITY_ATTRIBUTES pipeAttributes;
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
|
||||
pipeAttributes.nLength = sizeof(pipeAttributes);
|
||||
pipeAttributes.bInheritHandle = TRUE;
|
||||
|
@ -534,6 +536,8 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
|
|||
#elif defined(XP_UNIX)
|
||||
int pipefd[2];
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
if (pipe(pipefd) == -1) {
|
||||
/* XXX map pipe error */
|
||||
PR_SetError(PR_UNKNOWN_ERROR, errno);
|
||||
|
|
|
@ -268,6 +268,8 @@ static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
|
|||
PRIntn rehash = _MW_REHASH_MAX;
|
||||
PRRecvWait **waiter;
|
||||
PRUintn hidx = _MW_HASH(desc->fd, hash->length);
|
||||
PRUintn hoffset = 0;
|
||||
|
||||
while (rehash-- > 0)
|
||||
{
|
||||
waiter = &hash->recv_wait;
|
||||
|
@ -294,7 +296,12 @@ static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
|
|||
"table[*%u:%u:%u]: 0x%x->0x%x\n",
|
||||
hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd);
|
||||
#endif
|
||||
hidx = _MW_REHASH(desc->fd, hidx, hash->length);
|
||||
if (0 == hoffset)
|
||||
{
|
||||
hoffset = _MW_HASH2(desc->fd, hash->length);
|
||||
PR_ASSERT(0 != hoffset);
|
||||
}
|
||||
hidx = (hidx + hoffset) % (hash->length);
|
||||
}
|
||||
return _prmw_rehash;
|
||||
} /* MW_AddHashInternal */
|
||||
|
@ -302,56 +309,71 @@ static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
|
|||
static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
|
||||
{
|
||||
PRRecvWait **desc;
|
||||
PRUint32 pidx, length = 0;
|
||||
PRUint32 pidx, length;
|
||||
_PRWaiterHash *newHash, *oldHash = group->waiter;
|
||||
|
||||
PRBool retry;
|
||||
_PR_HashStory hrv;
|
||||
|
||||
static const PRInt32 prime_number[] = {
|
||||
_PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427,
|
||||
2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771};
|
||||
PRUintn primes = (sizeof(prime_number) / sizeof(PRIntn));
|
||||
PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32));
|
||||
|
||||
/* look up the next size we'd like to use for the hash table */
|
||||
for (pidx = 0; pidx < primes; ++pidx)
|
||||
{
|
||||
if (prime_number[pidx] == oldHash->length)
|
||||
{
|
||||
length = prime_number[pidx + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (0 == length)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return _prmw_error; /* we're hosed */
|
||||
}
|
||||
/* table size must be one of the prime numbers */
|
||||
PR_ASSERT(pidx < primes);
|
||||
|
||||
/* allocate the new hash table and fill it in with the old */
|
||||
newHash = (_PRWaiterHash*)PR_CALLOC(
|
||||
sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
|
||||
if (NULL == newHash)
|
||||
/* if pidx == primes - 1, we can't expand the table any more */
|
||||
while (pidx < primes - 1)
|
||||
{
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return _prmw_error;
|
||||
}
|
||||
/* next size */
|
||||
++pidx;
|
||||
length = prime_number[pidx];
|
||||
|
||||
newHash->length = length;
|
||||
for (desc = &oldHash->recv_wait; newHash->count < oldHash->count; ++desc)
|
||||
{
|
||||
if (NULL != *desc)
|
||||
/* allocate the new hash table and fill it in with the old */
|
||||
newHash = (_PRWaiterHash*)PR_CALLOC(
|
||||
sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
|
||||
if (NULL == newHash)
|
||||
{
|
||||
if (_prmw_success != MW_AddHashInternal(*desc, newHash))
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return _prmw_error;
|
||||
}
|
||||
|
||||
newHash->length = length;
|
||||
retry = PR_FALSE;
|
||||
for (desc = &oldHash->recv_wait;
|
||||
newHash->count < oldHash->count; ++desc)
|
||||
{
|
||||
PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length);
|
||||
if (NULL != *desc)
|
||||
{
|
||||
PR_ASSERT(!"But, but, but ...");
|
||||
PR_DELETE(newHash);
|
||||
return _prmw_error;
|
||||
hrv = MW_AddHashInternal(*desc, newHash);
|
||||
PR_ASSERT(_prmw_error != hrv);
|
||||
if (_prmw_success != hrv)
|
||||
{
|
||||
PR_DELETE(newHash);
|
||||
retry = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retry) continue;
|
||||
|
||||
PR_DELETE(group->waiter);
|
||||
group->waiter = newHash;
|
||||
group->p_timestamp += 1;
|
||||
return _prmw_success;
|
||||
}
|
||||
PR_DELETE(group->waiter);
|
||||
group->waiter = newHash;
|
||||
group->p_timestamp += 1;
|
||||
return _prmw_success;
|
||||
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return _prmw_error; /* we're hosed */
|
||||
} /* MW_ExpandHashInternal */
|
||||
|
||||
#ifndef WINNT
|
||||
|
@ -387,12 +409,18 @@ static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd)
|
|||
PRIntn rehash = _MW_REHASH_MAX;
|
||||
_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;
|
||||
hidx = _MW_REHASH(fd, hidx, hash->length);
|
||||
if (0 == hoffset)
|
||||
{
|
||||
hoffset = _MW_HASH2(fd, hash->length);
|
||||
PR_ASSERT(0 != hoffset);
|
||||
}
|
||||
hidx = (hidx + hoffset) % (hash->length);
|
||||
}
|
||||
return NULL;
|
||||
} /* _MW_LookupInternal */
|
||||
|
@ -849,6 +877,14 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
me->state = _PR_RUNNING;
|
||||
PR_Lock(group->ml);
|
||||
_PR_MD_LOCK(&group->mdlock);
|
||||
if (_PR_PENDING_INTERRUPT(me)) {
|
||||
PR_REMOVE_LINK(&me->waitQLinks);
|
||||
_PR_MD_UNLOCK(&group->mdlock);
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
me->io_suspended = PR_FALSE;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
goto aborted;
|
||||
}
|
||||
}
|
||||
io_ready = PR_LIST_HEAD(&group->io_ready);
|
||||
PR_ASSERT(io_ready != NULL);
|
||||
|
@ -948,11 +984,12 @@ PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
|
|||
PR_REMOVE_LINK(io_ready);
|
||||
} while (NULL == io_ready);
|
||||
|
||||
aborted:
|
||||
failed_poll:
|
||||
|
||||
#endif
|
||||
|
||||
aborted:
|
||||
|
||||
group->waiting_threads -= 1;
|
||||
invalid_state:
|
||||
(void)MW_TestForShutdownInternal(group);
|
||||
|
@ -1184,6 +1221,18 @@ PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
|
|||
overlapped = (_MDOverlapped *)
|
||||
((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);
|
||||
CancelTimer(overlapped->data.mw.timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
|
||||
== overlapped->data.mw.desc->timeout);
|
||||
}
|
||||
PR_DELETE(overlapped);
|
||||
#endif
|
||||
recv_wait = (PRRecvWait*)head;
|
||||
}
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
** Note: on some platforms va_list is defined as an array,
|
||||
** and requires array notation.
|
||||
*/
|
||||
#if defined(MKLINUX) || defined(WIN16)
|
||||
#if (defined(LINUX) && defined(__powerpc__)) || defined(WIN16)
|
||||
#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
|
||||
#else
|
||||
#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
|
||||
#endif /*MKLINUX*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it)
|
||||
|
|
|
@ -1116,6 +1116,8 @@ PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
|
|||
#ifdef XP_UNIX
|
||||
PRInt32 rv, osfd[2];
|
||||
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
|
||||
rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd);
|
||||
if (rv == -1) {
|
||||
return PR_FAILURE;
|
||||
|
@ -1356,7 +1358,6 @@ PRInt32 _PR_EmulateAcceptRead(
|
|||
return rv;
|
||||
}
|
||||
|
||||
failed:
|
||||
PR_Close(accepted);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ ifeq ($(OS_ARCH),SunOS)
|
|||
else
|
||||
ifneq ($(OS_RELEASE),4.1.3_U1)
|
||||
ifneq ($(LOCAL_THREADS_ONLY),1)
|
||||
ASFILES = os_$(OS_ARCH).s
|
||||
ASFILES += os_$(OS_ARCH).s
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -226,12 +226,10 @@ endif
|
|||
ifeq ($(OS_ARCH),SunOS)
|
||||
ifneq ($(OS_RELEASE),4.1.3_U1)
|
||||
ifeq ($(OS_TEST),sun4u)
|
||||
LIBRARY_NAME = $(ULTRASPARC_LIBRARY)
|
||||
LIBRARY_VERSION = $(MOD_VERSION)
|
||||
ULTRASPARC_ASFILES = os_$(OS_ARCH)_ultrasparc.s
|
||||
ASFILES += $(ULTRASPARC_ASFILES)
|
||||
CFLAGS += -D_PR_ULTRASPARC
|
||||
ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX)))
|
||||
TARGETS += $(ULTRASPARC_ASOBJS) $(SHARED_LIBRARY)
|
||||
RELEASE_LIBS = $(SHARED_LIBRARY)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -252,10 +250,6 @@ export:: $(TARGETS)
|
|||
ifeq ($(OS_ARCH),SunOS)
|
||||
ifneq ($(OS_RELEASE),4.1.3_U1)
|
||||
ifeq ($(OS_TEST),sun4u)
|
||||
$(SHARED_LIBRARY): $(ULTRASPARC_ASOBJS)
|
||||
$(LD) -G -z text -o $@ $(ULTRASPARC_ASOBJS)
|
||||
$(INSTALL) -m 444 $(SHARED_LIBRARY) $(DIST)/lib
|
||||
|
||||
$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES)
|
||||
/usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v8plus $<
|
||||
endif
|
||||
|
|
|
@ -105,6 +105,7 @@ PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to
|
|||
|
||||
int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 };
|
||||
static void (*libc_exit)(int) = NULL;
|
||||
static void *libc_handle = NULL;
|
||||
|
||||
#define _NSPR_DEF_INITUSERS 100 /* default value of CONF_INITUSERS */
|
||||
#define _NSPR_DEF_INITSIZE (4 * 1024 * 1024) /* 4 MB */
|
||||
|
@ -990,7 +991,6 @@ PRThread *me = _PR_MD_CURRENT_THREAD();
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 /* wtc: comment out */
|
||||
/*
|
||||
* Override the exit() function in libc to cause the process to exit
|
||||
* when the primodial/main nspr thread calls exit. Calls to exit by any
|
||||
|
@ -1003,10 +1003,20 @@ void exit(int status)
|
|||
{
|
||||
PRThread *me, *thr;
|
||||
PRCList *qp;
|
||||
void __exit(int status); /* XXX some IRIX machines don't have this symbol */
|
||||
|
||||
if (!_pr_initialized)
|
||||
__exit(status);
|
||||
if (!_pr_initialized) {
|
||||
if (!libc_exit) {
|
||||
|
||||
if (!libc_handle)
|
||||
libc_handle = dlopen("libc.so",RTLD_NOW);
|
||||
if (libc_handle)
|
||||
libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
|
||||
}
|
||||
if (libc_exit)
|
||||
(*libc_exit)(status);
|
||||
else
|
||||
_exit(status);
|
||||
}
|
||||
|
||||
me = _PR_MD_CURRENT_THREAD();
|
||||
|
||||
|
@ -1081,7 +1091,6 @@ void __exit(int status); /* XXX some IRIX machines don't have this symbol */
|
|||
(*libc_exit)(status);
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
void
|
||||
|
@ -1431,7 +1440,6 @@ void _MD_IrixInit()
|
|||
#if !defined(_PR_PTHREADS)
|
||||
struct sigaction sigact;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
void *libc_handle;
|
||||
int rv;
|
||||
|
||||
#ifndef IRIX5_3
|
||||
|
|
|
@ -194,6 +194,14 @@ ifeq ($(OS_ARCH),SunOS)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),SunOS)
|
||||
ifneq ($(OS_RELEASE),4.1.3_U1)
|
||||
ifeq ($(OS_TEST),sun4u)
|
||||
ASFILES += os_$(OS_ARCH)_ultrasparc.s
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), SINIX)
|
||||
ASFILES = os_ReliantUNIX.s
|
||||
endif
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
! %o3 [local] - work register
|
||||
! -----------------------
|
||||
|
||||
ENTRY(PR_AtomicIncrement) ! standard assembler/ELF prologue
|
||||
ENTRY(_pr_md_ultrasparc_inc) ! standard assembler/ELF prologue
|
||||
|
||||
retryAI:
|
||||
ld [%o0], %o2 ! set o2 to the current value
|
||||
|
@ -62,7 +62,7 @@ retryAI:
|
|||
retl ! return back to the caller
|
||||
mov %o1, %o0 ! set the return code to the new value
|
||||
|
||||
SET_SIZE(PR_AtomicIncrement) ! standard assembler/ELF epilogue
|
||||
SET_SIZE(_pr_md_ultrasparc_inc) ! standard assembler/ELF epilogue
|
||||
|
||||
!
|
||||
! end
|
||||
|
@ -93,7 +93,7 @@ retryAI:
|
|||
! %o3 [local] - work register
|
||||
! -----------------------
|
||||
|
||||
ENTRY(PR_AtomicDecrement) ! standard assembler/ELF prologue
|
||||
ENTRY(_pr_md_ultrasparc_dec) ! standard assembler/ELF prologue
|
||||
|
||||
retryAD:
|
||||
ld [%o0], %o2 ! set o2 to the current value
|
||||
|
@ -106,7 +106,7 @@ retryAD:
|
|||
retl ! return back to the caller
|
||||
mov %o1, %o0 ! set the return code to the new value
|
||||
|
||||
SET_SIZE(PR_AtomicDecrement) ! standard assembler/ELF epilogue
|
||||
SET_SIZE(_pr_md_ultrasparc_dec) ! standard assembler/ELF epilogue
|
||||
|
||||
!
|
||||
! end
|
||||
|
@ -136,7 +136,7 @@ retryAD:
|
|||
! %o3 [local] - work register
|
||||
! -----------------------
|
||||
|
||||
ENTRY(PR_AtomicSet) ! standard assembler/ELF prologue
|
||||
ENTRY(_pr_md_ultrasparc_set) ! standard assembler/ELF prologue
|
||||
|
||||
retryAS:
|
||||
ld [%o0], %o2 ! set o2 to the current value
|
||||
|
@ -148,7 +148,7 @@ retryAS:
|
|||
retl ! return back to the caller
|
||||
mov %o3, %o0 ! set the return code to the prev value
|
||||
|
||||
SET_SIZE(PR_AtomicSet) ! standard assembler/ELF epilogue
|
||||
SET_SIZE(_pr_md_ultrasparc_set) ! standard assembler/ELF epilogue
|
||||
|
||||
!
|
||||
! end
|
||||
|
@ -164,7 +164,7 @@ retryAS:
|
|||
! usage : newval = PR_AtomicAdd(address, val)
|
||||
! return: the value after addition
|
||||
!
|
||||
ENTRY(PR_AtomicAdd) ! standard assembler/ELF prologue
|
||||
ENTRY(_pr_md_ultrasparc_add) ! standard assembler/ELF prologue
|
||||
|
||||
retryAA:
|
||||
ld [%o0], %o2 ! set o2 to the current value
|
||||
|
@ -177,7 +177,7 @@ retryAA:
|
|||
retl ! return back to the caller
|
||||
mov %o4, %o0 ! set the return code to the new value
|
||||
|
||||
SET_SIZE(PR_AtomicAdd) ! standard assembler/ELF epilogue
|
||||
SET_SIZE(_pr_md_ultrasparc_add) ! standard assembler/ELF epilogue
|
||||
|
||||
!
|
||||
! end
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
#include "primpl.h"
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
|
||||
extern PRBool suspendAllOn;
|
||||
|
@ -58,8 +59,24 @@ PRIntervalTime _MD_Solaris_GetInterval(void)
|
|||
}
|
||||
|
||||
#ifdef _PR_PTHREADS
|
||||
|
||||
static PRInt32 _md_ultrasparc = 0;
|
||||
|
||||
void _MD_EarlyInit(void)
|
||||
{
|
||||
#define MACHINE_NAME_LEN 32
|
||||
#define ULTRASPARC "sun4u"
|
||||
char machine[MACHINE_NAME_LEN];
|
||||
int rv;
|
||||
|
||||
rv = sysinfo(SI_MACHINE, machine, MACHINE_NAME_LEN);
|
||||
/*
|
||||
* detect an ultrasparc (Sparc V9) system
|
||||
*/
|
||||
if ((rv > 0) && (rv <= MACHINE_NAME_LEN)) {
|
||||
if (!strncmp(machine,ULTRASPARC, strlen(ULTRASPARC)))
|
||||
_md_ultrasparc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
|
||||
|
@ -90,13 +107,22 @@ PRInt32
|
|||
_MD_AtomicIncrement(PRInt32 *val)
|
||||
{
|
||||
PRInt32 rv;
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
rv = ++(*val);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
if (_md_ultrasparc) {
|
||||
rv = _pr_md_ultrasparc_inc(val);
|
||||
} else {
|
||||
#endif
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
rv = ++(*val);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -105,13 +131,22 @@ PRInt32
|
|||
_MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
|
||||
{
|
||||
PRInt32 rv;
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
rv = ((*ptr) += val);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
if (_md_ultrasparc) {
|
||||
rv = _pr_md_ultrasparc_add(ptr, val);
|
||||
} else {
|
||||
#endif
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
rv = ((*ptr) += val);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -120,14 +155,22 @@ PRInt32
|
|||
_MD_AtomicDecrement(PRInt32 *val)
|
||||
{
|
||||
PRInt32 rv;
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
rv = --(*val);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
if (_md_ultrasparc) {
|
||||
rv = _pr_md_ultrasparc_dec(val);
|
||||
} else {
|
||||
#endif
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
rv = --(*val);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -135,15 +178,23 @@ PRInt32
|
|||
_MD_AtomicSet(PRInt32 *val, PRInt32 newval)
|
||||
{
|
||||
PRInt32 rv;
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
rv = *val;
|
||||
*val = newval;
|
||||
#ifdef _PR_ULTRASPARC
|
||||
if (_md_ultrasparc) {
|
||||
rv = _pr_md_ultrasparc_set(val, newval);
|
||||
} else {
|
||||
#endif
|
||||
if (mutex_lock(&_solaris_atomic) != 0)
|
||||
PR_ASSERT(0);
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
rv = *val;
|
||||
*val = newval;
|
||||
|
||||
if (mutex_unlock(&_solaris_atomic) != 0)\
|
||||
PR_ASSERT(0);
|
||||
#ifdef _PR_ULTRASPARC
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
#endif /* _PR_HAVE_ATOMIC_OPS */
|
||||
|
|
|
@ -1429,16 +1429,15 @@ extern sigset_t ints_off;
|
|||
*/
|
||||
if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
|
||||
if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
|
||||
PR_DELETE(pollfds);
|
||||
PR_DELETE(_PR_IOQ_POLLFDS(me->cpu));
|
||||
pollfds_size = PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
|
||||
pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
|
||||
_PR_IOQ_POLLFDS(me->cpu) = pollfds;
|
||||
_PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
|
||||
pollfdPtr = pollfds;
|
||||
} else {
|
||||
pollfds = _PR_IOQ_POLLFDS(me->cpu);
|
||||
pollfdPtr = pollfds;
|
||||
}
|
||||
pollfdPtr = pollfds;
|
||||
|
||||
/*
|
||||
* If we need to poll the pipe for waking up a native thread,
|
||||
|
@ -2522,7 +2521,12 @@ static PRIntn _MD_solaris25_stat64(const char *fn, _MDStat64 *buf)
|
|||
|
||||
static PRIntn _MD_Unix_lockf64(PRIntn osfd, PRIntn function, PRInt64 size)
|
||||
{
|
||||
#if defined(RHAPSODY) || defined(BSDI)
|
||||
#if defined(HAVE_BSD_FLOCK)
|
||||
/*
|
||||
* XXX: HAVE_BSD_FLOCK is not really the appropriate macro
|
||||
* to test for here. We are trying to identify the platforms
|
||||
* that don't have lockf, e.g., BSD/OS, FreeBSD, and Rhapsody.
|
||||
*/
|
||||
/* No lockf */
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return -1;
|
||||
|
|
|
@ -56,9 +56,11 @@ PRThread *me;
|
|||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
me = _MD_GET_ATTACHED_THREAD();
|
||||
if ((me != NULL) && (me->flags & _PR_ATTACHED))
|
||||
_PRI_DetachThread();
|
||||
if (_pr_initialized) {
|
||||
me = _MD_GET_ATTACHED_THREAD();
|
||||
if ((me != NULL) && (me->flags & _PR_ATTACHED))
|
||||
_PRI_DetachThread();
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
|
|
@ -2101,8 +2101,7 @@ _PR_MD_FSYNC(PRFileDesc *fd)
|
|||
* because of this, and if it was, I ignore the error.
|
||||
*/
|
||||
|
||||
long handle = _get_osfhandle(fd->secret->md.osfd);
|
||||
BOOL ok = FlushFileBuffers((HANDLE)handle);
|
||||
BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
|
||||
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
|
|
|
@ -39,9 +39,11 @@ PRThread *me;
|
|||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
me = _MD_GET_ATTACHED_THREAD();
|
||||
if ((me != NULL) && (me->flags & _PR_ATTACHED))
|
||||
_PRI_DetachThread();
|
||||
if (_pr_initialized) {
|
||||
me = _MD_GET_ATTACHED_THREAD();
|
||||
if ((me != NULL) && (me->flags & _PR_ATTACHED))
|
||||
_PRI_DetachThread();
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
|
|
@ -282,8 +282,7 @@ _PR_MD_FSYNC(PRFileDesc *fd)
|
|||
* to this bogosity, and if it was, I ignore the error.
|
||||
*/
|
||||
|
||||
long handle = _get_osfhandle(fd->secret->md.osfd);
|
||||
BOOL ok = FlushFileBuffers((HANDLE)handle);
|
||||
BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
|
||||
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
|
|
|
@ -355,6 +355,7 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
|
|||
* _PR_XXXCleanup() that we can call here.
|
||||
*/
|
||||
_PR_CleanupBeforeExit();
|
||||
_pr_initialized = PR_FALSE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
return PR_FAILURE;
|
||||
|
|
|
@ -25,9 +25,24 @@
|
|||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
PR_IMPLEMENT(char) PR_GetDirectorySepartor()
|
||||
PR_IMPLEMENT(char) PR_GetDirectorySeparator()
|
||||
{
|
||||
return PR_DIRECTORY_SEPARATOR;
|
||||
} /* PR_GetDirectorySeparator */
|
||||
|
||||
/*
|
||||
** OBSOLETE -- the function name is misspelled.
|
||||
*/
|
||||
PR_IMPLEMENT(char) PR_GetDirectorySepartor()
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
static PRBool warn = PR_TRUE;
|
||||
if (warn) {
|
||||
warn = _PR_Obsolete("PR_GetDirectorySepartor()",
|
||||
"PR_GetDirectorySeparator()");
|
||||
}
|
||||
#endif
|
||||
return PR_GetDirectorySeparator();
|
||||
} /* PR_GetDirectorySepartor */
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen)
|
||||
|
|
|
@ -749,7 +749,10 @@ recycle:
|
|||
|
||||
if (NULL != pt_tq.tail)
|
||||
{
|
||||
pt_tq.tail->status = pt_continuation_recycle;
|
||||
if (pt_tq.tail->status != pt_continuation_abort)
|
||||
{
|
||||
pt_tq.tail->status = pt_continuation_recycle;
|
||||
}
|
||||
PR_NotifyCondVar(pt_tq.tail->complete);
|
||||
#if defined(DEBUG)
|
||||
pt_debug.recyclesNeeded += 1;
|
||||
|
@ -789,7 +792,7 @@ static PRIntn pt_Continue(pt_Continuation *op)
|
|||
** will certainly be times within the function when it gets
|
||||
** released.
|
||||
*/
|
||||
pt_tq.thread = PR_GetCurrentThread(); /* I'm taking control */
|
||||
pt_tq.thread = self; /* I'm taking control */
|
||||
pt_ContinuationThreadInternal(op); /* go slash and burn */
|
||||
PR_ASSERT(pt_continuation_done == op->status);
|
||||
pt_tq.thread = NULL; /* I'm abdicating my rule */
|
||||
|
@ -809,15 +812,36 @@ static PRIntn pt_Continue(pt_Continuation *op)
|
|||
* notice, this operation will be finished and the op's status
|
||||
* marked as pt_continuation_done.
|
||||
*/
|
||||
if ((PR_FAILURE == rv) /* the wait failed */
|
||||
&& (pt_continuation_pending == op->status) /* but the op hasn't */
|
||||
&& (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) /* was interrupted */
|
||||
if ((PR_FAILURE == rv) /* the wait was interrupted */
|
||||
&& (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
|
||||
{
|
||||
op->status = pt_continuation_abort; /* go around the loop again */
|
||||
if (pt_continuation_done == op->status)
|
||||
{
|
||||
/*
|
||||
* The op is done and has been removed
|
||||
* from the timed queue. We must not
|
||||
* change op->status, otherwise this
|
||||
* thread will go around the loop again.
|
||||
*
|
||||
* It's harsh to mark the op failed with
|
||||
* interrupt error when the io is already
|
||||
* done, but we should indicate the fact
|
||||
* that the thread was interrupted. So
|
||||
* we set the aborted flag to abort the
|
||||
* thread's next blocking call. Is this
|
||||
* the right thing to do?
|
||||
*/
|
||||
self->state |= PT_THREAD_ABORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* go around the loop again */
|
||||
op->status = pt_continuation_abort;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we're to recycle, continue within this loop. This will
|
||||
* cause this thread to be come the continuation thread.
|
||||
* cause this thread to become the continuation thread.
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -199,24 +199,15 @@ static PRThread* pt_AttachThread(void)
|
|||
* We cannot have PR_AttachThread call implicit initialization
|
||||
* because if multiple threads call PR_AttachThread simultaneously,
|
||||
* NSPR may be initialized more than once.
|
||||
* We can't call PR_SetError() either.
|
||||
* We can't call any function that calls PR_GetCurrentThread()
|
||||
* either (e.g., PR_SetError()) as that will result in infinite
|
||||
* recursion.
|
||||
*/
|
||||
if (!_pr_initialized) return NULL;
|
||||
|
||||
/*
|
||||
* If the thread is already known, it will have a non-NULL value
|
||||
* in its private data. If that's the case, simply suppress the
|
||||
* attach and note an error.
|
||||
*/
|
||||
PTHREAD_GETSPECIFIC(pt_book.key, privateData);
|
||||
if (NULL != privateData)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return NULL;
|
||||
}
|
||||
/* PR_NEWZAP must not call PR_GetCurrentThread() */
|
||||
thred = PR_NEWZAP(PRThread);
|
||||
if (NULL == thred) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
else
|
||||
if (NULL != thred)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
@ -717,6 +708,17 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
|
|||
static void _pt_thread_death(void *arg)
|
||||
{
|
||||
PRThread *thred = (PRThread*)arg;
|
||||
|
||||
if (thred->state & PT_THREAD_FOREIGN)
|
||||
{
|
||||
PR_Lock(pt_book.ml);
|
||||
thred->prev->next = thred->next;
|
||||
if (NULL == thred->next)
|
||||
pt_book.last = thred->prev;
|
||||
else
|
||||
thred->next->prev = thred->prev;
|
||||
PR_Unlock(pt_book.ml);
|
||||
}
|
||||
_PR_DestroyThreadPrivate(thred);
|
||||
if (NULL != thred->errorString)
|
||||
PR_Free(thred->errorString);
|
||||
|
@ -835,6 +837,7 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
|
|||
PR_DestroyLock(pt_book.ml); pt_book.ml = NULL;
|
||||
}
|
||||
_pt_thread_death(me);
|
||||
_pr_initialized = PR_FALSE;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
return PR_FAILURE;
|
||||
|
|
|
@ -62,6 +62,7 @@ CSRCS = \
|
|||
instrumt.c \
|
||||
intrupt.c \
|
||||
io_timeout.c \
|
||||
ioconthr.c \
|
||||
ipv6.c \
|
||||
join.c \
|
||||
joinkk.c \
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "plgetopt.h"
|
||||
#include "plerror.h"
|
||||
|
||||
#define BASE_PORT 8001
|
||||
#define BASE_PORT 10000
|
||||
|
||||
#define CLIENT_DATA 128
|
||||
|
||||
|
@ -62,6 +62,8 @@
|
|||
#define CLIENT_TIMEOUT_ACCEPT 0x2
|
||||
#define CLIENT_TIMEOUT_SEND 0x3
|
||||
|
||||
#define SERVER_MAX_BIND_COUNT 100
|
||||
|
||||
#if defined(XP_MAC) || defined(XP_OS2)
|
||||
#define TIMEOUTSECS 10
|
||||
#else
|
||||
|
@ -185,6 +187,7 @@ static PRInt32 bytesRead;
|
|||
static void
|
||||
RunTest(PRInt32 acceptType, PRInt32 clientAction)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* First bind to the socket */
|
||||
listenSock = PR_NewTCPSocket();
|
||||
|
@ -194,17 +197,28 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
|
|||
PR_fprintf(output, "unable to create listen socket\n");
|
||||
return;
|
||||
}
|
||||
memset(&listenAddr, 0 , sizeof(listenAddr));
|
||||
listenAddr.inet.family = PR_AF_INET;
|
||||
listenAddr.inet.port = PR_htons(BASE_PORT);
|
||||
listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
|
||||
rv = PR_Bind(listenSock, &listenAddr);
|
||||
if (rv == PR_FAILURE) {
|
||||
/*
|
||||
* try a few times to bind server's address, if addresses are in
|
||||
* use
|
||||
*/
|
||||
i = 0;
|
||||
while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) {
|
||||
if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
|
||||
listenAddr.inet.port += 2;
|
||||
if (i++ < SERVER_MAX_BIND_COUNT)
|
||||
continue;
|
||||
}
|
||||
failed_already=1;
|
||||
if (debug_mode)
|
||||
PR_fprintf(output, "unable to bind\n");
|
||||
return;
|
||||
PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
rv = PR_Listen(listenSock, 100);
|
||||
if (rv == PR_FAILURE) {
|
||||
failed_already=1;
|
||||
|
@ -308,7 +322,7 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
|
|||
TEST_ASSERT(status == CLIENT_DATA);
|
||||
break;
|
||||
case CLIENT_TIMEOUT_SEND:
|
||||
TEST_ASSERT(clientSock);
|
||||
TEST_ASSERT(clientSock == NULL);
|
||||
TEST_ASSERT(status == -1);
|
||||
TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
|
||||
break;
|
||||
|
@ -330,7 +344,7 @@ RunTest(PRInt32 acceptType, PRInt32 clientAction)
|
|||
case CLIENT_TIMEOUT_SEND:
|
||||
if (debug_mode)
|
||||
PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock);
|
||||
TEST_ASSERT(clientSock);
|
||||
TEST_ASSERT(clientSock == NULL);
|
||||
TEST_ASSERT(status == -1);
|
||||
TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
|
||||
break;
|
||||
|
|
|
@ -165,7 +165,7 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
if (NULL == filename)
|
||||
{
|
||||
if (DEFAULT_FILESIZE != filesize) return Usage();
|
||||
else filename = "/usr/tmp/bigfile.dat";
|
||||
else filename = "bigfile.dat";
|
||||
}
|
||||
|
||||
if (PR_FAILURE == DeleteIfFound(filename)) return 1;
|
||||
|
|
|
@ -513,9 +513,10 @@ static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
|
|||
server->bytesTransferred += filebytes;
|
||||
PR_Unlock(server->ml);
|
||||
|
||||
rv = PR_Close(file); file = NULL;
|
||||
rv = PR_Close(file);
|
||||
if (Aborted(rv)) goto aborted;
|
||||
TEST_ASSERT(PR_SUCCESS == rv);
|
||||
file = NULL;
|
||||
|
||||
TEST_LOG(
|
||||
cltsrv_log_file, TEST_LOG_VERBOSE,
|
||||
|
@ -596,9 +597,10 @@ static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
|
|||
rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
|
||||
if (Aborted(rv)) goto aborted;
|
||||
|
||||
rv = PR_Close(file); file = NULL;
|
||||
rv = PR_Close(file);
|
||||
if (Aborted(rv)) goto aborted;
|
||||
TEST_ASSERT(PR_SUCCESS == rv);
|
||||
file = NULL;
|
||||
|
||||
aborted:
|
||||
PR_ClearInterrupt();
|
||||
|
|
|
@ -212,6 +212,9 @@ static void PR_CALLBACK lazyEntry(void *arg)
|
|||
static void OneShot(void *arg)
|
||||
{
|
||||
PRUintn pdkey;
|
||||
PRLock *lock;
|
||||
PRFileDesc *fd;
|
||||
PRDir *dir;
|
||||
PRFileDesc *pair[2];
|
||||
PRIntn test = (PRIntn)arg;
|
||||
|
||||
|
@ -220,9 +223,10 @@ static void OneShot(void *arg)
|
|||
switch (test)
|
||||
{
|
||||
case 0:
|
||||
(void)PR_NewLock();
|
||||
lock = PR_NewLock();
|
||||
DPRINTF((output,"Thread[0x%x] called PR_NewLock\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_DestroyLock(lock);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -239,27 +243,31 @@ static void OneShot(void *arg)
|
|||
break;
|
||||
|
||||
case 3:
|
||||
(void)PR_Open("/usr/tmp/", PR_RDONLY, 0);
|
||||
fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666);
|
||||
DPRINTF((output,"Thread[0x%x] called PR_Open\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_Close(fd);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
(void)PR_NewUDPSocket();
|
||||
fd = PR_NewUDPSocket();
|
||||
DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_Close(fd);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
(void)PR_NewTCPSocket();
|
||||
fd = PR_NewTCPSocket();
|
||||
DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_Close(fd);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
(void)PR_OpenDir("/usr/tmp/");
|
||||
dir = PR_OpenDir("/usr/tmp/");
|
||||
DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_CloseDir(dir);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
|
@ -278,6 +286,8 @@ static void OneShot(void *arg)
|
|||
(void)PR_NewTCPSocketPair(pair);
|
||||
DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n",
|
||||
PR_GetCurrentThread()));
|
||||
PR_Close(pair[0]);
|
||||
PR_Close(pair[1]);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
|
|
|
@ -42,7 +42,7 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
PLOptStatus os;
|
||||
PRUint8 *buffer;
|
||||
PRFileDesc *file = NULL;
|
||||
const char *filename = "/usr/tmp/sync.dat";
|
||||
const char *filename = "sync.dat";
|
||||
PRUint32 index, loops, iterations = 10, filesize = 10;
|
||||
PRIntn flags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "hSK:c:");
|
||||
|
|
|
@ -334,7 +334,6 @@ static void TraceTest( void )
|
|||
size = SMALL_TRACE_BUFSIZE;
|
||||
PR_SET_TRACE_OPTION( PRTraceBufSize, &size );
|
||||
PR_GET_TRACE_OPTION( PRTraceBufSize, &i );
|
||||
PR_ASSERT( i == size );
|
||||
|
||||
PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );
|
||||
PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a test for the io continuation thread machinery
|
||||
* in pthreads.
|
||||
*/
|
||||
|
||||
#include "nspr.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int num_threads = 10; /* must be an even number */
|
||||
PRThreadScope thread_scope = PR_GLOBAL_THREAD;
|
||||
|
||||
void ThreadFunc(void *arg)
|
||||
{
|
||||
PRFileDesc *fd = (PRFileDesc *) arg;
|
||||
char buf[1024];
|
||||
PRInt32 nbytes;
|
||||
PRErrorCode err;
|
||||
|
||||
nbytes = PR_Recv(fd, buf, sizeof(buf), 0, PR_SecondsToInterval(20));
|
||||
if (nbytes == -1) {
|
||||
err = PR_GetError();
|
||||
if (err != PR_PENDING_INTERRUPT_ERROR) {
|
||||
fprintf(stderr, "PR_Recv failed: (%d, %d)\n",
|
||||
err, PR_GetOSError());
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
if (PR_Close(fd) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Close failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "PR_Recv received %d bytes!?\n", nbytes);
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PRFileDesc **fds;
|
||||
PRThread **threads;
|
||||
PRIntervalTime start, elapsed;
|
||||
int index;
|
||||
|
||||
fds = (PRFileDesc **) PR_MALLOC(num_threads * sizeof(PRFileDesc *));
|
||||
PR_ASSERT(fds != NULL);
|
||||
threads = (PRThread **) PR_MALLOC(num_threads * sizeof(PRThread *));
|
||||
PR_ASSERT(threads != NULL);
|
||||
|
||||
for (index = 0; index < (num_threads / 2); index++) {
|
||||
if (PR_NewTCPSocketPair(&fds[2 * index]) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_NewTCPSocket failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
|
||||
threads[2 * index] = PR_CreateThread(
|
||||
PR_USER_THREAD, ThreadFunc, fds[2 * index],
|
||||
PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0);
|
||||
if (NULL == threads[2 * index]) {
|
||||
fprintf(stderr, "PR_CreateThread failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
threads[2 * index + 1] = PR_CreateThread(
|
||||
PR_USER_THREAD, ThreadFunc, fds[2 * index + 1],
|
||||
PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0);
|
||||
if (NULL == threads[2 * index + 1]) {
|
||||
fprintf(stderr, "PR_CreateThread failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Let the threads block in PR_Recv */
|
||||
PR_Sleep(PR_SecondsToInterval(2));
|
||||
|
||||
printf("Interrupting the threads\n");
|
||||
fflush(stdout);
|
||||
start = PR_IntervalNow();
|
||||
for (index = 0; index < num_threads; index++) {
|
||||
if (PR_Interrupt(threads[index]) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Interrupt failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
}
|
||||
for (index = 0; index < num_threads; index++) {
|
||||
if (PR_JoinThread(threads[index]) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_JoinThread failed\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
}
|
||||
elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
|
||||
printf("Threads terminated in %d milliseconds\n",
|
||||
PR_IntervalToMilliseconds(elapsed));
|
||||
fflush(stdout);
|
||||
|
||||
/* We are being very generous and allow 10 seconds. */
|
||||
if (elapsed >= PR_SecondsToInterval(10)) {
|
||||
fprintf(stderr, "Interrupting threads took longer than 10 seconds!!\n");
|
||||
PR_ProcessExit(1);
|
||||
}
|
||||
|
||||
PR_DELETE(threads);
|
||||
PR_DELETE(fds);
|
||||
printf("PASS\n");
|
||||
PR_Cleanup();
|
||||
return 0;
|
||||
}
|
|
@ -84,6 +84,9 @@ static void PR_CALLBACK Client(void *arg)
|
|||
PRIntn bytes_read, bytes_sent;
|
||||
PRFileDesc *stack = (PRFileDesc*)arg;
|
||||
|
||||
/* Initialize the buffer so that Purify won't complain */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
|
||||
PR_ASSERT(PR_SUCCESS == rv);
|
||||
while (minor_iterations-- > 0)
|
||||
|
@ -157,7 +160,7 @@ static PRInt32 PR_CALLBACK MyRecv(
|
|||
{
|
||||
char *b = (char*)buf;
|
||||
PRFileDesc *lo = fd->lower;
|
||||
PRInt32 rv, readin = 0, request;
|
||||
PRInt32 rv, readin = 0, request = 0;
|
||||
rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout);
|
||||
if (verbosity > chatty) PR_fprintf(
|
||||
logFile, "MyRecv sending permission for %d bytes\n", request);
|
||||
|
|
|
@ -156,6 +156,9 @@ static void PR_CALLBACK ClientThread(void* arg)
|
|||
if (verbosity > chatty)
|
||||
PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server);
|
||||
|
||||
/* Initialize the buffer so that Purify won't complain */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address);
|
||||
MW_ASSERT(PR_SUCCESS == rv);
|
||||
|
||||
|
@ -259,8 +262,6 @@ static void ManyOpOneThread(Shared *shared)
|
|||
PRRecvWait *desc_in;
|
||||
PRRecvWait *desc_out;
|
||||
|
||||
desc_in = (PRRecvWait*)PR_CALLOC(sizeof(PRRecvWait*) * wait_objects);
|
||||
|
||||
if (verbosity > quiet)
|
||||
PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects);
|
||||
|
||||
|
@ -604,6 +605,7 @@ static void RealOneGroupIO(Shared *shared)
|
|||
rv = PR_JoinThread(client_thread[index]);
|
||||
MW_ASSERT(PR_SUCCESS == rv);
|
||||
}
|
||||
PR_DELETE(client_thread);
|
||||
|
||||
if (verbosity > quiet)
|
||||
PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n", shared->title);
|
||||
|
|
|
@ -50,6 +50,7 @@ static char *hosts[4] = {"cynic", "warp", "gandalf", "neon"};
|
|||
#define SERVER_MAX_BIND_COUNT 100
|
||||
#define DATA_BUF_SIZE 256
|
||||
#define TCP_SERVER_PORT 10000
|
||||
#define TCP_UNUSED_PORT 211
|
||||
|
||||
typedef struct Server_Param {
|
||||
PRFileDesc *sp_fd; /* server port */
|
||||
|
@ -70,7 +71,7 @@ int main(int argc, char **argv)
|
|||
PRPollDesc pd;
|
||||
PRStatus rv;
|
||||
PRSocketOptionData optData;
|
||||
const char *hostname;
|
||||
const char *hostname = NULL;
|
||||
PRIntn default_case, n, bytes_read, bytes_sent;
|
||||
PRInt32 failed_already = 0;
|
||||
#ifdef XP_MAC
|
||||
|
@ -279,7 +280,7 @@ connection_success_test()
|
|||
Server_Param sp;
|
||||
char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE];
|
||||
PRIntn default_case, n, bytes_read, bytes_sent;
|
||||
PRIntn failed_already;
|
||||
PRIntn failed_already = 0;
|
||||
|
||||
/*
|
||||
* Create a tcp socket
|
||||
|
@ -341,11 +342,6 @@ connection_success_test()
|
|||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
} else {
|
||||
PR_ASSERT(rv == PR_SUCCESS);
|
||||
fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n");
|
||||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
/*
|
||||
* Now create a thread to accept a connection
|
||||
|
@ -373,12 +369,6 @@ connection_success_test()
|
|||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
if (pd.out_flags != PR_POLL_WRITE) {
|
||||
fprintf(stderr,"Error - PR_Poll returned invalid outflags: 0x%x\n",
|
||||
pd.out_flags);
|
||||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
|
||||
PRInt32 rv;
|
||||
|
||||
|
@ -520,6 +510,12 @@ connection_failure_test()
|
|||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
#ifdef AIX
|
||||
/*
|
||||
* On AIX, set to unused/reserved port
|
||||
*/
|
||||
netaddr.inet.port = PR_htons(TCP_UNUSED_PORT);
|
||||
#endif
|
||||
if ((conn_fd = PR_NewTCPSocket()) == NULL) {
|
||||
fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
|
||||
failed_already=1;
|
||||
|
@ -551,12 +547,6 @@ connection_failure_test()
|
|||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
if (pd.out_flags != PR_POLL_WRITE) {
|
||||
fprintf(stderr,"Error - PR_Poll returned invalid outflags: 0x%x\n",
|
||||
pd.out_flags);
|
||||
failed_already=1;
|
||||
goto def_exit;
|
||||
}
|
||||
if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
|
||||
PRInt32 rv;
|
||||
fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n");
|
||||
|
|
|
@ -100,6 +100,9 @@ static void PR_CALLBACK Client(void *arg)
|
|||
PRIntn bytes_read, bytes_sent;
|
||||
PRFileDesc *stack = (PRFileDesc*)arg;
|
||||
|
||||
/* Initialize the buffer so that Purify won't complain */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
|
||||
if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
|
||||
{
|
||||
|
@ -299,9 +302,8 @@ static void PR_CALLBACK Server(void *arg)
|
|||
} while (0 != bytes_read);
|
||||
|
||||
if (verbosity > quiet)
|
||||
PR_fprintf(logFile, "Server shutting down and closing stack\n");
|
||||
PR_fprintf(logFile, "Server shutting down stack\n");
|
||||
rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
|
||||
rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
|
||||
|
||||
} /* Server */
|
||||
|
||||
|
@ -630,4 +632,4 @@ PRIntn main(PRIntn argc, char **argv)
|
|||
return 0;
|
||||
} /* main */
|
||||
|
||||
/* layer.c */
|
||||
/* nblayer.c */
|
||||
|
|
|
@ -74,6 +74,9 @@ clientThreadFunc(void *arg)
|
|||
PRStatus retVal;
|
||||
PRInt32 nBytes;
|
||||
|
||||
/* Initialize the buffer so that Purify won't complain */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
addr.inet.family = PR_AF_INET;
|
||||
addr.inet.port = PR_htons((PRUint16)port);
|
||||
addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
#define SEND_FLAGS 0
|
||||
#define BUFFER_SIZE 1024
|
||||
#define DEFAULT_BACKLOG 5
|
||||
#define DEFAULT_PORT 12848
|
||||
#define DEFAULT_PORT 13000
|
||||
#define DEFAULT_CLIENTS 1
|
||||
#define ALLOWED_IN_ACCEPT 1
|
||||
#define DEFAULT_CLIPPING 1000
|
||||
|
@ -706,7 +706,7 @@ static PRStatus NewThread(
|
|||
PRThread *thread = PR_CreateThread(
|
||||
PR_USER_THREAD, start, arg,
|
||||
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, 0);
|
||||
PR_JOINABLE_THREAD, 0);
|
||||
rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
@ -1070,6 +1070,7 @@ PRIntn main(PRIntn argc, char** argv)
|
|||
CSClient_t *client;
|
||||
PRStatus rv, joinStatus;
|
||||
CSServer_t *server = NULL;
|
||||
char *thread_type;
|
||||
|
||||
PRUintn backlog = DEFAULT_BACKLOG;
|
||||
PRUintn clients = DEFAULT_CLIENTS;
|
||||
|
@ -1095,6 +1096,16 @@ PRIntn main(PRIntn argc, char** argv)
|
|||
PLOptStatus os;
|
||||
PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp");
|
||||
|
||||
#if defined(WIN32)
|
||||
thread_provider = thread_win32;
|
||||
#elif defined(_PR_PTHREADS)
|
||||
thread_provider = thread_pthread;
|
||||
#elif defined(IRIX)
|
||||
thread_provider = thread_sproc;
|
||||
#else
|
||||
thread_provider = thread_nspr;
|
||||
#endif
|
||||
|
||||
debug_out = PR_GetSpecialFD(PR_StandardError);
|
||||
|
||||
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
||||
|
@ -1347,7 +1358,18 @@ PRIntn main(PRIntn argc, char** argv)
|
|||
cltsrv_log_file, TEST_LOG_ALWAYS,
|
||||
("main(0x%p): test complete\n", PR_CurrentThread()));
|
||||
|
||||
PT_FPrintStats(debug_out, "\nPThread Statistics\n");
|
||||
if (thread_provider == thread_win32)
|
||||
thread_type = "\nWin32 Thread Statistics\n";
|
||||
else if (thread_provider == thread_pthread)
|
||||
thread_type = "\npthread Statistics\n";
|
||||
else if (thread_provider == thread_sproc)
|
||||
thread_type = "\nsproc Statistics\n";
|
||||
else {
|
||||
PR_ASSERT(thread_provider == thread_nspr);
|
||||
thread_type = "\nPRThread Statistics\nn";
|
||||
}
|
||||
|
||||
PT_FPrintStats(debug_out, thread_type);
|
||||
|
||||
TimeOfDayMessage("Test exiting at", PR_CurrentThread());
|
||||
return 0;
|
||||
|
|
|
@ -58,7 +58,7 @@ extern void SetupMacPrintfLog(char *logFile);
|
|||
#define DPRINTF(arg) if (_debug_on) printf arg
|
||||
|
||||
#ifdef XP_PC
|
||||
char *TEST_DIR = "C:\\tmp\\prdir";
|
||||
char *TEST_DIR = "prdir";
|
||||
char *SMALL_FILE_NAME = "prsmallf";
|
||||
char *LARGE_FILE_NAME = "prlargef";
|
||||
#else
|
||||
|
|
|
@ -129,8 +129,10 @@ PRIntn main(PRIntn argc, char *argv)
|
|||
value = &boolean;
|
||||
size = &booleansize;
|
||||
break;
|
||||
#ifndef WIN32
|
||||
case PR_SockOpt_MaxSegment: /* maximum segment size */
|
||||
socket = tcp;
|
||||
#endif
|
||||
case PR_SockOpt_RecvBufferSize: /* send buffer size */
|
||||
case PR_SockOpt_SendBufferSize: /* receive buffer size */
|
||||
value = &segment;
|
||||
|
@ -150,9 +152,20 @@ PRIntn main(PRIntn argc, char *argv)
|
|||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = PR_SetSockOpt(socket, option, value, *size);
|
||||
if (PR_FAILURE == rv) Failed("PR_SetSockOpt()", tag[option]);
|
||||
/*
|
||||
* TCP_MAXSEG can only be read, not set
|
||||
*/
|
||||
if (option != PR_SockOpt_MaxSegment) {
|
||||
#ifdef WIN32
|
||||
if ((option != PR_SockOpt_McastTimeToLive) &&
|
||||
(option != PR_SockOpt_McastLoopback))
|
||||
#endif
|
||||
{
|
||||
rv = PR_SetSockOpt(socket, option, value, *size);
|
||||
if (PR_FAILURE == rv) Failed("PR_SetSockOpt()",
|
||||
tag[option]);
|
||||
}
|
||||
}
|
||||
|
||||
rv = PR_GetSockOpt(socket, option, &value, size);
|
||||
if (PR_FAILURE == rv) Failed("PR_GetSockOpt()", tag[option]);
|
||||
|
@ -200,14 +213,28 @@ PRIntn main(PRIntn argc, char *argv)
|
|||
case PR_SockOpt_NoDelay:
|
||||
data.value.no_delay = PR_TRUE;
|
||||
break;
|
||||
#ifndef WIN32
|
||||
case PR_SockOpt_MaxSegment:
|
||||
data.value.max_segment = segment;
|
||||
break;
|
||||
#endif
|
||||
default: continue;
|
||||
}
|
||||
|
||||
rv = PR_SetSocketOption(fd, &data);
|
||||
if (PR_FAILURE == rv) Failed("PR_SetSocketOption()", tag[option]);
|
||||
/*
|
||||
* TCP_MAXSEG can only be read, not set
|
||||
*/
|
||||
if (option != PR_SockOpt_MaxSegment) {
|
||||
#ifdef WIN32
|
||||
if ((option != PR_SockOpt_McastTimeToLive) &&
|
||||
(option != PR_SockOpt_McastLoopback))
|
||||
#endif
|
||||
{
|
||||
rv = PR_SetSocketOption(fd, &data);
|
||||
if (PR_FAILURE == rv)
|
||||
Failed("PR_SetSocketOption()", tag[option]);
|
||||
}
|
||||
}
|
||||
|
||||
rv = PR_GetSocketOption(fd, &data);
|
||||
if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]);
|
||||
|
|
|
@ -425,7 +425,7 @@ int Tmocon(int argc, char **argv)
|
|||
PR_fprintf(
|
||||
PR_GetSpecialFD(PR_StandardError), "%s\n",
|
||||
((shared->failed) ? "FAILED" : "PASSED"));
|
||||
return (shared->failed) ? 0 : 1;
|
||||
return (shared->failed) ? 1 : 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
Загрузка…
Ссылка в новой задаче