Fix for bug 121952 -- make PR_ConnectContinue work on Mac, re-enabling non-blocking connects. r=wtc. Also bring forward some code changes to build with CodeWarrior Pro 7 (UPP stuff).
authorsfraser%netscape.com
Tue, 19 Feb 2002 01:26:30 +0000
changeset 2266 0bedeecd4d56e610df99a18de02f75f06b4de061
parent 2264 953710c63a818abdfb4902819eaa06b56e0dbf0b
child 2268 e3c2dc8ad80b4cbd70d6e1a39cd1f28c344a19af
push idunknown
push userunknown
push dateunknown
reviewerswtc
bugs121952
Fix for bug 121952 -- make PR_ConnectContinue work on Mac, re-enabling non-blocking connects. r=wtc. Also bring forward some code changes to build with CodeWarrior Pro 7 (UPP stuff).
pr/include/md/_macos.h
pr/src/io/prsocket.c
pr/src/md/mac/macio.c
pr/src/md/mac/macsockotpt.c
pr/src/md/mac/macthr.c
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -110,25 +110,28 @@ struct _MDCPU {
 
 typedef struct _MDSocketCallerInfo {
 	PRThread *	thread;
 	void *		cookie;
 } _MDSocketCallerInfo;
 
 struct _MDFileDesc {
     PRInt32     osfd;
-	PRBool      orderlyDisconnect;
-	PRBool      readReady;
-	PRBool      writeReady;
-	PRBool      exceptReady;
+    PRPackedBool    orderlyDisconnect;
+    PRPackedBool    readReady;
+    PRPackedBool    writeReady;
+    PRPackedBool    exceptReady;
 	PRLock *    miscLock;
 	
 	/* Server sockets: listen bit tells the notifier func what to do */
 	PRBool		doListen;
 
+    /* stored error for non-blocking connects, as a Unix-style error code */
+    OTReason        disconnectError;
+
 	_MDSocketCallerInfo  misc;
 	_MDSocketCallerInfo  read;
 	_MDSocketCallerInfo  write;
 };
 
 /*
 ** Iinitialization Related definitions
 */
@@ -642,17 +645,17 @@ extern void * _MD_MemMap(struct PRFileMa
 
 extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
 #define _MD_MEM_UNMAP _MD_MemUnmap
 
 extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
 #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
 
 extern void SetLogFileTypeCreator(const char *logFile);
-extern int _MD_mac_get_nonblocking_connect_error(PRInt32 osfd);
+extern int _MD_mac_get_nonblocking_connect_error(PRFileDesc* fd);
 
 
 /*
  * Critical section support
  */
 
 #define MAC_CRITICAL_REGIONS  TARGET_CARBON
 
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -342,17 +342,17 @@ static PRStatus PR_CALLBACK SocketConnec
     if (err != 0) {
         _PR_MD_MAP_CONNECT_ERROR(err);
         return PR_FAILURE;
     }
     return PR_SUCCESS;
 
 #elif defined(XP_MAC)
 
-    err = _MD_mac_get_nonblocking_connect_error(osfd);
+    err = _MD_mac_get_nonblocking_connect_error(fd);
     if (err == -1)
         return PR_FAILURE;
 	else     
 		return PR_SUCCESS;
 
 #elif defined(XP_BEOS)
 
 #ifdef BONE_VERSION  /* bug 122364 */
--- a/pr/src/md/mac/macio.c
+++ b/pr/src/md/mac/macio.c
@@ -262,17 +262,17 @@ PRInt32 ReadWriteProc(PRFileDesc *fd, vo
 		static IOCompletionUPP	sCompletionUPP = NULL;
 		
 		PRBool  doingAsync = PR_FALSE;
 		
 		/* allocate the callback Universal Procedure Pointer (UPP). This actually allocates
 		   a 32 byte Ptr in the heap, so only do this once
 		*/
 		if (!sCompletionUPP)
-			sCompletionUPP = NewIOCompletionProc((IOCompletionProcPtr)&AsyncIOCompletion);
+			sCompletionUPP = NewIOCompletionUPP((IOCompletionProcPtr)&AsyncIOCompletion);
 			
 		/* grab the thread so we know which one to post to at completion */
 		pbAsync.thread	= me;
 
 		pbAsync.pb.ioParam.ioCompletion	= sCompletionUPP;
 		pbAsync.pb.ioParam.ioResult		= noErr;
 		pbAsync.pb.ioParam.ioRefNum		= refNum;
 		pbAsync.pb.ioParam.ioBuffer		= buf;
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -368,16 +368,18 @@ static pascal void  NotifierRoutine(void
             return;
 
         case T_DISCONNECT:  // A disconnect is available
             discon.udata.len = 0;
             err = OTRcvDisconnect(endpoint, &discon);
             PR_ASSERT(err == kOTNoError);
             secret->md.exceptReady = PR_TRUE;       // XXX Check this
 
+            md->disconnectError = discon.reason;    // save for _MD_mac_get_nonblocking_connect_error
+
             // wake up waiting threads, if any
             result = -3199 - discon.reason; // obtain the negative error code
             if ((readThread = secret->md.read.thread) != NULL) {
                 secret->md.read.thread    = NULL;
                 secret->md.read.cookie    = cookie;
             }
 
             if ((writeThread = secret->md.write.thread) != NULL) {
@@ -2192,30 +2194,37 @@ PR_IMPLEMENT(struct protoent *) getproto
         return (&sUDPProto);
         
 ErrorExit:
     macsock_map_error(kEINVALErr);
     return NULL;
 }
 
 
-int _MD_mac_get_nonblocking_connect_error(PRInt32 osfd)
+int _MD_mac_get_nonblocking_connect_error(PRFileDesc* fd)
 {
-    OTResult resultOT;
-    EndpointRef endpoint = (EndpointRef) osfd;
+    EndpointRef endpoint = (EndpointRef)fd->secret->md.osfd;
+    OTResult    resultOT = OTGetEndpointState(endpoint);
 
-    resultOT = OTGetEndpointState(endpoint);
     switch (resultOT)    {
         case T_OUTCON:
             macsock_map_error(EINPROGRESS);
             return -1;
+            
         case T_DATAXFER:
             return 0;
+            
         case T_IDLE:
+            macsock_map_error(fd->secret->md.disconnectError);
+            fd->secret->md.disconnectError = 0;
             return -1;
+
         case T_INREL:
             macsock_map_error(ENOTCONN);
             return -1;
+
         default:
             PR_ASSERT(0);
             return -1;
     }
+
+    return -1;      // not reached
 }
--- a/pr/src/md/mac/macthr.c
+++ b/pr/src/md/mac/macthr.c
@@ -194,17 +194,17 @@ pascal void TimerCallback(TMTaskPtr tmTa
 }
 
 
 void _MD_StartInterrupts(void)
 {
 	gPrimaryThread = _PR_MD_CURRENT_THREAD();
 
 	if ( !gTimerCallbackUPP )
-		gTimerCallbackUPP = NewTimerProc(TimerCallback);
+		gTimerCallbackUPP = NewTimerUPP(TimerCallback);
 
 	//	Fill in the Time Manager queue element
 	
 	gTimeManagerTaskElem.tmAddr = (TimerUPP)gTimerCallbackUPP;
 	gTimeManagerTaskElem.tmCount = 0;
 	gTimeManagerTaskElem.tmWakeUp = 0;
 	gTimeManagerTaskElem.tmReserved = 0;