pollfd: route the fds-removal io stop through _lws_event_loop_ops_io() - #3650
Closed
saghul wants to merge 1 commit into
Closed
pollfd: route the fds-removal io stop through _lws_event_loop_ops_io()#3650saghul wants to merge 1 commit into
saghul wants to merge 1 commit into
Conversation
__remove_wsi_socket_from_fds() calls event_loop_ops->io() directly, bypassing
the parallel routing that _lws_event_loop_ops_io() does.
That matters for the racing (parallel) connect teardown:
lws_remove_parallel_fd_safely() points wsi->desc and position_in_fds_table at
the racer it is removing and then calls __remove_wsi_socket_from_fds(), so the
raw ->io() reaches the event lib as "stop everything on this wsi". Event libs
key their watcher off the wsi (lws's own libuv elops_io_uv() uses
wsi_to_priv_uv(wsi)->w_read), so it stops the *primary* socket's watcher, while
the racer's watcher is the one meant to be stopped. The primary is still
connecting at that point and nothing re-enables its POLLOUT, so the connect
attempt hangs until it times out.
Route it like the two lws_plat_{insert,delete}_socket_into_fds() call sites
already do after 'event-loop: HE races', so the stop lands on the socket
wsi->desc actually refers to.
Contributor
Author
|
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.



Third one found while implementing the parallel-connect event lib ops (
d31f2d830"event-loop: HE races") in a custom event lib driving lws off a libuv loop.__remove_wsi_socket_from_fds()callsevent_loop_ops->io()directly, bypassing the parallel routing that_lws_event_loop_ops_io()performs:lws_remove_parallel_fd_safely()pointswsi->descandposition_in_fds_tableat the racer it is removing and then calls__remove_wsi_socket_from_fds(), so this raw call reaches the event lib as "stop everything on this wsi". Event libs resolve their watcher from the wsi — lws's own libuvelops_io_uv()useswsi_to_priv_uv(wsi)->w_read, i.e. the primary — so it stops the primary socket's watcher, when the racer's is the one being torn down. Thelws_plat_delete_socket_from_fds()call right after does go through_lws_event_loop_ops_io()and correctly stops the racer, so the net effect is: racer stopped (intended) and primary stopped (not intended).The primary is typically still connecting when a racer is removed (e.g. an unroutable AAAA racer failing first), and nothing re-enables its POLLOUT afterwards —
_lws_change_pollfd()short-circuits onpa->prev_events == pa->events, and from lws's point of view the primary's fds entry never changed — so the connect attempt hangs until it times out. Symptom on our side wasTimed out waiting SSLon hosts with more than one address.This routes it the same way the two
lws_plat_{insert,delete}_socket_into_fds()call sites were routed by 'event-loop: HE races', so the stop lands on the socketwsi->descactually refers to.Note this one is not needed by an event lib that resolves its watcher by fd rather than by wsi (which is what we ended up doing), but it does affect the in-tree libuv/libev/libevent/glib/sdevent/uloop libs, which all key off the wsi.