diff options
author | wtc%netscape.com <devnull@localhost> | 2003-09-11 00:29:37 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2003-09-11 00:29:37 +0000 |
commit | 7833838dc872c52014deb72b018bf8d297b1c88d (patch) | |
tree | c13642e33461338454893870500925f557ee6bad | |
parent | a1bc1b5e718250c3ca18736f80c0e6d4ff3f092e (diff) | |
download | nspr-hg-7833838dc872c52014deb72b018bf8d297b1c88d.tar.gz |
Bugzilla bug 214411: implement automatic attaching and detaching of SolarisNSPR_4_4_BASE
native threads. The patch contains contribution by Gerard Roos
<gerard.roos@adnovum.ch>.
Modified Files: _solaris.h primpl.h solaris.c pruthr.c foreign.c provider.c
-rw-r--r-- | pr/include/md/_solaris.h | 2 | ||||
-rw-r--r-- | pr/include/private/primpl.h | 3 | ||||
-rw-r--r-- | pr/src/md/unix/solaris.c | 35 | ||||
-rw-r--r-- | pr/src/threads/combined/pruthr.c | 7 | ||||
-rw-r--r-- | pr/tests/foreign.c | 39 | ||||
-rw-r--r-- | pr/tests/provider.c | 57 |
6 files changed, 134 insertions, 9 deletions
diff --git a/pr/include/md/_solaris.h b/pr/include/md/_solaris.h index 01b5fed4..811681bf 100644 --- a/pr/include/md/_solaris.h +++ b/pr/include/md/_solaris.h @@ -221,6 +221,7 @@ extern struct PRLock *_pr_schedLock; #define THREAD_KEY_T thread_key_t +extern struct PRThread *_pr_attached_thread_tls(); extern struct PRThread *_pr_current_thread_tls(); extern struct _PRCPU *_pr_current_cpu_tls(); extern struct PRThread *_pr_last_thread_tls(); @@ -229,6 +230,7 @@ extern THREAD_KEY_T threadid_key; extern THREAD_KEY_T cpuid_key; extern THREAD_KEY_T last_thread_key; +#define _MD_GET_ATTACHED_THREAD() _pr_attached_thread_tls() #define _MD_CURRENT_THREAD() _pr_current_thread_tls() #define _MD_CURRENT_CPU() _pr_current_cpu_tls() #define _MD_LAST_THREAD() _pr_last_thread_tls() diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index b0cd1b5b..351781bf 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -304,7 +304,8 @@ typedef struct _PRInterruptTable { #define _PR_CPU_PTR(_qp) \ ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links))) -#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) +#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \ + && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) #define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD()) #endif diff --git a/pr/src/md/unix/solaris.c b/pr/src/md/unix/solaris.c index 4dd1c06e..3313ac83 100644 --- a/pr/src/md/unix/solaris.c +++ b/pr/src/md/unix/solaris.c @@ -183,9 +183,25 @@ THREAD_KEY_T cpuid_key; THREAD_KEY_T last_thread_key; static sigset_t set, oldset; +static void +threadid_key_destructor(void *value) +{ + PRThread *me = (PRThread *)value; + PR_ASSERT((me != NULL) && (me->flags & _PR_ATTACHED)); + /* + * The Solaris thread library sets the thread specific + * data (the current thread) to NULL before invoking + * the destructor. We need to restore it to prevent the + * _PR_MD_CURRENT_THREAD() call in _PRI_DetachThread() + * from attaching the thread again. + */ + _PR_MD_SET_CURRENT_THREAD(me); + _PRI_DetachThread(); +} + void _MD_EarlyInit(void) { - THR_KEYCREATE(&threadid_key, NULL); + THR_KEYCREATE(&threadid_key, threadid_key_destructor); THR_KEYCREATE(&cpuid_key, NULL); THR_KEYCREATE(&last_thread_key, NULL); sigemptyset(&set); @@ -337,7 +353,7 @@ void _MD_lock(struct _MDLock *md_lock) mutex_lock(&md_lock->lock); } -PRThread *_pr_current_thread_tls() +PRThread *_pr_attached_thread_tls() { PRThread *ret; @@ -345,6 +361,21 @@ PRThread *_pr_current_thread_tls() return ret; } +PRThread *_pr_current_thread_tls() +{ + PRThread *thread; + + thread = _MD_GET_ATTACHED_THREAD(); + + if (NULL == thread) { + thread = _PRI_AttachThread( + PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); + } + PR_ASSERT(thread != NULL); + + return thread; +} + PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks) { diff --git a/pr/src/threads/combined/pruthr.c b/pr/src/threads/combined/pruthr.c index cbdfd2c0..a86fe5d0 100644 --- a/pr/src/threads/combined/pruthr.c +++ b/pr/src/threads/combined/pruthr.c @@ -1510,13 +1510,14 @@ PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type, PR_IMPLEMENT(void) PR_DetachThread(void) { /* - * On IRIX and Windows, foreign threads are detached when + * On IRIX, Solaris, and Windows, foreign threads are detached when * they terminate. */ -#if !defined(IRIX) && !defined(WIN32) +#if !defined(IRIX) && !defined(WIN32) \ + && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) PRThread *me; if (_pr_initialized) { - me = _MD_GET_ATTACHED_THREAD(); + me = _PR_MD_GET_ATTACHED_THREAD(); if ((me != NULL) && (me->flags & _PR_ATTACHED)) _PRI_DetachThread(); } diff --git a/pr/tests/foreign.c b/pr/tests/foreign.c index 2fe48b1b..5457cc8c 100644 --- a/pr/tests/foreign.c +++ b/pr/tests/foreign.c @@ -63,7 +63,7 @@ #include <stdlib.h> static enum { - thread_nspr, thread_pthread, thread_sproc, thread_win32 + thread_nspr, thread_pthread, thread_uithread, thread_sproc, thread_win32 } thread_provider; typedef void (*StartFn)(void*); @@ -94,6 +94,18 @@ static void *pthread_start(void *arg) } /* pthread_start */ #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ +#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) +#include <thread.h> +static void *uithread_start(void *arg) +{ + StartFn start = ((StartObject*)arg)->start; + void *data = ((StartObject*)arg)->arg; + PR_Free(arg); + start(data); + return NULL; +} /* uithread_start */ +#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */ + #if defined(IRIX) && !defined(_PR_PTHREADS) #include <sys/types.h> #include <sys/prctl.h> @@ -169,6 +181,29 @@ static PRStatus CreateThread(StartFn start, void *arg) break; #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + case thread_uithread: +#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) + { + int rv; + thread_t id; + long flags; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + + flags = THR_DETACHED; + + rv = thr_create(NULL, NULL, uithread_start, start_object, flags, &id); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; + break; +#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */ + case thread_sproc: #if defined(IRIX) && !defined(_PR_PTHREADS) { @@ -335,6 +370,8 @@ PRIntn main(PRIntn argc, char **argv) thread_provider = thread_win32; #elif defined(_PR_PTHREADS) thread_provider = thread_pthread; +#elif defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) + thread_provider = thread_uithread; #elif defined(IRIX) thread_provider = thread_sproc; #else diff --git a/pr/tests/provider.c b/pr/tests/provider.c index 5fd91bea..9fc68d13 100644 --- a/pr/tests/provider.c +++ b/pr/tests/provider.c @@ -127,7 +127,7 @@ typedef enum Verbosity } Verbosity; static enum { - thread_nspr, thread_pthread, thread_sproc, thread_win32 + thread_nspr, thread_pthread, thread_uithread, thread_sproc, thread_win32 } thread_provider; static PRInt32 domain = AF_INET; @@ -658,6 +658,20 @@ static void *pthread_start(void *arg) } /* pthread_start */ #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ +#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) +#include <thread.h> + +static void *uithread_start(void *arg) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); + return NULL; +} /* uithread_start */ +#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */ + #if defined(IRIX) && !defined(_PR_PTHREADS) #include <sys/types.h> #include <sys/prctl.h> @@ -698,6 +712,11 @@ static PRStatus JoinThread(PRThread *thread) rv = PR_SUCCESS; break; #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + case thread_uithread: +#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) + rv = PR_SUCCESS; + break; +#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */ case thread_win32: #if defined(WIN32) rv = PR_SUCCESS; @@ -759,6 +778,29 @@ static PRStatus NewThread( #endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ break; + case thread_uithread: +#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) + { + int rv; + thread_t id; + long flags; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + + flags = THR_DETACHED; + + rv = thr_create(NULL, NULL, uithread_start, start_object, flags, &id); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */ + break; + case thread_sproc: #if defined(IRIX) && !defined(_PR_PTHREADS) { @@ -947,9 +989,15 @@ static void PR_CALLBACK Server(void *arg) PRNetAddr serverAddress; CSServer_t *server = (CSServer_t*)arg; PRThread *me = server->thread = PR_CurrentThread(); + PRSocketOptionData sockOpt; server->listener = PR_Socket(domain, SOCK_STREAM, protocol); + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(server->listener, &sockOpt); + TEST_ASSERT(PR_SUCCESS == rv); + memset(&serverAddress, 0, sizeof(serverAddress)); rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress); @@ -1063,7 +1111,7 @@ static void Help(void) PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds (10)\n"); PR_fprintf(debug_out, "\t-s <string> dsn name of server (localhost)\n"); PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n"); - PR_fprintf(debug_out, "\t-T <string> thread provider ('n' | 'p' | 'w')(n)\n"); + PR_fprintf(debug_out, "\t-T <string> thread provider ('n' | 'p' | 'u' | 'w')(n)\n"); PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n"); PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n"); PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n"); @@ -1115,6 +1163,8 @@ PRIntn main(PRIntn argc, char** argv) thread_provider = thread_win32; #elif defined(_PR_PTHREADS) thread_provider = thread_pthread; +#elif defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) + thread_provider = thread_uithread; #elif defined(IRIX) thread_provider = thread_sproc; #else @@ -1146,6 +1196,7 @@ PRIntn main(PRIntn argc, char** argv) case 'T': /* the thread provider */ if ('n' == *opt->value) thread_provider = thread_nspr; else if ('p' == *opt->value) thread_provider = thread_pthread; + else if ('u' == *opt->value) thread_provider = thread_uithread; else if ('w' == *opt->value) thread_provider = thread_win32; else {Help(); return 2; } break; @@ -1374,6 +1425,8 @@ PRIntn main(PRIntn argc, char** argv) thread_type = "\nWin32 Thread Statistics\n"; else if (thread_provider == thread_pthread) thread_type = "\npthread Statistics\n"; + else if (thread_provider == thread_uithread) + thread_type = "\nUnix International (UI) Thread Statistics\n"; else if (thread_provider == thread_sproc) thread_type = "\nsproc Statistics\n"; else { |