hello. i'm working on an asyncio bug in ProactorEventLoop transport https://bugs.python.org/issue33694#msg318875 pause_reading() cancels an overlapped WSARecv(), but sometimes WSARecv() completed before the cancellation
itamarst joined the channel
if WSARecv() completed but we call CancelIoEx(), I got an ERROR_NOT_FOUND and the IOCP loop then notify me that the WSARecv() completed
problem: if really want to cancel WSARecv() as soon as pause_reading() is called, otherwise it breaks the transport/protocol semantics in many different ways :-(
i* really want
i'm trying to avoid CancelIoEx() in pause_reading(), but asyncio recently got support for recv_into(), and start_tls() switchs from recv_into() to recv() in my case
recv_into() and recv() implementations are very different
so well, i have many issues and no idea how to deal with that :-( anyone has an advice for me? how does Twisted handle WSARecv() cancellation? how do you deal with ERROR_NOT_FOUND on CancelIoEx()
note: when CancelIoEx() fails with ERROR_NOT_FOUND, HasOverlappedIoCompleted() returns 0 (no completed I/O ... which is wrong, liar!)
it's hard to find any information about WSARecv() cancellation :-/ in short, the Internet tells me "don't do that, you fool!"
+1 for "post to the mailinglist" -- we've seem some very odd IOCP failures (probably #9446) but it'd be nice to have the above weirdness put into something not-epheheral :)
You guys probably already know this... but it seems twistedmatrix.com is down?
tos9
again?
runciter: ^^
ryanc-- joined the channel
rajesh has quit
ryanc--
Anybody have any idea when the website will be fixed?
clokep joined the channel
ryanc-- has quit
vstinner
cdunklau, teratorn : ok, thanks for your advices ;-) right now, the plan is to unblock the release by avoiding completely to cancel any overlapped WSASend() :-)
cdunklau: i read quickly the twisted/internet/iocpreactor but i failed to find the code that i was looking for. i should spend more time on it ;)
clokep joined the channel
njs
vstinner: I don't understand what semantics you're trying to get, but in general CancelIoEx's semantics are that it submits a request for the operation to be cancelled, and this submission might fail, or the submission might succeed but then the actual cancellation fails -- you don't know until you check the actual result of the operation
(at least AFAICT, I haven't actually implemented this yet myself so I'm sure there will be some fun surprises)
njs: first, i wanted to understand why test_asyncio.test_start_tls_server_1() failed randomly on Windows
njs: after a very long of hacking, i understood that asyncio had race condition. the issue wasn't start_tls() nor the test, but the proactor event loop
njs: it seems like proactor had a race condition, probably as old at the proactor code: pause_reading() cancels the overlapped WSARecv()
njs: most of the time, it's fine. but sometimes. WSARecv() actually completed in the meanwhile, and so CancelIoEx() fails with ERROR_NOT_FOUND. this error is silently ignored at the C level
njs: in this case, the overlapped object contains the actual data. but since the asyncio Future object has been cancelled, the completion of the WSASend() is ignored by the IOCP loop, and so... the data is lost forever
njs
vstinner: right
vstinner
njs: there are maybe two issues in asyncio. first, ERROR_NOT_FOUND is silently ignored. second, maybe WSARecv() should never be cancelled :) <= that's my workaround
njs
I guess cancelling it is fine, but if the cancellation fails then you should still deliver the data
I guess this might be tricky though b/c Future.cancel insists that cancellation must always succeed, and always be synchronous
njs: ah, and now to come back to the semantics: you can change the protocol of a transport. asyncio in python 3.7 got support for "buffer". a protocol contains a bytearray.
njs: if you change the protocol using set_protocol() on a transport, i expect that the old protocol is immediatly forgotten
njs: but WSARecv() doesn't seem to allow that, since cancelling the overlapped can fail... if it completed in the meanwhile
njs: my issue is either that i don't understand Windows APIs and that asyncio semantics is very strict
meejah
is it possible to know how many bytes are in the overlapped call (and remember that, and nuke them if they come it)....?