summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgordon%netscape.com <devnull@localhost>1999-11-03 01:22:58 +0000
committergordon%netscape.com <devnull@localhost>1999-11-03 01:22:58 +0000
commit448a0cc5dbd3caf987365328f4c7e9bc46e8daf3 (patch)
tree6dcab00f15065631312707649cd60fb19b12b7cc
parente7f3ab8311c96fb647b0efa0621f1157e656050d (diff)
downloadnspr-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.h4
-rw-r--r--pr/include/private/pprthred.h10
-rw-r--r--pr/src/md/mac/macio.c22
-rw-r--r--pr/src/md/mac/macsockotpt.c8
-rw-r--r--pr/src/md/mac/macthr.c60
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 -