[Zodb-checkins] CVS: StandaloneZODB/ZEO/zrpc - client.py:1.1.2.2.2.2

Jeremy Hylton jeremy@zope.com
Thu, 30 May 2002 23:19:17 -0400


Update of /cvs-repository/StandaloneZODB/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv1950

Modified Files:
      Tag: ZEO2-branch
	client.py 
Log Message:
Fix connection logic to work better (correctly?) on Win2k.

A comment in the code explains:

It appears that winsock isn't behaving as
expected on Win2k.  It's possible for connect()
to return 0, but the connection to have failed.
In particular, in situations where I expect to
get a Connection refused (10061), I'm seeing
connect_ex() return 0.  OTOH, it looks like
select() is a more reliable indicator on
Windows.


=== StandaloneZODB/ZEO/zrpc/client.py 1.1.2.2.2.1 => 1.1.2.2.2.2 ===
                     return 0
                 try:
-                    r, w, x = select.select([], self.sockets.keys(), [], 1.0)
+                    sockets = self.sockets.keys()
+                    r, w, x = select.select([], sockets, sockets, 1.0)
                 except select.error:
                     continue
+                for s in x:
+                    del self.sockets[s]
+                    s.close()
                 for s in w:
                     # connect() raises Connected iff it succeeds
                     self.connect(s)
@@ -310,9 +314,29 @@
             log("failed to connect to %s: %s" % (addr, msg),
                 level=zLOG.ERROR)
         else:
+            log("connect_ex(%s) == %s" % (addr, e))
             if e in _CONNECT_IN_PROGRESS:
                 return
             elif e in _CONNECT_OK:
+                # special cases to deal with winsock oddities
+                if sys.platform.startswith("win") and e == 0:
+                    
+                    # It appears that winsock isn't behaving as
+                    # expected on Win2k.  It's possible for connect()
+                    # to return 0, but the connection to have failed.
+                    # In particular, in situations where I expect to
+                    # get a Connection refused (10061), I'm seeing
+                    # connect_ex() return 0.  OTOH, it looks like
+                    # select() is a more reliable indicator on
+                    # Windows.
+                    
+                    r, w, x = select.select([s], [s], [s], 0.1)
+                    if not (r or w or x):
+                        return
+                    if x:
+                        # see comment at the end of the function
+                        s.close()
+                        del self.socket[s]
                 c = self.test_connection(s, addr)
                 if c:
                     log("connected to %s" % repr(addr), level=zLOG.DEBUG)