-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix multi callback issues: easy.pause(), easy.close(), multi.close() #708
Conversation
This ensures multi's callbacks invoked by some easy functions have access to thread state. Fixes callbacks invoked by: * do_curl_pause * util_curl_xdecref
The above build failed because of the assert on line 22: Lines 17 to 33 in 23afe62
The assert logic is OK: it verifies that easy.perform() is not called in a different thread at the same time as multi functions - not just multi.perform() though as the comment on line 28 might imply. Simply setting both I've now changed
For easy.perform() I've also reverted back to using pytest passes on my end now so I'll push the fix. |
dd3d3bd
to
ddde588
Compare
Tests invocation of callbacks by the following methods: * multi.socket_action(...) * multi.add_handle(easy) * [mid-transfer] multi.remove_handle(easy) * [mid-transfer] easy.pause(PAUSE_ALL) * [mid-transfer] easy.pause(PAUSE_CONT) * [mid-transfer] easy.close()
I've written tests for Good news is that they caught a bug which happens when you close multi handle mid-transfer without removing easy handles from it first. I'm adding the fix and tests to this PR since it's related. |
This ensures callbacks invoked by some easy-related functions have
access to the corect thread state.
Fixes callbacks invoked from:
This is the fix I referred to in #592 (comment), a continuation of #594. The latter only fixed callbacks invoked by multi handles. This one fixes them when they're invoked by easy handles as well.
Practical example:
At this point callbacks will be invoked to let you know that you should stop polling for sockets associated with that easy handle. But only
easy->state
is set byPYCURL_BEGIN_ALLOW_THREADS
, so the multi handle in multi_socket_callback() won't have access to that state and will fail to acquire thread.Thus we need to set a reference to
easy->multi_stack->state
as well. For that purpose I've addedPYCURL_BEGIN_ALLOW_THREADS_EASY
and placed it at those points where easy handles can invoke callbacks.The practical consequence of this fix is that event-driven transfers (such as asyncio) now work properly when easy handles are paused, unpaused or closed mid-transfer.
Previously multi_socket_callback() would silently fail, while your event loop would go on polling sockets that are not active anymore - or even worse (when easy handle is unpaused), the event loop would never learn about the sockets that it should start polling.