diff --git a/nsprpub/pr/include/private/primpl.h b/nsprpub/pr/include/private/primpl.h index ea4f5070e4b..3bdf038033b 100644 --- a/nsprpub/pr/include/private/primpl.h +++ b/nsprpub/pr/include/private/primpl.h @@ -158,6 +158,7 @@ struct _PT_Notified #define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */ #define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */ #define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */ +#define PT_THREAD_BOUND 0x100 /* a bound-global thread */ /* ** Possible values for thread's suspend field diff --git a/nsprpub/pr/include/prthread.h b/nsprpub/pr/include/prthread.h index c9ff0bced55..7d132508c03 100644 --- a/nsprpub/pr/include/prthread.h +++ b/nsprpub/pr/include/prthread.h @@ -71,7 +71,8 @@ typedef enum PRThreadType { typedef enum PRThreadScope { PR_LOCAL_THREAD, - PR_GLOBAL_THREAD + PR_GLOBAL_THREAD, + PR_GLOBAL_BOUND_THREAD } PRThreadScope; typedef enum PRThreadState { diff --git a/nsprpub/pr/src/md/unix/solaris.c b/nsprpub/pr/src/md/unix/solaris.c index 882cbca48d9..439cb94f70b 100644 --- a/nsprpub/pr/src/md/unix/solaris.c +++ b/nsprpub/pr/src/md/unix/solaris.c @@ -200,7 +200,8 @@ PRStatus _MD_CreateThread(PRThread *thread, * when the corresponding NSPR threads terminate. */ flags = THR_SUSPENDED|THR_DETACHED; - if (thread->flags & (_PR_GCABLE_THREAD|_PR_BOUND_THREAD)) + if ((thread->flags & (_PR_GCABLE_THREAD|_PR_BOUND_THREAD)) || + (scope == PR_GLOBAL_BOUND_THREAD)) flags |= THR_BOUND; if (thr_create(NULL, thread->stack->stackSize, @@ -219,8 +220,8 @@ PRStatus _MD_CreateThread(PRThread *thread, thr_sigsetmask(SIG_SETMASK, &oldset, NULL); _MD_NEW_SEM(&thread->md.waiter_sem, 0); - if (scope == PR_GLOBAL_THREAD) { - thread->flags |= _PR_GLOBAL_SCOPE; + if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) { + thread->flags |= _PR_GLOBAL_SCOPE; } _MD_SET_PRIORITY(&(thread->md), priority); diff --git a/nsprpub/pr/src/md/unix/unixware.c b/nsprpub/pr/src/md/unix/unixware.c index 76c9c751fb0..b6c4de77e82 100644 --- a/nsprpub/pr/src/md/unix/unixware.c +++ b/nsprpub/pr/src/md/unix/unixware.c @@ -256,7 +256,8 @@ PRStatus _MD_CREATE_THREAD(PRThread *thread, flags = (state == PR_JOINABLE_THREAD ? THR_SUSPENDED/*|THR_NEW_LWP*/ : THR_SUSPENDED|THR_DETACHED/*|THR_NEW_LWP*/); - if (thread->flags & _PR_GCABLE_THREAD) + if ((thread->flags & _PR_GCABLE_THREAD) || + (scope == PR_GLOBAL_BOUND_THREAD)) flags |= THR_BOUND; if (thr_create(NULL, thread->stack->stackSize, @@ -276,8 +277,8 @@ PRStatus _MD_CREATE_THREAD(PRThread *thread, thr_sigsetmask(SIG_SETMASK, &oldset, NULL); _MD_NEW_SEM(&thread->md.waiter_sem, 0); - if (scope == PR_GLOBAL_THREAD) { - thread->flags |= _PR_GLOBAL_SCOPE; + if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) { + thread->flags |= _PR_GLOBAL_SCOPE; } /* diff --git a/nsprpub/pr/src/pthreads/ptthread.c b/nsprpub/pr/src/pthreads/ptthread.c index 10f6112ec56..d69220c6ff5 100644 --- a/nsprpub/pr/src/pthreads/ptthread.c +++ b/nsprpub/pr/src/pthreads/ptthread.c @@ -311,6 +311,8 @@ static PRThread* _PR_CreateThread( thred->state |= PT_THREAD_DETACHED; if (PR_GLOBAL_THREAD == scope) thred->state |= PT_THREAD_GLOBAL; + if (PR_GLOBAL_BOUND_THREAD == scope) + thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND); if (PR_SYSTEM_THREAD == type) thred->state |= PT_THREAD_SYSTEM; @@ -339,6 +341,9 @@ static PRThread* _PR_CreateThread( else pt_book.user += 1; PR_Unlock(pt_book.ml); + if (thred->state & PT_THREAD_BOUND) { + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM); + } /* * We pass a pointer to a local copy (instead of thred->id) * to pthread_create() because who knows what wacky things @@ -518,7 +523,8 @@ PR_IMPLEMENT(PRThread*) PR_GetCurrentThread() PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thred) { - return PR_GLOBAL_THREAD; + return (thred->state & PT_THREAD_BOUND) ? + PR_GLOBAL_BOUND_THREAD : PR_GLOBAL_THREAD; } /* PR_GetThreadScope() */ PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thred) diff --git a/nsprpub/pr/src/threads/combined/pruthr.c b/nsprpub/pr/src/threads/combined/pruthr.c index 94cd9071e2c..d279d791b5a 100644 --- a/nsprpub/pr/src/threads/combined/pruthr.c +++ b/nsprpub/pr/src/threads/combined/pruthr.c @@ -1088,10 +1088,15 @@ PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type, me = _PR_MD_CURRENT_THREAD(); #if defined(_PR_GLOBAL_THREADS_ONLY) - scope = PR_GLOBAL_THREAD; + /* + * can create global threads only + */ + if (scope == PR_LOCAL_THREAD) + scope = PR_GLOBAL_THREAD; #endif - native = ((scope == PR_GLOBAL_THREAD) && _PR_IS_NATIVE_THREAD_SUPPORTED()); + native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD)) + && _PR_IS_NATIVE_THREAD_SUPPORTED()); _PR_ADJUST_STACKSIZE(stackSize); diff --git a/nsprpub/pr/src/threads/prcthr.c b/nsprpub/pr/src/threads/prcthr.c index 4f1c35a58e2..288b3fd2430 100644 --- a/nsprpub/pr/src/threads/prcthr.c +++ b/nsprpub/pr/src/threads/prcthr.c @@ -403,9 +403,10 @@ PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread) #endif if (!_pr_initialized) _PR_ImplicitInitialization(); - if (_PR_IS_NATIVE_THREAD(thread)) - return PR_GLOBAL_THREAD; - else + if (_PR_IS_NATIVE_THREAD(thread)) { + return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD : + PR_GLOBAL_THREAD; + } else return PR_LOCAL_THREAD; }