wip
[re6stnet.git] / re6st / compat.py
1 try:
2 from socket import socketpair
3 except ImportError
4 import errno, socket
5
6 def socketpair():
7 # Originally written by Tim Peters for ZEO.zrpc.trigger
8 w = socket.socket()
9 failed = 0
10 while 1:
11 # Bind to a local port; for efficiency, let the OS pick
12 # a free port for us.
13 # Unfortunately, stress tests showed that we may not
14 # be able to connect to that port ("Address already in
15 # use") despite that the OS picked it. This appears
16 # to be a race bug in the Windows socket implementation.
17 # So we loop until a connect() succeeds (almost always
18 # on the first try). See the long thread at
19 # http://mail.zope.org/pipermail/zope/2005-July/160433.html
20 # for hideous details.
21 a = socket.socket()
22 try:
23 a.bind(("127.0.0.1", 0))
24 a.listen(1)
25 w.connect(a.getsockname())
26 return w, a.accept()[0] # success
27 except socket.error, detail:
28 if detail[0] != errno.WSAEADDRINUSE or failed >= 9:
29 # "Address already in use" is the only error
30 # I've seen on two WinXP Pro SP2 boxes, under
31 # Pythons 2.3.5 and 2.4.1.
32 w.close()
33 raise
34 # assert failed < 2 # never triggered in Tim's tests
35 failed += 1
36 finally:
37 # Close `a` and try again. Note: I originally put a short
38 # sleep() here, but it didn't appear to help or hurt.
39 a.close()