@@ -25,61 +25,60 @@ namespace facebook::react {
25
25
using RuntimeExecutor =
26
26
std::function<void (std::function<void (jsi::Runtime& runtime)>&& callback)>;
27
27
28
- /*
29
- * Executes a `callback` in a *synchronous* manner on the same thread using
30
- * given `RuntimeExecutor`.
31
- * Use this method when the caller needs to *be blocked* by executing the
32
- * `callback` and requires that the callback will be executed on the same
33
- * thread.
34
- * Example order of events (when not a sync call in runtimeExecutor callback):
28
+ /* *
29
+ * Example order of events (when not a sync call in runtimeExecutor
30
+ * jsWork):
35
31
* - [UI thread] Lock all mutexes at start
36
- * - [UI thread] runtimeCaptured.lock before callback
37
- * - [JS thread] Set runtimePtr in runtimeExecutor callback
38
- * - [JS thread] runtimeCaptured.unlock in runtimeExecutor callback
39
- * - [UI thread] Call callback
40
- * - [JS thread] callbackExecuted.lock in runtimeExecutor callback
41
- * - [UI thread] callbackExecuted.unlock after callback
42
- * - [UI thread] jsBlockExecuted.lock after callback
43
- * - [JS thread] jsBlockExecuted.unlock in runtimeExecutor callback
32
+ * - [UI thread] Schedule "runtime capture block" on js thread
33
+ * - [UI thread] Wait for runtime capture: runtimeCaptured.lock()
34
+ * - [JS thread] Capture runtime by setting runtimePtr
35
+ * - [JS thread] Signal runtime captured: runtimeCaptured.unlock()
36
+ * - [UI thread] Call jsWork using runtimePtr
37
+ * - [JS thread] Wait until jsWork done: jsWorkDone.lock()
38
+ * - [UI thread] Signal jsWork done: jsWorkDone.unlock()
39
+ * - [UI thread] Wait until runtime capture block finished:
40
+ * runtimeCaptureBlockDone.lock()
41
+ * - [JS thread] Signal runtime capture block is finished:
42
+ * runtimeCaptureBlockDone.unlock()
44
43
*/
45
44
inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK (
46
45
const RuntimeExecutor& runtimeExecutor,
47
- std::function<void (jsi::Runtime& runtime)>&& callback ) noexcept {
46
+ std::function<void (jsi::Runtime& runtime)>&& jsWork ) noexcept {
48
47
// Note: We need the third mutex to get back to the main thread before
49
48
// the lambda is finished (because all mutexes are allocated on the stack).
50
49
51
50
std::mutex runtimeCaptured;
52
- std::mutex callbackExecuted ;
53
- std::mutex jsBlockExecuted ;
51
+ std::mutex jsWorkDone ;
52
+ std::mutex runtimeCaptureBlockDone ;
54
53
55
54
runtimeCaptured.lock ();
56
- callbackExecuted .lock ();
57
- jsBlockExecuted .lock ();
55
+ jsWorkDone .lock ();
56
+ runtimeCaptureBlockDone .lock ();
58
57
59
58
jsi::Runtime* runtimePtr;
60
59
61
60
auto threadId = std::this_thread::get_id ();
62
-
63
- runtimeExecutor ([&](jsi::Runtime& runtime) {
61
+ auto runtimeCaptureBlock = [&](jsi::Runtime& runtime) {
64
62
runtimePtr = &runtime;
65
63
66
64
if (threadId == std::this_thread::get_id ()) {
67
65
// In case of a synchronous call, we should unlock mutexes and return.
68
66
runtimeCaptured.unlock ();
69
- jsBlockExecuted .unlock ();
67
+ runtimeCaptureBlockDone .unlock ();
70
68
return ;
71
69
}
72
70
73
71
runtimeCaptured.unlock ();
74
- // `callback` is called somewhere here.
75
- callbackExecuted.lock ();
76
- jsBlockExecuted.unlock ();
77
- });
72
+ // `jsWork` is called somewhere here.
73
+ jsWorkDone.lock ();
74
+ runtimeCaptureBlockDone.unlock ();
75
+ };
76
+ runtimeExecutor (std::move (runtimeCaptureBlock));
78
77
79
78
runtimeCaptured.lock ();
80
- callback (*runtimePtr);
81
- callbackExecuted .unlock ();
82
- jsBlockExecuted .lock ();
79
+ jsWork (*runtimePtr);
80
+ jsWorkDone .unlock ();
81
+ runtimeCaptureBlockDone .lock ();
83
82
}
84
83
85
84
template <typename DataT>
0 commit comments