This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2004年05月13日 21:47 by shane_kerr, last changed 2022年04月11日 14:56 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| asyncore.py.diff | shane_kerr, 2004年05月13日 21:47 | |||
| Messages (4) | |||
|---|---|---|---|
| msg20798 - (view) | Author: Shane Kerr (shane_kerr) | Date: 2004年05月13日 21:47 | |
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. |
|||
| msg20799 - (view) | Author: Alexey Klimkin (klimkin) | Date: 2004年07月02日 13:56 | |
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. |
|||
| msg20800 - (view) | Author: Josiah Carlson (josiahcarlson) * (Python triager) | Date: 2007年01月06日 23:21 | |
The solution suggested by klimkin seems to have made it into revision 35513 as a fix to bug #887279. I'm not sure that this is necessarily the right solution to this bug or #887279, as a socket disconnect isn't necessarily an error condition, otherwise .handle_close_event() shouldn't exist for select-based loops, and it should always be an error. Suggest switching to the last if clause of readwrite() to... if flags & (select.POLLERR | select.POLLNVAL): obj.handle_expt_event() if flags & select.POLLHUP: obj.handle_close_event() |
|||
| msg69376 - (view) | Author: Josiah Carlson (josiahcarlson) * (Python triager) | Date: 2008年07月07日 05:04 | |
Fixed for 2.6 in changelist 64768. Fixed for 3.0 in changelist 64770. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:56:04 | admin | set | github: 40253 |
| 2008年07月07日 05:04:43 | josiahcarlson | set | status: open -> closed resolution: fixed messages: + msg69376 |
| 2008年01月04日 04:10:28 | christian.heimes | set | versions: + Python 2.6 |
| 2007年12月13日 01:29:26 | giampaolo.rodola | set | nosy: + giampaolo.rodola |
| 2004年05月13日 21:47:17 | shane_kerr | create | |