Fix bug 29338 "PR_Poll should not poll (spin) on Mac". Checking in for sfraser. r=dougt, sdagley, gordon, sr=sfraser, or vice versa.
authorgordon%netscape.com
Tue, 13 Mar 2001 07:02:53 +0000
changeset 1780 92eb0bdaf941c179fd618dd2d860eb94a14a7961
parent 1778 706b23613972a32ad7eabc60e4f385b804e81f48
child 1783 dcad374d78853707911a181839ac61b62436e3e0
push idunknown
push userunknown
push dateunknown
reviewersdougt, sdagley, gordon, sfraser, or
bugs29338
Fix bug 29338 "PR_Poll should not poll (spin) on Mac". Checking in for sfraser. r=dougt, sdagley, gordon, sr=sfraser, or vice versa.
pr/include/md/_macos.h
pr/src/md/mac/macsockotpt.c
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -119,16 +119,17 @@ struct _MDFileDesc {
 	PRLock *    miscLock;
 	
 	/* Server sockets: listen bit tells the notifier func what to do */
 	PRBool		doListen;
 	
 	_MDSocketCallerInfo  misc;
 	_MDSocketCallerInfo  read;
 	_MDSocketCallerInfo  write;
+	_MDSocketCallerInfo  poll;
 };
 
 /*
 ** Iinitialization Related definitions
 */
 
 #define _MD_EARLY_INIT		_MD_EarlyInit
 #define _MD_FINAL_INIT		_MD_FinalInit
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -303,16 +303,17 @@ WakeUpNotifiedThread(PRThread *thread, O
 // Async callback routine.
 // A5 is OK. Cannot allocate memory here
 static pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
 {
 	PRFilePrivate *secret  = (PRFilePrivate *) contextPtr;
 	_MDFileDesc * md       = &(secret->md);
 	EndpointRef   endpoint = (EndpointRef)secret->md.osfd;
     PRThread *    thread   = NULL;
+    PRThread *	  pollThread = md->poll.thread;
 	OSStatus      err;
 	OTResult	  resultOT;
     TDiscon		  discon;
 
     switch (code)
     {
 // OTLook Events - 
         case T_LISTEN:        // A connection request is available
@@ -463,17 +464,21 @@ static pascal void  NotifierRoutine(void
 //      case T_DNRMAILEXCHANGECOMPLETE:
 //      case T_DNRQUERYCOMPLETE:
         default:
         	// we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.
 			// PR_ASSERT(code != 0);
             return;
     }
 
+	if (pollThread)
+		WakeUpNotifiedThread(pollThread, kOTNoError);
+	else
 	WakeUpNotifiedThread(thread, result);
+	
 }
 
 
 static OSErr CreateSocket(int type, EndpointRef *endpoint)
 {
     OSStatus err;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     char *  configName;
@@ -1670,18 +1675,20 @@ PRInt32 _MD_writev(PRFileDesc *fd, const
     _PR_MD_CURRENT_THREAD()->md.osErrCode = unimpErr;
     return -1;
 }                               
 
 
 static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady)
 {
     OTResult resultOT;
+	size_t   availableData;
     
-	*readReady = fd->secret->md.readReady;
+	resultOT = OTCountDataBytes((EndpointRef)fd->secret->md.osfd, &availableData);   
+	*readReady = fd->secret->md.readReady && (availableData > 0);
 	*exceptReady = fd->secret->md.exceptReady;
 
     resultOT = OTGetEndpointState((EndpointRef)fd->secret->md.osfd);
     switch (resultOT)    {
         case T_DATAXFER:
         case T_INREL:
             *writeReady = PR_TRUE;
             break;
@@ -1692,24 +1699,21 @@ static PRBool GetState(PRFileDesc *fd, P
     return  *readReady || *writeReady || *exceptReady;
 }
 
 
 PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
 {
     PRInt32 ready = 0;
     PRPollDesc *pd, *epd;
-    PRIntervalTime sleepTime, timein;
+    PRThread	*thread = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime timein;
     
-    sleepTime = PR_MillisecondsToInterval(5UL);
     if (PR_INTERVAL_NO_TIMEOUT != timeout)
-    {
-        if (sleepTime > timeout) sleepTime = timeout;
         timein = PR_IntervalNow();
-    }
 
     do
     {
         for (pd = pds, epd = pd + npds; pd < epd; pd++)
         {
             PRInt16  in_flags_read = 0,  in_flags_write = 0;
             PRInt16 out_flags_read = 0, out_flags_write = 0;
 
@@ -1736,16 +1740,18 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn
                 PRFileDesc *bottomFD;
                 PRBool readReady, writeReady, exceptReady;
 
                 pd->out_flags = 0;  /* pre-condition */
                 bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
                 PR_ASSERT(NULL != bottomFD);
                 if ((NULL != bottomFD) && (_PR_FILEDESC_OPEN == bottomFD->secret->state))
                 {
+                    bottomFD->secret->md.poll.thread = thread;
+                	
                     if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))
                     {
                         if (readReady)
                         {
                             if (in_flags_read & PR_POLL_READ)
                                 pd->out_flags |= PR_POLL_READ;
                             if (in_flags_write & PR_POLL_READ)
                                 pd->out_flags |= PR_POLL_WRITE;
@@ -1769,17 +1775,20 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn
                     ready += 1;  /* this will cause an abrupt return */
                     pd->out_flags = PR_POLL_NVAL;  /* bogii */
                 }
             }
         }
 
         if (ready > 0) return ready;
 
-        (void) PR_Sleep(sleepTime);
+        thread->io_pending       = PR_TRUE;
+        thread->io_fd            = NULL;
+        thread->md.osErrCode     = noErr;
+        WaitOnThisThread(thread, timeout);
 
     } while ((timeout == PR_INTERVAL_NO_TIMEOUT) ||
            (((PRIntervalTime)(PR_IntervalNow() - timein)) < timeout));
 
     return 0; /* timed out */
 }