mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-19 23:07:33 +09:00
Revert "Update NSPR to 4.18"
This reverts commit 8781f745556be5d7402d0f3adc67ecfe32fe04a0.
This commit is contained in:
parent
9e32522120
commit
cd3167e35d
32 changed files with 395 additions and 295 deletions
|
|
@ -138,8 +138,12 @@ endif
|
|||
|
||||
ifeq ($(OS_ARCH),HP-UX)
|
||||
ifeq ($(USE_PTHREADS), 1)
|
||||
ifeq (,$(filter-out B.10.10 B.10.20,$(OS_RELEASE)))
|
||||
OS_LIBS = -ldce
|
||||
else
|
||||
OS_LIBS = -lpthread -lrt
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PTHREADS_USER), 1)
|
||||
OS_LIBS = -lpthread
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -137,82 +137,11 @@ PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd)
|
|||
_PR_Putfd(fd);
|
||||
}
|
||||
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
|
||||
PRFileDescList *_fd_waiting_for_overlapped_done = NULL;
|
||||
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->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;
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(_fd_waiting_for_overlapped_done_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Wait for some i/o to finish on one or more more poll descriptors.
|
||||
*/
|
||||
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();
|
||||
#endif
|
||||
|
||||
return(_PR_MD_PR_POLL(pds, npds, timeout));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,25 +304,7 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
|
|||
if (err != 0) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
} else {
|
||||
#if defined(_WIN64)
|
||||
if (fd->secret->overlappedActive) {
|
||||
PRInt32 rvSent;
|
||||
if (GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE) == FALSE) {
|
||||
err = WSAGetLastError();
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("SocketConnectContinue GetOverlappedResult failed %d\n", err));
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
}
|
||||
#else
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
#endif
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
@ -737,56 +719,6 @@ static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd)
|
|||
}
|
||||
|
||||
if (fd->secret->state == _PR_FILEDESC_OPEN) {
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
/* TCP Fast Open on Windows must use ConnectEx, which uses overlapped
|
||||
* input/output. Before closing such a socket we must cancelIO.
|
||||
*/
|
||||
if (fd->secret->overlappedActive) {
|
||||
PR_ASSERT(fd->secret->nonblocking);
|
||||
if (CancelIo((HANDLE) fd->secret->md.osfd) == TRUE) {
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("SocketClose - CancelIo succeeded\n"));
|
||||
} else {
|
||||
DWORD err = WSAGetLastError();
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("SocketClose - CancelIo failed err=%x\n", err));
|
||||
}
|
||||
|
||||
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,
|
||||
("SocketClose GetOverlappedResult succeeded\n"));
|
||||
} else {
|
||||
DWORD err = WSAGetLastError();
|
||||
PR_LOG(_pr_io_lm, PR_LOG_MIN,
|
||||
("SocketClose GetOverlappedResult failed %d\n", err));
|
||||
if (err != ERROR_IO_INCOMPLETE) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
fd->secret->overlappedActive = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd->secret->overlappedActive &&
|
||||
_fd_waiting_for_overlapped_done_lock) {
|
||||
// Put osfd into the list to be checked later.
|
||||
PRFileDescList *forWaiting = PR_NEW(PRFileDescList);
|
||||
if (!forWaiting) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
forWaiting->fd = fd;
|
||||
|
||||
PR_Lock(_fd_waiting_for_overlapped_done_lock);
|
||||
forWaiting->next = _fd_waiting_for_overlapped_done;
|
||||
_fd_waiting_for_overlapped_done = forWaiting;
|
||||
PR_Unlock(_fd_waiting_for_overlapped_done_lock);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2854,11 +2854,28 @@ void _PR_UnixInit(void)
|
|||
#endif
|
||||
#endif /* !defined(_PR_PTHREADS) */
|
||||
|
||||
/*
|
||||
* Under HP-UX DCE threads, sigaction() installs a per-thread
|
||||
* handler, so we use sigvector() to install a process-wide
|
||||
* handler.
|
||||
*/
|
||||
#if defined(HPUX) && defined(_PR_DCETHREADS)
|
||||
{
|
||||
struct sigvec vec;
|
||||
|
||||
vec.sv_handler = SIG_IGN;
|
||||
vec.sv_mask = 0;
|
||||
vec.sv_flags = 0;
|
||||
rv = sigvector(SIGPIPE, &vec, NULL);
|
||||
PR_ASSERT(0 == rv);
|
||||
}
|
||||
#else
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
rv = sigaction(SIGPIPE, &sigact, 0);
|
||||
PR_ASSERT(0 == rv);
|
||||
#endif /* HPUX && _PR_DCETHREADS */
|
||||
|
||||
_pr_rename_lock = PR_NewLock();
|
||||
PR_ASSERT(NULL != _pr_rename_lock);
|
||||
|
|
|
|||
|
|
@ -685,6 +685,10 @@ static void pr_SigchldHandler(int sig)
|
|||
|
||||
static void pr_InstallSigchldHandler()
|
||||
{
|
||||
#if defined(HPUX) && defined(_PR_DCETHREADS)
|
||||
#error "HP-UX DCE threads have their own SIGCHLD handler"
|
||||
#endif
|
||||
|
||||
struct sigaction act, oact;
|
||||
int rv;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ PRUint32 _nt_idleCount;
|
|||
extern __declspec(thread) PRThread *_pr_io_restarted_io;
|
||||
extern DWORD _pr_io_restartedIOIndex;
|
||||
|
||||
typedef HRESULT (WINAPI *SETTHREADDESCRIPTION)(HANDLE, PCWSTR);
|
||||
static SETTHREADDESCRIPTION sSetThreadDescription = NULL;
|
||||
|
||||
/* Must check the restarted_io *before* decrementing no_sched to 0 */
|
||||
#define POST_SWITCH_WORK() \
|
||||
PR_BEGIN_MACRO \
|
||||
|
|
@ -82,8 +79,6 @@ _nt_handle_restarted_io(PRThread *restarted_io)
|
|||
void
|
||||
_PR_MD_EARLY_INIT()
|
||||
{
|
||||
HMODULE hModule;
|
||||
|
||||
_MD_NEW_LOCK( &_nt_idleLock );
|
||||
_nt_idleCount = 0;
|
||||
PR_INIT_CLIST(&_nt_idleList);
|
||||
|
|
@ -103,15 +98,6 @@ _PR_MD_EARLY_INIT()
|
|||
_pr_intsOffIndex = TlsAlloc();
|
||||
_pr_io_restartedIOIndex = TlsAlloc();
|
||||
}
|
||||
|
||||
// SetThreadDescription is Windows 10 build 1607+
|
||||
hModule = GetModuleHandleW(L"kernel32.dll");
|
||||
if (hModule) {
|
||||
sSetThreadDescription =
|
||||
(SETTHREADDESCRIPTION) GetProcAddress(
|
||||
hModule,
|
||||
"SetThreadDescription");
|
||||
}
|
||||
}
|
||||
|
||||
void _PR_MD_CLEANUP_BEFORE_EXIT(void)
|
||||
|
|
@ -307,16 +293,7 @@ _PR_MD_SET_CURRENT_THREAD_NAME(const char *name)
|
|||
{
|
||||
#ifdef _MSC_VER
|
||||
THREADNAME_INFO info;
|
||||
#endif
|
||||
|
||||
if (sSetThreadDescription) {
|
||||
WCHAR wideName[MAX_PATH];
|
||||
if (MultiByteToWideChar(CP_ACP, 0, name, -1, wideName, MAX_PATH)) {
|
||||
sSetThreadDescription(GetCurrentThread(), wideName);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if (!IsDebuggerPresent())
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -382,11 +382,6 @@ PRInt32
|
|||
_PR_MD_TCPSENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
|
||||
const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
|
||||
{
|
||||
if (!_fd_waiting_for_overlapped_done_lock) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if (PR_CallOnce(&_pr_has_connectex_once, _pr_set_connectex) != PR_SUCCESS) {
|
||||
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/* -*- 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
|
||||
|
|
@ -28,32 +27,14 @@ DWORD _pr_currentCPUIndex;
|
|||
int _pr_intsOff = 0;
|
||||
_PRInterruptTable _pr_interruptTable[] = { { 0 } };
|
||||
|
||||
typedef HRESULT (WINAPI *SETTHREADDESCRIPTION)(HANDLE, PCWSTR);
|
||||
static SETTHREADDESCRIPTION sSetThreadDescription = NULL;
|
||||
|
||||
void
|
||||
_PR_MD_EARLY_INIT()
|
||||
{
|
||||
HMODULE hModule;
|
||||
|
||||
#ifndef _PR_USE_STATIC_TLS
|
||||
_pr_currentThreadIndex = TlsAlloc();
|
||||
_pr_lastThreadIndex = TlsAlloc();
|
||||
_pr_currentCPUIndex = TlsAlloc();
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
_fd_waiting_for_overlapped_done_lock = PR_NewLock();
|
||||
#endif
|
||||
|
||||
// SetThreadDescription is Windows 10 build 1607+
|
||||
hModule = GetModuleHandleW(L"kernel32.dll");
|
||||
if (hModule) {
|
||||
sSetThreadDescription =
|
||||
(SETTHREADDESCRIPTION) GetProcAddress(
|
||||
hModule,
|
||||
"SetThreadDescription");
|
||||
}
|
||||
}
|
||||
|
||||
void _PR_MD_CLEANUP_BEFORE_EXIT(void)
|
||||
|
|
@ -69,29 +50,6 @@ void _PR_MD_CLEANUP_BEFORE_EXIT(void)
|
|||
TlsFree(_pr_lastThreadIndex);
|
||||
TlsFree(_pr_currentCPUIndex);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64) && defined(WIN95)
|
||||
// For each iteration check if TFO overlapped IOs are down.
|
||||
if (_fd_waiting_for_overlapped_done_lock) {
|
||||
PRIntervalTime delay = PR_MillisecondsToInterval(1000);
|
||||
PRFileDescList *cur;
|
||||
do {
|
||||
CheckOverlappedPendingSocketsAreDone();
|
||||
|
||||
PR_Lock(_fd_waiting_for_overlapped_done_lock);
|
||||
cur = _fd_waiting_for_overlapped_done;
|
||||
PR_Unlock(_fd_waiting_for_overlapped_done_lock);
|
||||
#if defined(DO_NOT_WAIT_FOR_CONNECT_OVERLAPPED_OPERATIONS)
|
||||
cur = NULL;
|
||||
#endif
|
||||
if (cur) {
|
||||
PR_Sleep(delay); // wait another 1s.
|
||||
}
|
||||
} while (cur);
|
||||
|
||||
PR_DestroyLock(_fd_waiting_for_overlapped_done_lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PRStatus
|
||||
|
|
@ -232,16 +190,7 @@ _PR_MD_SET_CURRENT_THREAD_NAME(const char *name)
|
|||
{
|
||||
#ifdef _MSC_VER
|
||||
THREADNAME_INFO info;
|
||||
#endif
|
||||
|
||||
if (sSetThreadDescription) {
|
||||
WCHAR wideName[MAX_PATH];
|
||||
if (MultiByteToWideChar(CP_ACP, 0, name, -1, wideName, MAX_PATH)) {
|
||||
sSetThreadDescription(GetCurrentThread(), wideName);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if (!IsDebuggerPresent())
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -166,26 +166,21 @@ void _MD_win32_map_default_error(PRInt32 err)
|
|||
prError = PR_ADDRESS_IN_USE_ERROR;
|
||||
break;
|
||||
case WSAEADDRNOTAVAIL:
|
||||
case ERROR_INVALID_NETNAME:
|
||||
prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
case ERROR_INCORRECT_ADDRESS:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case WSAEALREADY:
|
||||
case ERROR_ALREADY_INITIALIZED:
|
||||
prError = PR_ALREADY_INITIATED_ERROR;
|
||||
break;
|
||||
case WSAEBADF:
|
||||
prError = PR_BAD_DESCRIPTOR_ERROR;
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
case ERROR_CONNECTION_ABORTED:
|
||||
prError = PR_CONNECT_ABORTED_ERROR;
|
||||
break;
|
||||
case WSAECONNREFUSED:
|
||||
case ERROR_CONNECTION_REFUSED:
|
||||
prError = PR_CONNECT_REFUSED_ERROR;
|
||||
break;
|
||||
case WSAECONNRESET:
|
||||
|
|
@ -198,7 +193,6 @@ void _MD_win32_map_default_error(PRInt32 err)
|
|||
prError = PR_ACCESS_FAULT_ERROR;
|
||||
break;
|
||||
case WSAEHOSTUNREACH:
|
||||
case ERROR_HOST_UNREACHABLE:
|
||||
prError = PR_HOST_UNREACHABLE_ERROR;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
|
|
@ -214,14 +208,12 @@ void _MD_win32_map_default_error(PRInt32 err)
|
|||
prError = PR_BUFFER_OVERFLOW_ERROR;
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
case ERROR_NO_NETWORK:
|
||||
prError = PR_NETWORK_DOWN_ERROR;
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
prError = PR_CONNECT_ABORTED_ERROR;
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
case ERROR_NETWORK_UNREACHABLE:
|
||||
prError = PR_NETWORK_UNREACHABLE_ERROR;
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#if !defined(_PR_HAVE_ATOMIC_OPS)
|
||||
|
||||
#if defined(_PR_PTHREADS)
|
||||
#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
|
||||
/*
|
||||
* PR_AtomicDecrement() is used in NSPR's thread-specific data
|
||||
* destructor. Because thread-specific data destructors may be
|
||||
|
|
@ -190,7 +190,7 @@ _PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
|
|||
pthread_mutex_unlock(&atomic_locks[idx]);
|
||||
return rv;
|
||||
}
|
||||
#else /* _PR_PTHREADS */
|
||||
#else /* _PR_PTHREADS && !_PR_DCETHREADS */
|
||||
/*
|
||||
* We use a single lock for all the emulated atomic operations.
|
||||
* The lock contention should be acceptable.
|
||||
|
|
@ -259,7 +259,7 @@ _PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
|
|||
PR_Unlock(atomic_lock);
|
||||
return rv;
|
||||
}
|
||||
#endif /* _PR_PTHREADS */
|
||||
#endif /* _PR_PTHREADS && !_PR_DCETHREADS */
|
||||
|
||||
#endif /* !_PR_HAVE_ATOMIC_OPS */
|
||||
|
||||
|
|
|
|||
|
|
@ -1895,6 +1895,19 @@ static PRInt32 pt_Send(
|
|||
PRInt32 tmp_amount = amount;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,
|
||||
* which has the following:
|
||||
* # define send cma_send
|
||||
* extern int cma_send (int , void *, int, int );
|
||||
* So we need to cast away the 'const' of argument #2 for send().
|
||||
*/
|
||||
#if defined (HPUX) && defined(_PR_DCETHREADS)
|
||||
#define PT_SENDBUF_CAST (void *)
|
||||
#else
|
||||
#define PT_SENDBUF_CAST
|
||||
#endif
|
||||
|
||||
if (pt_TestAbort()) return bytes;
|
||||
|
||||
/*
|
||||
|
|
@ -1905,9 +1918,9 @@ static PRInt32 pt_Send(
|
|||
#if defined(SOLARIS)
|
||||
PR_ASSERT(0 == flags);
|
||||
retry:
|
||||
bytes = write(fd->secret->md.osfd, buf, tmp_amount);
|
||||
bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount);
|
||||
#else
|
||||
bytes = send(fd->secret->md.osfd, buf, amount, flags);
|
||||
bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags);
|
||||
#endif
|
||||
syserrno = errno;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ static pthread_condattr_t _pt_cvar_attr;
|
|||
|
||||
#if defined(DEBUG)
|
||||
extern PTDebug pt_debug; /* this is shared between several modules */
|
||||
|
||||
#if defined(_PR_DCETHREADS)
|
||||
static pthread_t pt_zero_tid; /* a null pthread_t (pthread_t is a struct
|
||||
* in DCE threads) to compare with */
|
||||
#endif /* defined(_PR_DCETHREADS) */
|
||||
#endif /* defined(DEBUG) */
|
||||
|
||||
#if defined(FREEBSD)
|
||||
|
|
@ -258,7 +263,12 @@ static PRIntn pt_TimedWait(
|
|||
rv = pthread_cond_timedwait(cv, ml, &tmo);
|
||||
|
||||
/* NSPR doesn't report timeouts */
|
||||
#ifdef _PR_DCETHREADS
|
||||
if (rv == -1) return (errno == EAGAIN) ? 0 : errno;
|
||||
else return rv;
|
||||
#else
|
||||
return (rv == ETIMEDOUT) ? 0 : rv;
|
||||
#endif
|
||||
} /* pt_TimedWait */
|
||||
|
||||
|
||||
|
|
@ -1161,14 +1171,14 @@ PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
|
|||
PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock)
|
||||
{
|
||||
PRIntn rv = pthread_mutex_trylock(&lock->mutex);
|
||||
if (rv == 0)
|
||||
if (rv == PT_TRYLOCK_SUCCESS)
|
||||
{
|
||||
PR_ASSERT(PR_FALSE == lock->locked);
|
||||
lock->locked = PR_TRUE;
|
||||
lock->owner = pthread_self();
|
||||
}
|
||||
/* XXX set error code? */
|
||||
return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
|
||||
return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE;
|
||||
} /* PRP_TryLock */
|
||||
|
||||
PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
** Exports: ptthread.h
|
||||
*/
|
||||
|
||||
#if defined(_PR_PTHREADS)
|
||||
#if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS)
|
||||
|
||||
#include "prlog.h"
|
||||
#include "primpl.h"
|
||||
|
|
@ -58,7 +58,7 @@ static struct _PT_Bookeeping
|
|||
pthread_key_t key; /* thread private data key */
|
||||
PRBool keyCreated; /* whether 'key' should be deleted */
|
||||
PRThread *first, *last; /* list of threads we know about */
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(_PR_DCETHREADS) || _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
PRInt32 minPrio, maxPrio; /* range of scheduling priorities */
|
||||
#endif
|
||||
} pt_book = {0};
|
||||
|
|
@ -67,7 +67,7 @@ static void _pt_thread_death(void *arg);
|
|||
static void _pt_thread_death_internal(void *arg, PRBool callDestructors);
|
||||
static void init_pthread_gc_support(void);
|
||||
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(_PR_DCETHREADS) || _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
static PRIntn pt_PriorityMap(PRThreadPriority pri)
|
||||
{
|
||||
#ifdef NTO
|
||||
|
|
@ -148,6 +148,21 @@ static void *_pt_root(void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** DCE Threads can't detach during creation, so do it late.
|
||||
** I would like to do it only here, but that doesn't seem
|
||||
** to work.
|
||||
*/
|
||||
#if defined(_PR_DCETHREADS)
|
||||
if (detached)
|
||||
{
|
||||
/* pthread_detach() modifies its argument, so we must pass a copy */
|
||||
pthread_t self = id;
|
||||
rv = pthread_detach(&self);
|
||||
PR_ASSERT(0 == rv);
|
||||
}
|
||||
#endif /* defined(_PR_DCETHREADS) */
|
||||
|
||||
/* Set up the thread stack information */
|
||||
_PR_InitializeStack(thred->stack);
|
||||
|
||||
|
|
@ -314,7 +329,7 @@ static PRThread* _PR_CreateThread(
|
|||
|
||||
if (EPERM != pt_schedpriv)
|
||||
{
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if !defined(_PR_DCETHREADS) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
struct sched_param schedule;
|
||||
#endif
|
||||
|
||||
|
|
@ -325,7 +340,10 @@ static PRThread* _PR_CreateThread(
|
|||
|
||||
/* Use the default scheduling policy */
|
||||
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(_PR_DCETHREADS)
|
||||
rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority));
|
||||
PR_ASSERT(0 == rv);
|
||||
#elif _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
rv = pthread_attr_getschedparam(&tattr, &schedule);
|
||||
PR_ASSERT(0 == rv);
|
||||
schedule.sched_priority = pt_PriorityMap(priority);
|
||||
|
|
@ -335,13 +353,19 @@ static PRThread* _PR_CreateThread(
|
|||
rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */
|
||||
PR_ASSERT(0 == rv);
|
||||
#endif
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING > 0 */
|
||||
#endif /* !defined(_PR_DCETHREADS) */
|
||||
}
|
||||
|
||||
/*
|
||||
* DCE threads can't set detach state before creating the thread.
|
||||
* AIX can't set detach late. Why can't we all just get along?
|
||||
*/
|
||||
#if !defined(_PR_DCETHREADS)
|
||||
rv = pthread_attr_setdetachstate(&tattr,
|
||||
((PR_JOINABLE_THREAD == state) ?
|
||||
PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
|
||||
PR_ASSERT(0 == rv);
|
||||
#endif /* !defined(_PR_DCETHREADS) */
|
||||
|
||||
/*
|
||||
* If stackSize is 0, we use the default pthread stack size.
|
||||
|
|
@ -432,6 +456,7 @@ static PRThread* _PR_CreateThread(
|
|||
*/
|
||||
rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
|
||||
|
||||
#if !defined(_PR_DCETHREADS)
|
||||
if (EPERM == rv)
|
||||
{
|
||||
#if defined(IRIX)
|
||||
|
|
@ -457,10 +482,15 @@ static PRThread* _PR_CreateThread(
|
|||
#endif /* IRIX */
|
||||
rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (0 != rv)
|
||||
{
|
||||
#if defined(_PR_DCETHREADS)
|
||||
PRIntn oserr = errno;
|
||||
#else
|
||||
PRIntn oserr = rv;
|
||||
#endif
|
||||
PR_Lock(pt_book.ml);
|
||||
if (thred->state & PT_THREAD_SYSTEM)
|
||||
pt_book.system -= 1;
|
||||
|
|
@ -572,6 +602,10 @@ PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred)
|
|||
PR_ASSERT(rv == 0 && result == NULL);
|
||||
if (0 == rv)
|
||||
{
|
||||
#ifdef _PR_DCETHREADS
|
||||
rv = pthread_detach(&id);
|
||||
PR_ASSERT(0 == rv);
|
||||
#endif
|
||||
/*
|
||||
* PR_FALSE, because the thread already called the TPD
|
||||
* destructors before exiting _pt_root.
|
||||
|
|
@ -659,7 +693,10 @@ PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri
|
|||
else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)newPri)
|
||||
newPri = PR_PRIORITY_LAST;
|
||||
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(_PR_DCETHREADS)
|
||||
rv = pthread_setprio(thred->id, pt_PriorityMap(newPri));
|
||||
/* pthread_setprio returns the old priority */
|
||||
#elif _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
if (EPERM != pt_schedpriv)
|
||||
{
|
||||
int policy;
|
||||
|
|
@ -890,7 +927,7 @@ void _PR_InitThreads(
|
|||
pthread_init();
|
||||
#endif
|
||||
|
||||
#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(_PR_DCETHREADS) || _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
#if defined(FREEBSD)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
|
|
@ -1124,7 +1161,11 @@ PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
|
|||
|
||||
PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thred)
|
||||
{
|
||||
#if defined(_PR_DCETHREADS)
|
||||
return (PRUint32)&thred->id; /* this is really a sham! */
|
||||
#else
|
||||
return (PRUint32)thred->id; /* and I don't know what they will do with it */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1156,6 +1197,18 @@ PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg)
|
|||
* Garbage collection support follows.
|
||||
*/
|
||||
|
||||
#if defined(_PR_DCETHREADS)
|
||||
|
||||
/*
|
||||
* statics for Garbage Collection support. We don't need to protect these
|
||||
* signal masks since the garbage collector itself is protected by a lock
|
||||
* and multiple threads will not be garbage collecting at the same time.
|
||||
*/
|
||||
static sigset_t javagc_vtalarm_sigmask;
|
||||
static sigset_t javagc_intsoff_sigmask;
|
||||
|
||||
#else /* defined(_PR_DCETHREADS) */
|
||||
|
||||
/* a bogus signal mask for forcing a timed wait */
|
||||
/* Not so bogus in AIX as we really do a sigwait */
|
||||
static sigset_t sigwait_set;
|
||||
|
|
@ -1171,6 +1224,8 @@ static void suspend_signal_handler(PRIntn sig);
|
|||
static void null_signal_handler(PRIntn sig);
|
||||
#endif
|
||||
|
||||
#endif /* defined(_PR_DCETHREADS) */
|
||||
|
||||
/*
|
||||
* Linux pthreads use SIGUSR1 and SIGUSR2 internally, which
|
||||
* conflict with the use of these two signals in our GC support.
|
||||
|
|
@ -1181,6 +1236,12 @@ static void init_pthread_gc_support(void)
|
|||
#ifndef SYMBIAN
|
||||
PRIntn rv;
|
||||
|
||||
#if defined(_PR_DCETHREADS)
|
||||
rv = sigemptyset(&javagc_vtalarm_sigmask);
|
||||
PR_ASSERT(0 == rv);
|
||||
rv = sigaddset(&javagc_vtalarm_sigmask, SIGVTALRM);
|
||||
PR_ASSERT(0 == rv);
|
||||
#else /* defined(_PR_DCETHREADS) */
|
||||
{
|
||||
struct sigaction sigact_usr2;
|
||||
|
||||
|
|
@ -1208,6 +1269,7 @@ static void init_pthread_gc_support(void)
|
|||
PR_ASSERT(0 ==rv);
|
||||
}
|
||||
#endif /* defined(PT_NO_SIGTIMEDWAIT) */
|
||||
#endif /* defined(_PR_DCETHREADS) */
|
||||
#endif /* SYMBIAN */
|
||||
}
|
||||
|
||||
|
|
@ -1238,7 +1300,9 @@ PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
|
|||
PRThread* thred = pt_book.first;
|
||||
|
||||
#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
|
||||
#if !defined(_PR_DCETHREADS)
|
||||
PRThread *me = PR_GetCurrentThread();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_EnumerateThreads\n"));
|
||||
|
|
@ -1267,7 +1331,9 @@ PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
|
|||
|
||||
if (_PT_IS_GCABLE_THREAD(thred))
|
||||
{
|
||||
#if !defined(_PR_DCETHREADS)
|
||||
PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED));
|
||||
#endif
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,
|
||||
("In PR_EnumerateThreads callback thread %p thid = %X\n",
|
||||
thred, thred->id));
|
||||
|
|
@ -1295,6 +1361,8 @@ PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
|
|||
* proceed until the thread is suspended or resumed.
|
||||
*/
|
||||
|
||||
#if !defined(_PR_DCETHREADS)
|
||||
|
||||
/*
|
||||
* In the signal handler, we can not use condition variable notify or wait.
|
||||
* This does not work consistently across all pthread platforms. We also can not
|
||||
|
|
@ -1593,6 +1661,78 @@ PR_IMPLEMENT(void *)PR_GetSP(PRThread *thred)
|
|||
return thred->sp;
|
||||
} /* PR_GetSP */
|
||||
|
||||
#else /* !defined(_PR_DCETHREADS) */
|
||||
|
||||
static pthread_once_t pt_gc_support_control = pthread_once_init;
|
||||
|
||||
/*
|
||||
* For DCE threads, there is no pthread_kill or a way of suspending or resuming a
|
||||
* particular thread. We will just disable the preemption (virtual timer alarm) and
|
||||
* let the executing thread finish the garbage collection. This stops all other threads
|
||||
* (GC able or not) and is very inefficient but there is no other choice.
|
||||
*/
|
||||
PR_IMPLEMENT(void) PR_SuspendAll()
|
||||
{
|
||||
PRIntn rv;
|
||||
|
||||
rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support);
|
||||
PR_ASSERT(0 == rv); /* returns -1 on failure */
|
||||
#ifdef DEBUG
|
||||
suspendAllOn = PR_TRUE;
|
||||
#endif
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
|
||||
/*
|
||||
* turn off preemption - i.e add virtual alarm signal to the set of
|
||||
* blocking signals
|
||||
*/
|
||||
rv = sigprocmask(
|
||||
SIG_BLOCK, &javagc_vtalarm_sigmask, &javagc_intsoff_sigmask);
|
||||
PR_ASSERT(0 == rv);
|
||||
suspendAllSuspended = PR_TRUE;
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_SuspendAll\n"));
|
||||
} /* PR_SuspendAll */
|
||||
|
||||
PR_IMPLEMENT(void) PR_ResumeAll()
|
||||
{
|
||||
PRIntn rv;
|
||||
|
||||
suspendAllSuspended = PR_FALSE;
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n"));
|
||||
/* turn on preemption - i.e re-enable virtual alarm signal */
|
||||
|
||||
rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL);
|
||||
PR_ASSERT(0 == rv);
|
||||
#ifdef DEBUG
|
||||
suspendAllOn = PR_FALSE;
|
||||
#endif
|
||||
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n"));
|
||||
} /* PR_ResumeAll */
|
||||
|
||||
/* Return the stack pointer for the given thread- used by the GC */
|
||||
PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred)
|
||||
{
|
||||
pthread_t tid = thred->id;
|
||||
char *thread_tcb, *top_sp;
|
||||
|
||||
/*
|
||||
* For HPUX DCE threads, pthread_t is a struct with the
|
||||
* following three fields (see pthread.h, dce/cma.h):
|
||||
* cma_t_address field1;
|
||||
* short int field2;
|
||||
* short int field3;
|
||||
* where cma_t_address is typedef'd to be either void*
|
||||
* or char*.
|
||||
*/
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_GetSP\n"));
|
||||
thread_tcb = (char*)tid.field1;
|
||||
top_sp = *(char**)(thread_tcb + 128);
|
||||
PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_GetSP %p \n", top_sp));
|
||||
return top_sp;
|
||||
} /* PR_GetSP */
|
||||
|
||||
#endif /* !defined(_PR_DCETHREADS) */
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name)
|
||||
{
|
||||
PRThread *thread;
|
||||
|
|
@ -1677,6 +1817,6 @@ PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread)
|
|||
return thread->name;
|
||||
}
|
||||
|
||||
#endif /* defined(_PR_PTHREADS) */
|
||||
#endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
|
||||
|
||||
/* ptthread.c */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(HPUX) && defined(_PR_PTHREADS)
|
||||
#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
|
||||
|
||||
#include <pthread.h>
|
||||
#define HAVE_UNIX98_RWLOCK
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue