diff options
author | sfraser%netscape.com <devnull@localhost> | 2001-06-14 01:35:05 +0000 |
---|---|---|
committer | sfraser%netscape.com <devnull@localhost> | 2001-06-14 01:35:05 +0000 |
commit | 5429f36e7da3facc36cee7e250103e85bda4ce30 (patch) | |
tree | b7914258ef7bba25339feaeb565054a483a53879 | |
parent | 87adadd8f7ce537e9bab9ef63aa8af0708674cef (diff) | |
download | nspr-hg-5429f36e7da3facc36cee7e250103e85bda4ce30.tar.gz |
Fix for bug 85514 -- use OTEnter/LeaveNotifer calls to fix synchronization problem caused by the OT notifier firing while we are inside OTSnd or OTRcv. r=gordon, wtc. a=blizzard
-rw-r--r-- | pr/src/md/mac/macsockotpt.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c index 68c07367..00cc9022 100644 --- a/pr/src/md/mac/macsockotpt.c +++ b/pr/src/md/mac/macsockotpt.c @@ -1408,7 +1408,9 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, goto ErrorExit; } - while (bytesLeft > 0) { + while (bytesLeft > 0) + { + Boolean disabledNotifications = OTEnterNotifier(endpoint); PrepareForAsyncCompletion(me, fd->secret->md.osfd); @@ -1427,14 +1429,19 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, if (result != kOTFlowErr) break; - // Blocking write, but the pipe is full. Wait for an event, - // hoping that it's a T_GODATA event. + // Blocking write, but the pipe is full. Turn notifications on and + // wait for an event, hoping that it's a T_GODATA event. + if (disabledNotifications) { + OTLeaveNotifier(endpoint); + disabledNotifications = false; + } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); result = me->md.osErrCode; if (result != kOTNoError) // got interrupted, or some other error break; // Prepare to loop back and try again + disabledNotifications = OTEnterNotifier(endpoint); PrepareForAsyncCompletion(me, fd->secret->md.osfd); } } @@ -1456,18 +1463,22 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, OSErr tmpResult; tmpResult = OTCountDataBytes(endpoint, &count); fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0)); - break; } - // Blocking read, but no data available. Wait for an event - // on this endpoint, and hope that we get a T_DATA event. + // Blocking read, but no data available. Turn notifications on and + // wait for an event on this endpoint, and hope that we get a T_DATA event. + if (disabledNotifications) { + OTLeaveNotifier(endpoint); + disabledNotifications = false; + } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); result = me->md.osErrCode; if (result != kOTNoError) // interrupted thread, etc. break; // Prepare to loop back and try again + disabledNotifications = OTEnterNotifier(endpoint); PrepareForAsyncCompletion(me, fd->secret->md.osfd); } } @@ -1476,10 +1487,15 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, } me->io_pending = PR_FALSE; + if (opCode == kSTREAM_SEND) - fd->secret->md.write.thread = nil; + fd->secret->md.write.thread = NULL; else - fd->secret->md.read.thread = nil; + fd->secret->md.read.thread = NULL; + + // turn notifications back on + if (disabledNotifications) + OTLeaveNotifier(endpoint); if (result > 0) { buf = (void *) ( (UInt32) buf + (UInt32)result ); |