[ python-Bugs-953599 ] asyncore misses socket closes when poll is used

SourceForge.net noreply at sourceforge.net
Fri Jul 2 09:56:13 EDT 2004


Bugs item #953599, was opened at 2004-05-14 01:47
Message generated for change (Comment added) made by klimkin
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=953599&group_id=5470

Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Shane Kerr (shane_kerr)
Assigned to: A.M. Kuchling (akuchling)
Summary: asyncore misses socket closes when poll is used

Initial Comment:
Problem:

If the loop() function of asyncore is invoked with poll
rather than select, the function readwrite() is used
when I/O is available on a socket.  However, this
function does not check for hangup - provided by POLLHUP.

If a socket is attempting to write, then POLLOUT never
gets set, so the socket hangs.  

Because poll() is returning immediately, but the return
value is never used, asyncore busy-loops, consuming all
available CPU.


Possible solutions:

The easy solution is to check for POLLHUP in the
readwrite() function:

        if flags & (select.POLLOUT | select.POLLHUP):
            obj.handle_write_event()

This makes the poll work exactly like the select - the
application raises a socket.error set to EPIPE.

An alternate solution - possibly more graceful - is to
invoke the handle_close() method of the object:

        if flags & select.POLLHUP:
            obj.handle_close()
        else:
            if flags & select.POLLIN:
                obj.handle_read_event()
            if flags & select.pollout:
                obj.handle_write_event()

This is incompatible with the select model, but it
means that the read and write logic is now the same for
socket hangups - handle_close() is invoked.


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

Comment By: Alexey Klimkin (klimkin)
Date: 2004-07-02 17:56

Message:
Logged In: YES 
user_id=410460

Perhaps, it would be better to raise exception:

def readwrite(obj, flags):
    try:
        if flags & (select.POLLIN | select.POLLPRI):
            obj.handle_read_event()
        if flags & select.POLLOUT:
            obj.handle_write_event()
        if flags & (select.POLLERR | select.POLLHUP |
select.POLLNVAL):
            obj.handle_expt_event()
    except ExitNow:
        raise
    except:
        obj.handle_error()

...

    def handle_expt_event(self):
        err = self.socket.getsockopt(socket.SOL_SOCKET,
socket.SO_ERROR)
        assert(err != 0)
        raise socket.error, (err, errorcode[err])

Since asyncore closes socket in handle_error, this solves
the problem too.

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

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



More information about the Python-bugs-list mailing list