Merged
Conversation
Implement blocking receive for channels that suspends Python while waiting for data and releases the dirty scheduler worker. - Add sync_waiter_pid and has_sync_waiter fields to py_channel_t - Add channel_register_sync_waiter NIF to register calling process - Modify channel_send to notify sync waiter via Erlang message - Modify channel_close to notify sync waiter of channel closure - Implement blocking handle_receive using Erlang receive to wait - Add tests for immediate, delayed, and closed channel cases
Test verifies blocking channel receive works with Python 3.12+ subinterpreter contexts. Skips gracefully on older Python versions.
- Use py_context:start_link/2 with unique integer ID - Use py_context:stop/1 instead of gen_server:stop - Test immediate receive, blocking receive with delayed send, try_receive on empty, and closed channel detection
cc2241c to
f15fd78
Compare
- Check if data is available when registering sync waiter to handle race between try_receive returning empty and register_sync_waiter being called - Return 'has_data' atom when data arrived in the window, caller retries - Notify sync waiter in channel destructor when channel is GC'd - Do not notify async waiter in destructor to avoid use-after-free when event loop is destroyed concurrently - Update test to consume data before re-registering waiter
The ChannelBuffer type was defined but never used. Removing dead code.
- Reject duplicate/mixed waiters: both async and sync waiter registration
now return {error, waiter_exists} if any waiter already exists
- Fix lost wakeups: event_loop_add_pending now returns bool; waiter state
is only cleared after successful dispatch
- Add null checks for enif_alloc_env in sync waiter notifications
- Add tests for mixed waiter rejection scenarios
The asgi_run and wsgi_run NIF functions are deprecated. Removed tests that call these functions, keeping only the deprecation attribute tests.
f9ab7e1 to
748d933
Compare
Clear tl_pending_args to NULL whenever tl_pending_callback is set to false. Previously, the thread-local pointer was left dangling after callback completion. When a dirty scheduler thread later handled a different subinterpreter's code, Py_XDECREF on the stale pointer would attempt to free memory from the wrong allocator.
748d933 to
d760e05
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
sync_waiter_pidandhas_sync_waiterfields to channel structchannel_register_sync_waiterNIF to register calling process as waiterchannel_sendto notify sync waiter viachannel_data_readymessagechannel_closeto notify sync waiter viachannel_closedmessagehandle_receiveusing Erlangreceiveto wait for data