Skip to content

E2B Tracking branch - #7

Draft
jakubno wants to merge 7 commits into
mainfrom
e2b-main
Draft

jakubno wants to merge 7 commits into
mainfrom
e2b-main

Conversation

@jakubno

@jakubno jakubno commented Jul 31, 2025

Copy link
Copy Markdown
Member

Tracks diff against the upstream

@jakubno
jakubno force-pushed the e2b-main branch 3 times, most recently from 097782b to cf77453 Compare July 31, 2025 12:48
jakubno and others added 5 commits July 31, 2025 15:52
Close queues a reply channel on done and waits for the reader to send on it after its cleanup. sendError takes that channel when the watcher is closing and drops it, so the reader never sees the shutdown request and Close blocks forever. These tests pin the channel handoff and the end-to-end Close; they fail before the fix.
sendError received the reply channel that Close queued on done and discarded it, unlike sendEvent, which puts it back. When nobody reads Errors any more and the backend then reports an error (an overflow, a failed CancelIo or CloseHandle), the reader handled the wakeup without the shutdown request, skipped the cleanup of its watches and the completion port, and Close waited on the reply forever. sendError now puts the channel back, as sendEvent does; TestSendErrorKeepsCloseReply and TestCloseAfterUnreadError fail without this change on windows-latest and pass with it.
Close read closed under the lock, released it, and set it under a second acquisition, so two concurrent calls could both proceed and queue two reply channels. done holds one, so the second Close blocked sending, and with an undeliverable error between them the reader, now keeping the first reply, could not drain the second: both calls and the reader hung. The check and the set now happen under one lock, so a second Close returns at once. TestConcurrentClose runs eight concurrent Close calls under a timeout and checks that no reply is left on done; the interleaving is a race, so it guards rather than reproduces.
…reply

windows: keep Close's reply channel when an error cannot be delivered
@cla-bot cla-bot Bot added the cla-signed label Oct 28, 2026
@cursor

cursor Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Inotify recursive create handling emits multiple events under lock and changes default watch semantics; Windows shutdown fixes touch concurrency-critical paths.

Overview
The module path and imports move to github.com/e2b-dev/fsnotify, with README describing recursive watches via a ... path suffix and narrowing supported platforms (kqueue/FEN marked not ready for this fork).

Recursive watching is turned on by default (enableRecurse = true); inotify walks trees on add, skips permission-denied subdirs, and on directory create walks nested dirs with synthetic Create events for mkdir -p-style trees. Windows sendError and Close are fixed so shutdown reply channels are not dropped under concurrent or unread Errors, with new Windows tests.

WithCreate() is exported for recursive inotify behavior. Stale docs still say Add is non-recursive and that recursion is test-only in recursivePath; README still links to upstream pkg.go.dev instead of the fork.

Reviewed by Cursor Bugbot for commit b260f7c. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b260f7c. Configure here.

Comment thread backend_inotify.go

// Send the previous event first to maintain proper ordering, then create a new event for the current directory
// The function expects to return only one event, so we need to send the previous event first and then create a new one
w.sendEvent(ev)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deadlock: sendEvent called while holding mutex

High Severity

w.sendEvent(ev) is called inside the WalkDir callback while w.mu is held (acquired at line 422 via handleEvent). On Linux, defaultBufferSize is 0, making Events unbuffered. If the channel blocks waiting for a consumer, and that consumer then calls Add, Remove, or WatchList (all of which acquire w.mu), a deadlock occurs. The existing sendEvent in readEvents (line 411) is safe because it runs after handleEvent returns and the deferred unlock fires; this new call inside the lock is not.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b260f7c. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants