Bugzilla bug #24542: removed the private exported funciton NSPRPUB_RELEASE_4_0_BRANCH
authorwtc%netscape.com
Thu, 27 Jan 2000 22:40:43 +0000
branchNSPRPUB_RELEASE_4_0_BRANCH
changeset 1108 5cdab0dd2bde6a122bf4a4920dd5a5f5c0953dfe
parent 1107 0f4be47ea2396b84d4a47cb8676bac598142f767
child 1112 360934cd5d06ffb238922a141f8ed95091eaa125
push idunknown
push userunknown
push dateunknown
bugs24542
Bugzilla bug #24542: removed the private exported funciton PR_NT_UseNonblock. Modified files: pprio.h, ntio.c (NSPRPUB_RELEASE_4_0_BRANCH)
pr/include/private/pprio.h
pr/src/md/windows/ntio.c
--- a/pr/include/private/pprio.h
+++ b/pr/include/private/pprio.h
@@ -203,28 +203,16 @@ NSPR_API(PRFileDesc*)	PR_NTFast_Accept(P
 **    so that the socket can make general purpose socket calls.
 **    Without calling this, the only operations supported on the socket
 **    Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close.
 */
 NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, 
                                         PRFileDesc *listenSock);
 
 
-/* FUNCTION: PR_NT_UseNonblock
-** DESCRIPTION:
-**    This function only works on NT.  It tells nspr to use nonblocking io
-**    rather than async IO.  There is no way to use some of each.  This 
-**    function should be called immediately after calling PR_Init().
-**
-**    WARNING: THIS FUNCTION IS A TEMPORARY HACK AND WILL BE REMOVED SHORTLY
-**    (LIKE ALL FUNCTIONS IN THE PRIVATE AREA).  DO NOT USE THIS FUNCTION AT
-**    ALL WITHOUT CONTACTING mbelshe@netscape.com.
-*/
-NSPR_API(void) PR_NT_UseNonblock();
-
 /* FUNCTION: PR_NT_CancelIo
 ** DESCRIPTION:
 **    Cancel IO operations on fd.
 */
 NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
 
 
 #endif /* WIN32 */
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -90,20 +90,16 @@ static const PRTime _pr_filetime_offset 
 #define _PR_LOCAL_FILE 1
 #define _PR_REMOTE_FILE 2
 PRBool IsFileLocalInit();
 PRInt32 IsFileLocal(HANDLE hFile);
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
 static PRInt32 _md_MakeNonblock(HANDLE);
 
-/* The _nt_use_async flag is used to prevent nspr from using any async io.
- * this is a temporary hack.  Don't learn to rely on it.
- */
-static int _nt_use_async = 1;
 PRInt32 _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr_in *addr, int *len, PRIntervalTime);
 PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
 PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
 PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime);
 
 /*
@@ -1138,17 +1134,17 @@ PRInt32
                PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 rv;
     PRThread *cThread;
     struct connect_data_s cd;
 
-    if (!_nt_use_async || fd->secret->nonblocking) {
+    if (fd->secret->nonblocking) {
         PRInt32 rv;
         fd_set wd;
         struct timeval tv, *tvp;
 
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
@@ -1305,29 +1301,29 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     SOCKET accept_sock;
     int bytes;
     PRNetAddr *Laddr;
     PRNetAddr *Raddr;
     PRUint32 llen, err;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         /*
          * The accepted socket inherits the nonblocking and
          * inheritable (HANDLE_FLAG_INHERIT) attributes of
          * the listening socket.
          */
         accept_sock = _nt_nonblock_accept(fd, (struct sockaddr_in *)raddr, rlen, timeout);
-        if (_nt_use_async && !fd->secret->nonblocking) {
+        if (!fd->secret->nonblocking) {
             u_long zero = 0;
 
             rv = ioctlsocket(accept_sock, FIONBIO, &zero);
             PR_ASSERT(0 == rv);
         }
         return accept_sock;
     }
 
@@ -1452,31 +1448,16 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     PRNetAddr *Laddr;
     PRUint32 llen, rlen, err;
     int rv;
     PRBool isConnected;
     PRBool madeCallback = PR_FALSE;
 
-    if (!_nt_use_async) {
-        PRFileDesc *nd;
-        bytes = _PR_EmulateAcceptRead(sd, &nd, raddr, buf, amount, timeout);
-        if (bytes != -1) {
-            /*
-             * This part is the same as SocketClose(nd), except
-             * that we don't close the osfd.
-             */
-            PR_ASSERT(nd->secret->state == _PR_FILEDESC_OPEN);
-            *newSock = nd->secret->md.osfd;
-            PR_FreeFileDesc(nd);
-        }
-        return bytes;
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sd->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock);
         PR_ASSERT(0 != rv);
@@ -1631,25 +1612,16 @@ retry:
 PRInt32
 _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
 					PRInt32 flags, PRIntervalTime timeout)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 tflags;
     int rv, err;
 
-    if (!_nt_use_async) {
-        if (!sock->secret->md.io_model_committed) {
-            rv = _md_MakeNonblock((HANDLE)sock->secret->md.osfd);
-            PR_ASSERT(0 != rv);
-            sock->secret->md.io_model_committed = PR_TRUE;
-        }
-        return _PR_EmulateSendFile(sock, sfd, flags, timeout);
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sock->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock->secret->md.osfd);
         PR_ASSERT(0 != rv);
@@ -1746,17 +1718,17 @@ PRInt32
 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_recv(fd, buf, amount, timeout);
     }
 
@@ -1845,17 +1817,17 @@ PRInt32
 _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_send(fd, (char *)buf, amount, timeout);
     }
 
@@ -1943,17 +1915,17 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 PRInt32
 _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
                 PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
@@ -1961,32 +1933,32 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 /* XXXMB - for now this is a sockets call only */
 PRInt32
 _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     int index;
     int sent = 0;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_writev(fd, iov, iov_size, timeout);
     }
 
@@ -2126,201 +2098,124 @@ PRInt32
 {
     HANDLE file;
     PRInt32 access = 0;
     PRInt32 flags = 0;
     PRInt32 flag6 = 0;
     
     if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
  
-    if (_nt_use_async)
-    {
-        if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE)
-            flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
-        else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
-        else flags = OPEN_EXISTING;
-
-        
-        flag6 |= FILE_FLAG_OVERLAPPED;
-
-        file = CreateFile(name, 
-                          access, 
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags, 
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      NULL,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
             return -1;
         }
-
-        if (osflags & PR_APPEND) {
-            if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
-                _PR_MD_MAP_LSEEK_ERROR(GetLastError());
-                CloseHandle(file);
-                return -1;
-            }
-        }
-
-        return (PRInt32)file;
     }
-    else
-    {
-   
-        if (osflags & PR_RDONLY || osflags & PR_RDWR)
-            access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR)
-            access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE) {
-            if (osflags & PR_TRUNCATE)
-                flags = CREATE_ALWAYS;
-            else
-                flags = OPEN_ALWAYS;
-        } else {
-            if (osflags & PR_TRUNCATE)
-                flags = TRUNCATE_EXISTING;
-            else
-                flags = OPEN_EXISTING;
-        }
-
-        file = CreateFile(name,
-                          access,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags,
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
-            return -1; 
-        }
-
-        return (PRInt32)file;
-    }
+
+    return (PRInt32)file;
 }
 
 PRInt32
 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode)
 {
     HANDLE file;
     PRInt32 access = 0;
     PRInt32 flags = 0;
     PRInt32 flag6 = 0;
     SECURITY_ATTRIBUTES sa;
     LPSECURITY_ATTRIBUTES lpSA = NULL;
     PSECURITY_DESCRIPTOR pSD = NULL;
     PACL pACL = NULL;
 
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
     if (osflags & PR_CREATE_FILE) {
         if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
                 &pSD, &pACL) == PR_SUCCESS) {
             sa.nLength = sizeof(sa);
             sa.lpSecurityDescriptor = pSD;
             sa.bInheritHandle = FALSE;
             lpSA = &sa;
         }
     }
-    
-    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
- 
-    if (_nt_use_async)
-    {
-        if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE)
-            flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
-        else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
-        else flags = OPEN_EXISTING;
-
-        
-        flag6 |= FILE_FLAG_OVERLAPPED;
-
-        file = CreateFile(name, 
-                          access, 
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          lpSA,
-                          flags, 
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
-            return -1;
-        }
-
-        if (osflags & PR_APPEND) {
-            if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
-                _PR_MD_MAP_LSEEK_ERROR(GetLastError());
-                CloseHandle(file);
-                return -1;
-            }
-        }
-    }
-    else
-    {
-   
-        if (osflags & PR_RDONLY || osflags & PR_RDWR)
-            access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR)
-            access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE) {
-            if (osflags & PR_TRUNCATE)
-                flags = CREATE_ALWAYS;
-            else
-                flags = OPEN_ALWAYS;
-        } else {
-            if (osflags & PR_TRUNCATE)
-                flags = TRUNCATE_EXISTING;
-            else
-                flags = OPEN_EXISTING;
-        }
-
-        file = CreateFile(name,
-                          access,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          &sa,
-                          flags,
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
-            return -1; 
-        }
-    }
-
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags, 
+                      flag6,
+                      NULL);
     if (lpSA != NULL) {
         _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
     }
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
+            return -1;
+        }
+    }
+
     return (PRInt32)file;
 }
 
 PRInt32 
 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRUint32 bytes;
     int rv, err;
     LONG hiOffset = 0;
     LONG loOffset;
 
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
@@ -2461,17 +2356,17 @@ PRInt32
 _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRInt32 bytes;
     int rv, err;
     LONG hiOffset = 0;
     LONG loOffset;
 
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
@@ -2708,72 +2603,60 @@ PRInt32
     }
     return 0;
 }
 
 PRInt32
 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket)
 {
     PRInt32 rv;
-    if (_nt_use_async) {
-        PRThread *me = _PR_MD_CURRENT_THREAD();
-
-        if (socket)  {
-            rv = closesocket((SOCKET)osfd);
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
-
-        if (rv == 0 && me->io_suspended) {
-            if (me->io_fd == osfd) {
-                PRBool fWait;
-
-                _PR_THREAD_LOCK(me);
-                me->state = _PR_IO_WAIT;
-                /* The IO could have completed on another thread just after
-                 * calling closesocket while the io_suspended flag was true.  
-                 * So we now grab the lock to do a safe check on io_pending to
-                 * see if we need to wait or not.
-                 */
-                fWait = me->io_pending;
-                me->io_suspended = PR_FALSE;
-                me->md.interrupt_disabled = PR_TRUE;
-                _PR_THREAD_UNLOCK(me);
-
-                if (fWait)
-                    _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
-                PR_ASSERT(me->io_suspended ==  PR_FALSE);
-                PR_ASSERT(me->io_pending ==  PR_FALSE);
-				/*
-				 * I/O operation is no longer pending; the thread can now
-				 * run on any cpu
-				 */
-                _PR_THREAD_LOCK(me);
-                me->md.interrupt_disabled = PR_FALSE;
-				me->md.thr_bound_cpu = NULL;
-                me->io_suspended = PR_FALSE;
-                me->io_pending = PR_FALSE;
-                me->state = _PR_RUNNING;
-                _PR_THREAD_UNLOCK(me);
-            }
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (socket)  {
+        rv = closesocket((SOCKET)osfd);
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+    } else {
+        rv = CloseHandle((HANDLE)osfd)?0:-1;
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    }
+
+    if (rv == 0 && me->io_suspended) {
+        if (me->io_fd == osfd) {
+            PRBool fWait;
+
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_IO_WAIT;
+            /* The IO could have completed on another thread just after
+             * calling closesocket while the io_suspended flag was true.  
+             * So we now grab the lock to do a safe check on io_pending to
+             * see if we need to wait or not.
+             */
+            fWait = me->io_pending;
+            me->io_suspended = PR_FALSE;
+            me->md.interrupt_disabled = PR_TRUE;
+            _PR_THREAD_UNLOCK(me);
+
+            if (fWait)
+                _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+            PR_ASSERT(me->io_suspended ==  PR_FALSE);
+            PR_ASSERT(me->io_pending ==  PR_FALSE);
+            /*
+             * I/O operation is no longer pending; the thread can now
+             * run on any cpu
+             */
+            _PR_THREAD_LOCK(me);
+            me->md.interrupt_disabled = PR_FALSE;
+            me->md.thr_bound_cpu = NULL;
+            me->io_suspended = PR_FALSE;
+            me->io_pending = PR_FALSE;
+            me->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(me);
         }
-    } else { 
-        if (socket) {
-            rv = closesocket((SOCKET)osfd);
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
     }
     return rv;
 }
 
 PRStatus
 _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
 {
     BOOL rv;
@@ -3817,21 +3700,16 @@ PRInt32 IsFileLocal(HANDLE hFile)
       dwIndex++;
       dwMask = dwMask >> 1;
    }
 
    return _PR_REMOTE_FILE;
 }
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
-PR_IMPLEMENT(void) PR_NT_UseNonblock()
-{
-    _nt_use_async = 0;
-}
-
 PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
 	PRBool fWait;
 	PRFileDesc *bottom;
 
 	bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
     if (!me->io_suspended || (NULL == bottom) ||