Lifecycle Management
This content is for v1. Switch to the latest version for up-to-date documentation.
此内容尚不支持你的语言。
The bridge lifecycle has three layers: process-level Runtime, Isolate-level Session, and object-level Opaque handle. Understanding who creates, who releases, and who must not be touched is key to avoiding deadlocks and memory leaks.
Runtime: Process-Level Singleton
Section titled “Runtime: Process-Level Singleton”dcb::Runtime is a process-level singleton that internally manages:
asio::io_contextevent loopAsioExecutorthread_pool- Session registry
Startup and Shutdown
Section titled “Startup and Shutdown”- Startup: usually triggered automatically by
DartCppBridge.init(); C++ unit tests or pure C++ programs can calldcb::Runtime::instance().start()manually. - Shutdown:
DartCppBridge.shutdown()ordcb::Runtime::instance().stop()
Limitation: shutdown() can only be called from the main isolate / on process exit. It closes all Sessions and stops the Runtime.
Session: One per Isolate
Section titled “Session: One per Isolate”Every Dart Isolate that calls DartCppBridge.init() owns a Session:
- Independent reply port
- Independent
DartFnclosure registry - Generation counter
generation, used to drop late messages afterdispose()
Session Creation and Closing
Section titled “Session Creation and Closing”| Operation | Caller Location | Behavior |
|---|---|---|
init() |
Any Isolate | Creates or reuses a Session |
dispose() |
Current Isolate | Immediately closes that Isolate’s Session |
| Isolate shutdown / GC | Any | NativeFinalizer automatically closes the Session |
shutdown() |
Main isolate exit | Closes all Sessions |
dispose()is optional; normally rely onNativeFinalizeralone.- Do not call
shutdown()from a worker isolate. - Worker isolates can call
init(), own their own Session, but must not callshutdown().
Opaque Objects: Per-Session Handle
Section titled “Opaque Objects: Per-Session Handle”C++ objects marked with BRIDGE_OPAQUE are referenced from Dart via a handle:
- On construction: C++ creates the object, registers it in
ObjectHandleRegistry, and returns a handle. - On use: Dart passes the handle to C++ instance methods.
- On destruction: Dart GC triggers
NativeFinalizer→dcb_drop_object→ removes it from the registry and destructs it.
Lifecycle Boundaries
Section titled “Lifecycle Boundaries”- When a Session closes, all Opaque objects under that Session are automatically released.
- If Dart still holds an object reference but the Session is already closed, subsequent calls will fail.
Typical Flow
Section titled “Typical Flow”App starts └─ main isolate calls DartCppBridge.init() └─ Runtime starts (if not already started) └─ Session A is created ├─ worker isolate calls DartCppBridge.init() │ └─ Session B is created │ ├─ Dart calls C++ to create an Opaque object │ └─ ObjectHandleRegistry registers it and returns a handle │ ├─ Dart GC or dispose releases the Opaque object │ └─ NativeFinalizer → dcb_drop_object → destruct │ └─ App exits └─ main isolate calls shutdown() └─ Sessions A / B close, Runtime stopsCommon Mistakes
Section titled “Common Mistakes”| Mistake | Consequence |
|---|---|
Worker isolate calls shutdown() |
Closes the main isolate’s Session, stops the Runtime, and breaks the bridge |
Calling after dispose() |
Calls from that isolate will fail |
| Holding Opaque objects across Isolates | Objects cannot be shared across Isolates |
Calling DartFn inside BRIDGE_SYNC |
Deadlock (Dart replies need the io thread) |