diff options
Diffstat (limited to 'nsprpub/pr/src')
-rw-r--r-- | nsprpub/pr/src/Makefile.in | 4 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prio.c | 71 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prsocket.c | 68 | ||||
-rw-r--r-- | nsprpub/pr/src/md/unix/unix.c | 17 | ||||
-rw-r--r-- | nsprpub/pr/src/md/unix/uxproces.c | 4 | ||||
-rw-r--r-- | nsprpub/pr/src/md/windows/ntthread.c | 23 | ||||
-rw-r--r-- | nsprpub/pr/src/md/windows/w95sock.c | 5 | ||||
-rw-r--r-- | nsprpub/pr/src/md/windows/w95thred.c | 51 | ||||
-rw-r--r-- | nsprpub/pr/src/md/windows/win32_errors.c | 8 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/pratom.c | 6 | ||||
-rw-r--r-- | nsprpub/pr/src/pthreads/ptio.c | 17 | ||||
-rw-r--r-- | nsprpub/pr/src/pthreads/ptsynch.c | 14 | ||||
-rw-r--r-- | nsprpub/pr/src/pthreads/ptthread.c | 158 | ||||
-rw-r--r-- | nsprpub/pr/src/threads/prrwlock.c | 2 |
14 files changed, 205 insertions, 243 deletions
diff --git a/nsprpub/pr/src/Makefile.in b/nsprpub/pr/src/Makefile.in index 19c5a6987..48b6faed7 100644 --- a/nsprpub/pr/src/Makefile.in +++ b/nsprpub/pr/src/Makefile.in @@ -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 diff --git a/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c index 10ae5e098..bf9763a2c 100644 --- a/nsprpub/pr/src/io/prio.c +++ b/nsprpub/pr/src/io/prio.c @@ -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)); } diff --git a/nsprpub/pr/src/io/prsocket.c b/nsprpub/pr/src/io/prsocket.c index 26f7a245d..a24b8e1bb 100644 --- a/nsprpub/pr/src/io/prsocket.c +++ b/nsprpub/pr/src/io/prsocket.c @@ -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; } diff --git a/nsprpub/pr/src/md/unix/unix.c b/nsprpub/pr/src/md/unix/unix.c index 29e24e574..662f561b6 100644 --- a/nsprpub/pr/src/md/unix/unix.c +++ b/nsprpub/pr/src/md/unix/unix.c @@ -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); diff --git a/nsprpub/pr/src/md/unix/uxproces.c b/nsprpub/pr/src/md/unix/uxproces.c index 18f23fde8..5286b9e18 100644 --- a/nsprpub/pr/src/md/unix/uxproces.c +++ b/nsprpub/pr/src/md/unix/uxproces.c @@ -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; diff --git a/nsprpub/pr/src/md/windows/ntthread.c b/nsprpub/pr/src/md/windows/ntthread.c index 1fdf0e93b..fead1236d 100644 --- a/nsprpub/pr/src/md/windows/ntthread.c +++ b/nsprpub/pr/src/md/windows/ntthread.c @@ -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; diff --git a/nsprpub/pr/src/md/windows/w95sock.c b/nsprpub/pr/src/md/windows/w95sock.c index c6a3ec111..0429c655a 100644 --- a/nsprpub/pr/src/md/windows/w95sock.c +++ b/nsprpub/pr/src/md/windows/w95sock.c @@ -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; diff --git a/nsprpub/pr/src/md/windows/w95thred.c b/nsprpub/pr/src/md/windows/w95thred.c index a365411f5..c27d982a7 100644 --- a/nsprpub/pr/src/md/windows/w95thred.c +++ b/nsprpub/pr/src/md/windows/w95thred.c @@ -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; diff --git a/nsprpub/pr/src/md/windows/win32_errors.c b/nsprpub/pr/src/md/windows/win32_errors.c index 275792187..d26820a7a 100644 --- a/nsprpub/pr/src/md/windows/win32_errors.c +++ b/nsprpub/pr/src/md/windows/win32_errors.c @@ -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: diff --git a/nsprpub/pr/src/misc/pratom.c b/nsprpub/pr/src/misc/pratom.c index 65e6f3cd8..95bbee1d5 100644 --- a/nsprpub/pr/src/misc/pratom.c +++ b/nsprpub/pr/src/misc/pratom.c @@ -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 */ diff --git a/nsprpub/pr/src/pthreads/ptio.c b/nsprpub/pr/src/pthreads/ptio.c index f6aa56741..9dde03191 100644 --- a/nsprpub/pr/src/pthreads/ptio.c +++ b/nsprpub/pr/src/pthreads/ptio.c @@ -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; diff --git a/nsprpub/pr/src/pthreads/ptsynch.c b/nsprpub/pr/src/pthreads/ptsynch.c index a93b74795..251205336 100644 --- a/nsprpub/pr/src/pthreads/ptsynch.c +++ b/nsprpub/pr/src/pthreads/ptsynch.c @@ -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) diff --git a/nsprpub/pr/src/pthreads/ptthread.c b/nsprpub/pr/src/pthreads/ptthread.c index 6046d5d8d..9e12606ea 100644 --- a/nsprpub/pr/src/pthreads/ptthread.c +++ b/nsprpub/pr/src/pthreads/ptthread.c @@ -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,8 +1300,10 @@ 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 */ diff --git a/nsprpub/pr/src/threads/prrwlock.c b/nsprpub/pr/src/threads/prrwlock.c index 1dd9e0a90..2e0f9ea4e 100644 --- a/nsprpub/pr/src/threads/prrwlock.c +++ b/nsprpub/pr/src/threads/prrwlock.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 |