Skip to content

Conversation

@DanShaders
Copy link
Collaborator

tonlib::EngineConsoleClient was accidentally merged with simplex even though the code was not meant to be seen by the world yet. This PR fixes stuff I was meaning to change before upstreaming the client.

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

  • High: Data race in ObjectCounter now that count_ is plain size_t with no synchronization. new_actor() increments and the guard decrements can run on different threads (client thread vs scheduler thread), making count_ and is_zero() UB under concurrent use. Consider restoring std::atomic<size_t> or guarding with a mutex. tonlib/tonlib/FFIEventLoop.h:11 tonlib/tonlib/FFIEventLoop.cpp:10
  • Medium: The actor-lifetime tracking changed from being tied to the actor instance (via ClientWrapper holding the guard) to being tied to the owning FFIEngineConsoleClient object (counter_). If EngineConsoleClient destruction is asynchronous or the actor outlives the owner, FFIEventLoop can now see is_zero() and stop the scheduler while an actor is still alive. If the intent is still “no stray actors”, keep the guard owned by the actor or ensure ActorOwn destruction is synchronous. tonlib/tonlib/FFIEngineConsoleClient.cpp:5 tonlib/tonlib/FFIEngineConsoleClient.h:31
  • Low: Tests now dereference *loop.wait(-1) directly. wait() can return nullopt on cancellation or if the eventfd wait returns without data (e.g., EINTR). This can make tests flaky with a hard crash instead of cleanly retrying. Consider keeping the loop‑until‑value helper in tests. test/tonlib/test-ffi-awaitable.cpp:104 test/tonlib/test-ffi-event-loop.cpp:51

@DanShaders DanShaders force-pushed the engine-console-client-review branch from 8d2aa9e to da43f8d Compare February 10, 2026 14:50
@github-actions
Copy link

  • Commit da43f8d: tonlib/tonlib/FFIEventLoop.h:15-26 + tonlib/tonlib/FFIEventLoop.cpp:10-13ObjectCounter::count_ is now a plain size_t with unsynchronized ++/-- and reads in is_zero(). new_actor() and guard destruction can run on different threads (e.g., FFI callers), and FFIEventLoop::~FFIEventLoop() reads it concurrently, which is a data race/UB and can also make the CHECK unreliable. At minimum keep std::atomic<size_t> (as before) or guard with a mutex; if you truly rely on single-threaded access, that invariant needs to be enforced/ documented and the CHECK should still be synchronized.

FFIEventLoop::run_in_context doesn't actually spawn lambda in a
different thread, it just sets some thread_local variables and calls the
lambda inline.
FFIEventLoop does not spuriously unblock.
The old code assumed that SchedulerContext::stop does not correctly work
when there are alive actors. However, my investigation into
SchedulerContext::stop implementation revealed that it most likely works
correctly and intuitively. Even if it doesn't, the solution we had did
not fully guard us against bugs (since it did not wait child actors) and
at best masked some race conditions.
@DanShaders DanShaders force-pushed the engine-console-client-review branch from da43f8d to e74aa1a Compare February 12, 2026 19:49
@github-actions
Copy link

  1. Commit e74aa1a2 (“Simplify check for no stray actors on FFIEventLoop destruction”): FFIEngineConsoleClient now holds the guard in the outer object, but the actor is reset asynchronously in ~FFIEngineConsoleClient(). That means counter_ can be released before the actor actually stops, so FFIEventLoop::~FFIEventLoop() can see object_counter_ as zero while a live EngineConsoleClient actor still exists. This defeats the “no stray actors” check and can allow event loop teardown with active actors. Consider re-attaching the guard to the actor lifetime (restore the wrapper), or move counter_ into the run_in_context lambda and only release it after client.reset() runs on the scheduler thread. References: tonlib/tonlib/FFIEngineConsoleClient.cpp:7, tonlib/tonlib/FFIEngineConsoleClient.h:19, tonlib/tonlib/FFIEventLoop.cpp:11.

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