Yes, but unless you run all subsequent code on the IOCP thread (thereby blocking any more completions) you need to schedule it back to another thread. This requires synchronization.
I think there's an assumption behind this whole async tasks discussion that the tasks being scheduled are I/O bound. We're trying to overlap CPU activity with I/O, and different I/O activities with each other. We're *not* trying to achieve concurrency of CPU-bound tasks -- the GIL prevents that anyway for pure Python code.
Sure, but it's easy enough to slip it in for (nearly) free. The only other option is complete exclusion of CPU-bound concurrency, which also rules out running C functions (outside the GIL) on a separate thread.
The whole Windows IOCP thing, on the other hand, seems to be geared towards having a pool of threads, any of which can handle any I/O operation. That's not helpful for us; when one of our tasks blocks waiting for I/O, the completion of that I/O must wake up *that particular task*, and it must be run using the same OS thread that was running it before.
I gather that Windows provides a way of making an async I/O request and specifying a callback for that request. If that's the case, do we need to bother with an IOCP at all? Just have the callback wake up the associated task directly.
IOCP is probably not useful at all, and as Guido said, it was brought up as an example of a non-select style of waiting. APIs like ReadFileEx/WriteFileEx let you provide the callback directly without using IOCP. In any case, even if we did use IOCP it would be an implementation detail and would not affect how the API is exposed. (Also, love your work on PEP 380. Despite my hesitation about using yield from for this API, I do really like using it with generators.) Cheers, Steve