From cf44d9dcf99a195bd7532c9ba2eb8197c27c849e Mon Sep 17 00:00:00 2001 From: "wtc%netscape.com" Date: Thu, 20 Dec 2001 05:24:02 +0000 Subject: [PATCH] Bugzilla bug 115149: clean up threads properly on non-emx platforms. Increased the default thread stack size to 64K. The patch is contributed by aaronr@us.ibm.com and Michael Kaply . Modified files: _os2.h os2cv.c os2io.c os2thred.c --- nsprpub/pr/include/md/_os2.h | 9 +++--- nsprpub/pr/src/md/os2/os2cv.c | 10 +++---- nsprpub/pr/src/md/os2/os2io.c | 10 +++---- nsprpub/pr/src/md/os2/os2thred.c | 50 ++++++++++---------------------- 4 files changed, 29 insertions(+), 50 deletions(-) diff --git a/nsprpub/pr/include/md/_os2.h b/nsprpub/pr/include/md/_os2.h index c11daf5762e..d98262d1d5f 100644 --- a/nsprpub/pr/include/md/_os2.h +++ b/nsprpub/pr/include/md/_os2.h @@ -96,17 +96,16 @@ typedef int (*FARPROC)(); #define _MD_MAGIC_DIR 0x55555555 #define _MD_MAGIC_CV 0x66666666 -typedef struct _MDSemaphore -{ +struct _MDSemaphore { HEV sem; -} MDSEM; +}; struct _MDCPU { int unused; }; struct _MDThread { - MDSEM blocked_sema; /* Threads block on this when waiting + HEV blocked_sema; /* Threads block on this when waiting * for IO or CondVar. */ PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the @@ -326,7 +325,7 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, #define _MD_PUT_ENV (_PR_MD_PUT_ENV) /* --- Threading Stuff --- */ -#define _MD_DEFAULT_STACK_SIZE 32767L +#define _MD_DEFAULT_STACK_SIZE 65536L #define _MD_INIT_THREAD (_PR_MD_INIT_THREAD) #define _MD_INIT_ATTACHED_THREAD (_PR_MD_INIT_THREAD) #define _MD_CREATE_THREAD (_PR_MD_CREATE_THREAD) diff --git a/nsprpub/pr/src/md/os2/os2cv.c b/nsprpub/pr/src/md/os2/os2cv.c index e5c026e3657..1a2d9399bf2 100644 --- a/nsprpub/pr/src/md/os2/os2cv.c +++ b/nsprpub/pr/src/md/os2/os2cv.c @@ -177,7 +177,7 @@ md_UnlockAndPostNotifies( next = thred->md.next; thred->md.prev = thred->md.next = NULL; - rv = DosPostEventSem(thred->md.blocked_sema.sem); + rv = DosPostEventSem(thred->md.blocked_sema); PR_ASSERT(rv == NO_ERROR); thred = next; } @@ -274,9 +274,9 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) } /* Wait for notification or timeout; don't really care which */ - rv = DosWaitEventSem(thred->md.blocked_sema.sem, msecs); + rv = DosWaitEventSem(thred->md.blocked_sema, msecs); if (rv == NO_ERROR) { - DosResetEventSem(thred->md.blocked_sema.sem, &count); + DosResetEventSem(thred->md.blocked_sema, &count); } DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT); @@ -315,9 +315,9 @@ _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) * times out. Wait on the semaphore again to make it * non-signaled. We assume this wait won't take long. */ - rv = DosWaitEventSem(thred->md.blocked_sema.sem, SEM_INDEFINITE_WAIT); + rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT); if (rv == NO_ERROR) { - DosResetEventSem(thred->md.blocked_sema.sem, &count); + DosResetEventSem(thred->md.blocked_sema, &count); } PR_ASSERT(rv == NO_ERROR); } diff --git a/nsprpub/pr/src/md/os2/os2io.c b/nsprpub/pr/src/md/os2/os2io.c index 44cee6464f4..12e2f2a2d87 100644 --- a/nsprpub/pr/src/md/os2/os2io.c +++ b/nsprpub/pr/src/md/os2/os2io.c @@ -80,8 +80,8 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks); - rv = DosWaitEventSem(thread->md.blocked_sema.sem, msecs); - DosResetEventSem(thread->md.blocked_sema.sem, &count); + rv = DosWaitEventSem(thread->md.blocked_sema, msecs); + DosResetEventSem(thread->md.blocked_sema, &count); switch(rv) { case NO_ERROR: @@ -101,8 +101,8 @@ _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) * call SemRequest() to clear the semaphore. */ _PR_THREAD_UNLOCK(thread); - rv = DosWaitEventSem(thread->md.blocked_sema.sem, 0); - DosResetEventSem(thread->md.blocked_sema.sem, &count); + rv = DosWaitEventSem(thread->md.blocked_sema, 0); + DosResetEventSem(thread->md.blocked_sema, &count); PR_ASSERT(rv == NO_ERROR); } } @@ -118,7 +118,7 @@ _PR_MD_WAKEUP_WAITER(PRThread *thread) { if ( _PR_IS_NATIVE_THREAD(thread) ) { - if (DosPostEventSem(thread->md.blocked_sema.sem) != NO_ERROR) + if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) return PR_FAILURE; else return PR_SUCCESS; diff --git a/nsprpub/pr/src/md/os2/os2thred.c b/nsprpub/pr/src/md/os2/os2thred.c index 55d07da5d34..d64ae0b9f4a 100644 --- a/nsprpub/pr/src/md/os2/os2thred.c +++ b/nsprpub/pr/src/md/os2/os2thred.c @@ -43,10 +43,6 @@ #include #endif -/* --- Declare these to avoid "implicit" warnings --- */ -PR_EXTERN(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value); -PR_EXTERN(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md); - /* --- globals ------------------------------------------------ */ _NSPR_TLS* pThreadLocalStorage = 0; _PRInterruptTable _pr_interruptTable[] = { { 0 } }; @@ -96,6 +92,7 @@ _pr_SetThreadMDHandle(PRThread *thread) PRStatus _PR_MD_INIT_THREAD(PRThread *thread) { + APIRET rv; #ifdef XP_OS2_EMX /* disable SIGPIPE */ struct sigaction sa; @@ -110,8 +107,8 @@ _PR_MD_INIT_THREAD(PRThread *thread) } /* Create the blocking IO semaphore */ - _PR_MD_NEW_SEM(&thread->md.blocked_sema, 1); - return (thread->md.blocked_sema.sem != 0) ? PR_SUCCESS : PR_FAILURE; + rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0); + return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE; } PRStatus @@ -178,40 +175,23 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) void _PR_MD_CLEAN_THREAD(PRThread *thread) { - if (&thread->md.blocked_sema) { - _PR_MD_DESTROY_SEM(&thread->md.blocked_sema); - } - - if (thread->md.handle) { - DosKillThread(thread->md.handle); - thread->md.handle = 0; - } + APIRET rv; + + if (thread->md.blocked_sema) { + rv = DosCloseEventSem(thread->md.blocked_sema); + PR_ASSERT(rv == NO_ERROR); + thread->md.blocked_sema = 0; + } + + if (thread->md.handle) { + thread->md.handle = 0; + } } void _PR_MD_EXIT_THREAD(PRThread *thread) { - _PR_MD_DESTROY_SEM(&thread->md.blocked_sema); - - if (thread->md.handle) { - /* DosKillThread will not kill a suspended thread, but it will mark it - * for death; we must resume it after killing it to make sure it knows - * it is about to die (pretty wicked, huh?). - * - * DosKillThread will not kill the current thread, instead we must use - * DosExit. - */ - if ( thread != _MD_CURRENT_THREAD() ) { - DosKillThread( thread->md.handle ); - DosResumeThread( thread->md.handle ); - } else { -#ifndef XP_OS2_EMX - _endthread(); -#endif - } - thread->md.handle = 0; - } - + _PR_MD_CLEAN_THREAD(thread); _PR_MD_SET_CURRENT_THREAD(NULL); }