diff options
author | gordon%netscape.com <devnull@localhost> | 1999-11-03 01:22:58 +0000 |
---|---|---|
committer | gordon%netscape.com <devnull@localhost> | 1999-11-03 01:22:58 +0000 |
commit | 448a0cc5dbd3caf987365328f4c7e9bc46e8daf3 (patch) | |
tree | 6dcab00f15065631312707649cd60fb19b12b7cc | |
parent | e7f3ab8311c96fb647b0efa0621f1157e656050d (diff) | |
download | nspr-hg-448a0cc5dbd3caf987365328f4c7e9bc46e8daf3.tar.gz |
Mac specific interrupt<->thread synchronization mechanism, required for async Mac dns.
r=warren, patrick, wtc, srinivas, larryh; part of bug:10731.
-rw-r--r-- | pr/include/md/_macos.h | 4 | ||||
-rw-r--r-- | pr/include/private/pprthred.h | 10 | ||||
-rw-r--r-- | pr/src/md/mac/macio.c | 22 | ||||
-rw-r--r-- | pr/src/md/mac/macsockotpt.c | 8 | ||||
-rw-r--r-- | pr/src/md/mac/macthr.c | 60 |
5 files changed, 92 insertions, 12 deletions
diff --git a/pr/include/md/_macos.h b/pr/include/md/_macos.h index 72f03a1c..4d083ec7 100644 --- a/pr/include/md/_macos.h +++ b/pr/include/md/_macos.h @@ -55,7 +55,9 @@ struct _MDThread { int osErrCode; PRLock * asyncIOLock; PRCondVar * asyncIOCVar; - PRBool notifyPending; + PRBool missedIONotify; + PRBool missedAsyncNotify; + PRBool asyncNotifyPending; }; struct _MDThreadStack { diff --git a/pr/include/private/pprthred.h b/pr/include/private/pprthred.h index ec0b6a30..2fbc1377 100644 --- a/pr/include/private/pprthred.h +++ b/pr/include/private/pprthred.h @@ -301,11 +301,19 @@ PR_EXTERN(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon); */ PR_EXTERN(PRMonitor*) PR_CTestAndEnterMonitor(void *address); +/*--------------------------------------------------------------------------- +** PLATFORM-SPECIFIC THREAD SYNCHRONIZATION FUNCTIONS +---------------------------------------------------------------------------*/ +#if defined(XP_MAC) + +PR_EXTERN(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout); +PR_EXTERN(void) PR_Mac_PostAsyncNotify(PRThread *thread); + +#endif /* XP_MAC */ /*--------------------------------------------------------------------------- ** PLATFORM-SPECIFIC INITIALIZATION FUNCTIONS ---------------------------------------------------------------------------*/ - #if defined(IRIX) /* ** Irix specific initialization funtion to be called before PR_Init diff --git a/pr/src/md/mac/macio.c b/pr/src/md/mac/macio.c index c12f39b2..94ff4e81 100644 --- a/pr/src/md/mac/macio.c +++ b/pr/src/md/mac/macio.c @@ -42,6 +42,8 @@ extern unsigned long gJanuaryFirst1970Seconds; extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout); extern void DoneWaitingOnThisThread(PRThread *thread); +extern void AsyncNotify(PRThread *thread); + /* PB for Read and Write */ struct ExtendedParamBlock { @@ -61,7 +63,7 @@ static void AsyncIOCompletion (ExtendedParamBlock *pbAsyncPtr) if (_PR_MD_GET_INTSOFF()) { cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - thread->md.notifyPending = PR_TRUE; + thread->md.missedIONotify = PR_TRUE; return; } _PR_MD_SET_INTSOFF(1); @@ -173,10 +175,15 @@ void _MD_IOInterrupt(void) qp = qp->next; - if (thread->md.notifyPending) { - thread->md.notifyPending = PR_FALSE; + if (thread->md.missedIONotify) { + thread->md.missedIONotify = PR_FALSE; DoneWaitingOnThisThread(thread); } + + if (thread->md.missedAsyncNotify) { + thread->md.missedAsyncNotify = PR_FALSE; + AsyncNotify(thread); + } } qp = _PR_SLEEPQ(me->cpu).next; while (qp != &_PR_SLEEPQ(me->cpu)) { @@ -186,10 +193,15 @@ void _MD_IOInterrupt(void) qp = qp->next; - if (thread->md.notifyPending) { - thread->md.notifyPending = PR_FALSE; + if (thread->md.missedIONotify) { + thread->md.missedIONotify = PR_FALSE; DoneWaitingOnThisThread(thread); } + + if (thread->md.missedAsyncNotify) { + thread->md.missedAsyncNotify = PR_FALSE; + AsyncNotify(thread); + } } _PR_SLEEPQ_UNLOCK(thread->cpu); } diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c index ab6409bc..776559d1 100644 --- a/pr/src/md/mac/macsockotpt.c +++ b/pr/src/md/mac/macsockotpt.c @@ -56,7 +56,7 @@ static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PR extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout); extern void DoneWaitingOnThisThread(PRThread *thread); -#ifdef TARGET_CARBON +#if TARGET_CARBON OTClientContextPtr clientContext = NULL; OTNotifyUPP DNSNotifierRoutineUPP; @@ -97,7 +97,7 @@ void _MD_InitNetAccess() PR_ASSERT(hasOTTCPIP == PR_TRUE); -#ifdef TARGET_CARBON +#if TARGET_CARBON DNSNotifierRoutineUPP = NewOTNotifyUPP(DNSNotifierRoutine); notifierRoutineUPP = NewOTNotifyUPP(NotifierRoutine); @@ -150,7 +150,7 @@ pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult re dnsContext.cookie = cookie; if (_PR_MD_GET_INTSOFF()) { cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - dnsContext.thread->md.notifyPending = PR_TRUE; + dnsContext.thread->md.missedIONotify = PR_TRUE; return; } DoneWaitingOnThisThread(dnsContext.thread); @@ -383,7 +383,7 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul thread->md.osErrCode = result; if (_PR_MD_GET_INTSOFF()) { cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - thread->md.notifyPending = PR_TRUE; + thread->md.missedIONotify = PR_TRUE; return; } DoneWaitingOnThisThread(thread); diff --git a/pr/src/md/mac/macthr.c b/pr/src/md/mac/macthr.c index 2256ef12..40d9be77 100644 --- a/pr/src/md/mac/macthr.c +++ b/pr/src/md/mac/macthr.c @@ -249,6 +249,7 @@ PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout) return PR_SUCCESS; } + void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout) { intn is; @@ -261,7 +262,7 @@ void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout) while ((thread->io_pending) && (status == PR_SUCCESS)) status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT); } else { - while ((thread->io_pending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout)) + while ((thread->io_pending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS)) status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout); } if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) { @@ -274,6 +275,7 @@ void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout) _PR_FAST_INTSON(is); } + void DoneWaitingOnThisThread(PRThread *thread) { intn is; @@ -287,6 +289,62 @@ void DoneWaitingOnThisThread(PRThread *thread) _PR_FAST_INTSON(is); } + +PR_IMPLEMENT(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout) +{ + intn is; + PRIntervalTime timein = PR_IntervalNow(); + PRStatus status = PR_SUCCESS; + PRThread *thread = _PR_MD_CURRENT_THREAD(); + + _PR_INTSOFF(is); + PR_Lock(thread->md.asyncIOLock); + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + while ((!thread->md.asyncNotifyPending) && (status == PR_SUCCESS)) + status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT); + } else { + while ((!thread->md.asyncNotifyPending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS)) + status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout); + } + if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) { + thread->md.osErrCode = kEINTRErr; + } else if (!thread->md.asyncNotifyPending) { + thread->md.osErrCode = kETIMEDOUTErr; + PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr); + } + thread->md.asyncNotifyPending = PR_FALSE; + PR_Unlock(thread->md.asyncIOLock); + _PR_FAST_INTSON(is); +} + + +void AsyncNotify(PRThread *thread) +{ + intn is; + + _PR_INTSOFF(is); + PR_Lock(thread->md.asyncIOLock); + thread->md.asyncNotifyPending = PR_TRUE; + /* let the waiting thread know that async IO completed */ + PR_NotifyCondVar(thread->md.asyncIOCVar); // let thread know that async IO completed + PR_Unlock(thread->md.asyncIOLock); + _PR_FAST_INTSON(is); +} + + +PR_IMPLEMENT(void) PR_Mac_PostAsyncNotify(PRThread *thread) +{ + _PRCPU * cpu = _PR_MD_CURRENT_CPU(); + + if (_PR_MD_GET_INTSOFF()) { + cpu->u.missed[cpu->where] |= _PR_MISSED_IO; + thread->md.missedAsyncNotify = PR_TRUE; + } else { + AsyncNotify(thread); + } +} + + //############################################################################## //############################################################################## #pragma mark - |