diff options
author | sfraser%netscape.com <devnull@localhost> | 2001-06-14 01:33:06 +0000 |
---|---|---|
committer | sfraser%netscape.com <devnull@localhost> | 2001-06-14 01:33:06 +0000 |
commit | 723ab59a48c9050943c6b7825f81c0a1c383b197 (patch) | |
tree | 2fcb5ee8ae60df9a2c3f27869d74183602458ac6 | |
parent | de0c3886ad99646ac6a9b5eaac2fbc5a467b889c (diff) | |
download | nspr-hg-723ab59a48c9050943c6b7825f81c0a1c383b197.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 | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c index 159a0db2..f8c454a9 100644 --- a/pr/src/md/mac/macsockotpt.c +++ b/pr/src/md/mac/macsockotpt.c @@ -1391,7 +1391,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); @@ -1410,15 +1412,20 @@ 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 - PrepareForAsyncCompletion(me, fd->secret->md.osfd); + disabledNotifications = OTEnterNotifier(endpoint); + PrepareForAsyncCompletion(me, fd->secret->md.osfd); } } while(1); @@ -1439,19 +1446,23 @@ 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 - PrepareForAsyncCompletion(me, fd->secret->md.osfd); + disabledNotifications = OTEnterNotifier(endpoint); + PrepareForAsyncCompletion(me, fd->secret->md.osfd); } } // Retry read if we had to wait for data to show up. @@ -1459,11 +1470,16 @@ 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 ); bytesLeft -= result; |