1 message in org.python.python-bugs-list[ python-Bugs-777588 ] asyncore is br...
FromSent OnAttachments
SourceForge.netMar 4, 2004 9:24 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[ python-Bugs-777588 ] asyncore is broken for windows if connection is refusedActions...
From:SourceForge.net (nore@sourceforge.net)
Date:Mar 4, 2004 9:24:58 am
List:org.python.python-bugs-list

Bugs item #777588, was opened at 2003-07-25 18:43 Message generated for change (Comment added) made by klimkin You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=777588&group_id=5470

Category: Python Library Group: Python 2.3 Status: Open Resolution: None Priority: 5 Submitted By: Garth Bushell (garth42) Assigned to: Nobody/Anonymous (nobody) Summary: asyncore is broken for windows if connection is refused

Initial Comment: asyncore.poll is broken on windows. If a connection is refused happens it will hang for ever and never raise an exception.

The Select statment never checks the exfds. This is needed as this is where windows reports failed connections. The documentation in the microsoft platform SDK mentions this.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp

The suggested fix is shown below althought this is untested. The correct error number is recived from getsockopt(SOL_SOCKET,SO_ERROR)

def poll(timeout=0.0, map=None): if map is None: map = socket_map if map: r = []; w = []; e = [] for fd, obj in map.items(): if obj.readable(): r.append(fd) if obj.writable(): w.append(fd)

if sys.platform == 'win32': if not obj.connected: e.append(fd) if [] == r == w == e: time.sleep(timeout) else: try: r, w, e = select.select(r, w, e, timeout) except select.error, err: if err[0] != EINTR: raise else: return

if sys.platform == 'win32': for fd in e: obj = map.get(fd) if obj is None: continue errno = fs.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) raise socket.error,(errno,socketerrorTab[error])

for fd in r: obj = map.get(fd) if obj is None: continue read(obj)

for fd in w: obj = map.get(fd) if obj is None: continue write(obj)

----------------------------------------------------------------------

Comment By: Alexey Klimkin (klimkin) Date: 2004-03-04 11:23

Message: Logged In: YES user_id=410460

Patch #909005 fixes the problem.

----------------------------------------------------------------------

Comment By: John J Smith (johnjsmith) Date: 2003-07-29 16:49

Message: Logged In: YES user_id=830565

I was bitten by the same problem. My workaround (in a Tkinter application) is given below.

Would it make sense to modify poll() to simply add the union of r and w to e, and call handle_error() for any fd in e?

Workaround:

try: self.connect(send_addr) except socket.error: self.handle_error() if sys.platform == 'win32': # Win98 select() doesn't seem to report errors for a # non-blocking connect(). self.__connected = 0 self.__frame.after(2000, self.__win_connect_poll)

...

if sys.platform == 'win32': def __win_connect_poll (self): if self.__connected: return e = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if e in (0, errno.EINPROGRESS, errno.WSAEINPROGRESS): self.__frame.after(2000, self.__win_connect_poll) else: try: str = socket.errorTab[e] except KeyError: str = os.strerror(e) try: raise socket.error(e, str) except socket.error: self.handle_error()

----------------------------------------------------------------------