Skip to content

fix(event): allocate loop->ios in hloop_init - #900

Merged
ithewei merged 1 commit into
ithewei:masterfrom
prestonbrown:fix/hloop-init-ios
Oct 8, 2026
Merged

ithewei merged 1 commit into
ithewei:masterfrom
prestonbrown:fix/hloop-init-ios

Conversation

@prestonbrown

Copy link
Copy Markdown
Contributor

hloop_init leaves loop->ios unallocated, so the first hio_get() allocates it. EventLoopThread::start() returns once the loop is running, before hloop_run() has created the eventfd io, and WebSocketClient::open() calls createsocket() -> hio_get() on the caller's thread. When those two are the first hio_get() on the loop, both allocate the array and one io is lost. The queued startConnect then reaches iowatcher_add_event with loop->ios.ptr[fd] == NULL:

#0 iowatcher_add_event
#1 hio_add
#2 std::function<void(hv::Event*)>::operator()
#3 hv::EventLoop::onCustomEvent
#4 eventfd_read_cb

We hit it about once in 360 runs of a test that starts an EventLoopThread and immediately connects a WebSocketClient. With the array allocated in hloop_init it did not recur in 1800 runs. fds at or past IO_ARRAY_INIT_SIZE still resize lazily.

hio_get() allocated loop->ios on first use, on whichever thread got there first. TcpClient::createsocket() calls hio_get() on the caller's thread, and EventLoopThread::start() returns before hloop_run() has created the eventfd io, so the two first allocations can race and one io is lost. Allocating the array in hloop_init() leaves only fds >= IO_ARRAY_INIT_SIZE to resize lazily.
@ithewei
ithewei merged commit f7b8cd2 into ithewei:master Oct 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants