Skip to content

core: event: prevent libevent timer socket deadlock - #445

Open
zshuang0316 wants to merge 1 commit into
monkey:masterfrom
zshuang0316:core-event-prevent-libevent-timer-deadlock
Open

core: event: prevent libevent timer socket deadlock#445
zshuang0316 wants to merge 1 commit into
monkey:masterfrom
zshuang0316:core-event-prevent-libevent-timer-deadlock

Conversation

@zshuang0316

Copy link
Copy Markdown

Summary

The libevent timeout callback writes timer notifications from the event-loop
thread. If unread notifications fill the socket buffer, the blocking
send() waits for that same event loop to drain the read endpoint and the
loop deadlocks.

Make the timer write endpoint nonblocking and treat EAGAIN/
EWOULDBLOCK as an already-pending notification. Also retrieve send errors
from the actual write endpoint instead of the libevent timer callback fd,
which is -1.

The issue was observed in Fluent Bit on Windows. A Windows Performance
Recorder trace showed the engine thread blocked through:

cb_timeout() -> send() -> WSPSend() -> SockWaitForSingleObject()

The same issue can affect any platform explicitly using Monkey's libevent
backend.

Related downstream PR: fluent/fluent-bit#12241

Testing

Built Monkey with the libevent backend on Windows and ran:

mk-test-event_timeout.exe

Result:

SUCCESS: All unit tests have passed.

The libevent timer callback writes notifications from the event-loop
thread. If its socket buffer fills, a blocking send waits for the same
loop to drain the read side and deadlocks the loop.

Make the write endpoint nonblocking and treat a would-block result as an
already pending timer notification. Read errors from the write socket
instead of the timer callback descriptor.

Signed-off-by: zshuang0316 <zshuang0316@163.com>
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.

1 participant