summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2000-02-17 21:28:49 +0000
committerwtc%netscape.com <devnull@localhost>2000-02-17 21:28:49 +0000
commita43baa7eae343c289e9265af4a32ba69f03fb803 (patch)
tree24a0b6baee2a8758c2cba004890ec7b5e067fb26
parenteb4ac968471f159adf71702e0dde6d744f7cd67f (diff)
downloadnspr-hg-a43baa7eae343c289e9265af4a32ba69f03fb803.tar.gz
Wake up waiting threads when we receive the T_DISCONNECT or T_ORDREL
events. This fix is contributed by Mark Welch <mwelch@netscape.com>. (NSPRPUB_RELEASE_4_0_BRANCH)
-rw-r--r--pr/src/md/mac/macsockotpt.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 004bd103..3fa57b18 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -243,6 +243,22 @@ static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
}
+static void
+WakeUpNotifiedThread(PRThread *thread, OTResult result)
+{
+ _PRCPU * cpu = _PR_MD_CURRENT_CPU();
+
+ if (thread) {
+ thread->md.osErrCode = result;
+ if (_PR_MD_GET_INTSOFF()) {
+ cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+ thread->md.missedIONotify = PR_TRUE;
+ return;
+ }
+ DoneWaitingOnThisThread(thread);
+ }
+}
+
// Notification routine
// Async callback routine.
// A5 is OK. Cannot allocate memory here
@@ -252,9 +268,9 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
_MDFileDesc * md = &(secret->md);
EndpointRef endpoint = (EndpointRef)secret->md.osfd;
PRThread * thread = NULL;
- _PRCPU * cpu = _PR_MD_CURRENT_CPU();
OSStatus err;
OTResult resultOT;
+ TDiscon discon;
switch (code)
{
@@ -303,10 +319,27 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
return;
case T_DISCONNECT: // A disconnect is available
- err = OTRcvDisconnect(endpoint, NULL);
+ err = OTRcvDisconnect(endpoint, &discon);
PR_ASSERT(err == kOTNoError);
secret->md.exceptReady = PR_TRUE;
secret->md.connectionOpen = PR_FALSE;
+
+ // wake up waiting threads, if any
+ result = kECONNRESETErr;//(OTResult) discon.reason;
+
+ if ((thread = secret->md.read.thread) != NULL) {
+ secret->md.read.thread = NULL;
+ secret->md.read.cookie = cookie;
+ WakeUpNotifiedThread(thread, result);
+ }
+
+ if ((thread = secret->md.write.thread) != NULL) {
+ secret->md.write.thread = NULL;
+ secret->md.write.cookie = cookie;
+ WakeUpNotifiedThread(thread, result);
+ }
+
+ thread = NULL; // already took care of notification here
break;
case T_ERROR: // obsolete/unused in library
@@ -323,6 +356,11 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
secret->md.readReady = PR_TRUE; // mark readable (to emulate bsd sockets)
// remember connection is closed, so we can return 0 on read or receive
secret->md.connectionOpen = PR_FALSE;
+
+ thread = secret->md.read.thread;
+ secret->md.read.thread = NULL;
+ secret->md.read.cookie = cookie;
+
break;
case T_GODATA: // Flow control lifted on standard data
@@ -391,16 +429,7 @@ pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult resul
return;
}
- if (thread) {
- thread->md.osErrCode = result;
- if (_PR_MD_GET_INTSOFF()) {
- cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
- thread->md.missedIONotify = PR_TRUE;
- return;
- }
-
- DoneWaitingOnThisThread(thread);
- }
+ WakeUpNotifiedThread(thread, result);
}
@@ -988,7 +1017,7 @@ PRInt32 _MD_socketavailable(PRFileDesc *fd)
err = OTCountDataBytes(endpoint, &bytes);
if ((err == kOTLookErr) || // Not really errors, we just need to do a read,
- (err == kOTNoDataErr)) // or there’s nothing there.
+ (err == kOTNoDataErr)) // or there's nothing there.
err = kOTNoError;
if (err != kOTNoError)