[ python-Bugs-777588 ] asyncore is broken for windows if connection is refused

SourceForge.net noreply at sourceforge.net
Sun Jan 7 07:19:11 CET 2007


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

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Library
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Garth Bushell (garth42)
Assigned to: Josiah Carlson (josiahcarlson)
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: Josiah Carlson (josiahcarlson)
Date: 2007-01-06 22:19

Message:
Logged In: YES 
user_id=341410
Originator: NO

I am looking into applying a variant of portions of #909005 to fix this
bug.

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

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

Message:
Logged In: YES 
user_id=410460

Patch #909005 fixes the problem.

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

Comment By: John J Smith (johnjsmith)
Date: 2003-07-29 05: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()


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

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=777588&group_id=5470


More information about the Python-bugs-list mailing list