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.

Author gvanrossum
Recipients Justin Mayfield, gvanrossum, thehesiod, vstinner, yselivanov
Date 2015-11-17.00:40:03
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1447720803.93.0.50257949829.issue25593@psf.upfronthosting.co.za>
In-reply-to
Content
Thinking about this more I believe it's possible for any of the FD callbacks in selector_events.py to be placed into loop._ready multiple times if the loop is stopped after the FD is ready (and the callback is scheduled) but before the callback is called. In all cases such a scenario results in the same callback (with the same future) being scheduled twice; the first call will call fut.set_result() and then the second call, if the FD is (still, or again) ready, will fail calling fut.set_result() on the same Future.

The reason we've only seen reports of this for _sock_connect_cb() is probably that the other calls are all uncommon -- you have to explicitly call loop.sock_accept(), loop.sock_recv(), or loop.sock_sendall(), which is not the usual (or recommended) idiom. Instead, most people use Transports and Protocols, which use a different API, and create_server() doesn't use sock_accept().  But create_connection() *does* call sock_connect(), so that's used by everybody's code.

I think the discussed change to stop() to set a flag that is only checked after all the ready for-loop is done might work here -- it guarantees that all I/O callbacks get to run before the selector is polled again. However, it requires that an I/O callback that wants to modify the selector in order to prevent itself from being called must do so itself, not schedule some other call that modifies the selector. That's fine for the set of I/O callbacks I've looked at.

I just don't feel comfortable running the ready queue before polling the selector, since a worst-case scenario could starve the selector completely (as I sketched before -- and the proposed modification to stop() doesn't directly change this).
History
Date User Action Args
2015-11-17 00:40:04gvanrossumsetrecipients: + gvanrossum, vstinner, yselivanov, thehesiod, Justin Mayfield
2015-11-17 00:40:03gvanrossumsetmessageid: <1447720803.93.0.50257949829.issue25593@psf.upfronthosting.co.za>
2015-11-17 00:40:03gvanrossumlinkissue25593 messages
2015-11-17 00:40:03gvanrossumcreate