Fix for bug 121952 -- make PR_ConnectContinue work on Mac, re-enabling non-blocking connects. r=wtc NSPRPUB_PRE_4_2_CLIENT_BRANCH
authorsfraser%netscape.com
Tue, 19 Feb 2002 01:09:46 +0000
branchNSPRPUB_PRE_4_2_CLIENT_BRANCH
changeset 2265 fd30aa6fb4e5bbd49940ffcddfadc34612ca632e
parent 2262 8801e4aa905a560a85eb81301d62f768f3ccb20c
child 2267 c5449be44a8811d119f2e46d1c52552bb8ab507f
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
pr/include/md/_macos.h
pr/src/io/prsocket.c
pr/src/md/mac/macsockotpt.c
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -109,29 +109,32 @@ struct _MDCPU {
 };
 
 typedef struct _MDSocketCallerInfo {
 	PRThread *	thread;
 	void *		cookie;
 } _MDSocketCallerInfo;
 
 struct _MDFileDesc {
-    PRInt32     osfd;
-	PRBool      orderlyDisconnect;
-	PRBool      readReady;
-	PRBool      writeReady;
-	PRBool      exceptReady;
-	PRLock *    miscLock;
-	
-	/* Server sockets: listen bit tells the notifier func what to do */
-	PRBool		doListen;
+    PRInt32         osfd;
+    PRPackedBool    orderlyDisconnect;
+    PRPackedBool    readReady;
+    PRPackedBool    writeReady;
+    PRPackedBool    exceptReady;
+    PRLock *        miscLock;
 
-	_MDSocketCallerInfo  misc;
-	_MDSocketCallerInfo  read;
-	_MDSocketCallerInfo  write;
+    /* 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
 */
 
 #define _MD_EARLY_INIT		_MD_EarlyInit
 #define _MD_FINAL_INIT		_MD_FinalInit
@@ -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,31 +342,21 @@ static PRStatus PR_CALLBACK SocketConnec
     if (err != 0) {
         _PR_MD_MAP_CONNECT_ERROR(err);
         return PR_FAILURE;
     }
     return PR_SUCCESS;
 
 #elif defined(XP_MAC)
 
-#if 0
-    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;
-#else
-    if (out_flags & PR_POLL_EXCEPT) {
-        PR_SetError(PR_CONNECT_REFUSED_ERROR, 0);
-        return PR_FAILURE;
-    }
-
-    PR_ASSERT(out_flags & PR_POLL_WRITE);
-    return PR_SUCCESS;
-#endif
 
 #elif defined(XP_BEOS)
 
 #ifdef BONE_VERSION  /* bug 122364 */
     /* temporary workaround until getsockopt(SO_ERROR) works in BONE */
     if (out_flags & PR_POLL_EXCEPT) {
         PR_SetError(PR_CONNECT_REFUSED_ERROR, 0);
         return PR_FAILURE;
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -370,16 +370,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) {
@@ -2195,30 +2197,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
 }