Skip to content

Commit 1859760

Browse files
ogoffartnierob
authored andcommitted
v8: add a way for a thread to call a callback
The callback will be called as soon as possible from the main thread.
1 parent e44b4b6 commit 1859760

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

src/3rdparty/v8/include/v8.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,6 +2484,8 @@ typedef void* (*CreateHistogramCallback)(const char* name,
24842484

24852485
typedef void (*AddHistogramSampleCallback)(void* histogram, int sample);
24862486

2487+
typedef void (*UserCallback)(void *data);
2488+
24872489
// --- M e m o r y A l l o c a t i o n C a l l b a c k ---
24882490
enum ObjectSpace {
24892491
kObjectSpaceNewSpace = 1 << 0,
@@ -3059,6 +3061,15 @@ class V8EXPORT V8 {
30593061
*/
30603062
static int ContextDisposedNotification();
30613063

3064+
#ifdef QT_BUILD_SCRIPT_LIB
3065+
/**
3066+
* Will call the callback with the data as parameter as soon as possible
3067+
* from the thread running the script
3068+
* This method can be used by any thread even if that thread has not
3069+
* acquired the V8 lock with a Locker object.
3070+
*/
3071+
static void ExecuteUserCallback(UserCallback Callback, void *data);
3072+
#endif
30623073
private:
30633074
V8();
30643075

src/3rdparty/v8/src/api.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4877,6 +4877,13 @@ void V8::TerminateExecution(int thread_id) {
48774877
}
48784878
}
48794879

4880+
#ifdef QT_BUILD_SCRIPT_LIB
4881+
void V8::ExecuteUserCallback(UserCallback callback, void *data) {
4882+
i::Isolate* isolate = i::Isolate::Current();
4883+
if (IsDeadCheck(isolate, "v8::ExecuteUserCallback()")) return;
4884+
isolate->stack_guard()->ExecuteUserCallback(callback, data);
4885+
}
4886+
#endif
48804887

48814888
void V8::TerminateExecution(Isolate* isolate) {
48824889
// If no isolate is supplied, use the default isolate.

src/3rdparty/v8/src/execution.cc

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,45 @@ bool StackGuard::IsTerminateExecution() {
321321
return thread_local_.interrupt_flags_ & TERMINATE;
322322
}
323323

324+
#ifdef QT_BUILD_SCRIPT_LIB
325+
bool StackGuard::IsUserCallback()
326+
{
327+
ExecutionAccess access(isolate_);
328+
return thread_local_.interrupt_flags_ & USERCALLBACK;
329+
}
330+
331+
void StackGuard::RunUserCallbackNow()
332+
{
333+
UserCallback cb;
334+
void *data;
335+
{
336+
ExecutionAccess access(isolate_);
337+
cb = thread_local_.user_callback_;
338+
data = thread_local_.user_data_;
339+
}
340+
if (cb)
341+
cb(data);
342+
}
343+
#endif
324344

325345
void StackGuard::TerminateExecution() {
326346
ExecutionAccess access(isolate_);
327347
thread_local_.interrupt_flags_ |= TERMINATE;
328348
set_interrupt_limits(access);
329349
}
330350

351+
#ifdef QT_BUILD_SCRIPT_LIB
352+
void StackGuard::ExecuteUserCallback(UserCallback callback, void *data)
353+
{
354+
ExecutionAccess access(isolate_);
355+
thread_local_.user_callback_ = callback;
356+
thread_local_.user_data_ = data;
357+
thread_local_.interrupt_flags_ |= USERCALLBACK;
358+
set_interrupt_limits(access);
359+
}
360+
#endif
361+
362+
331363

332364
bool StackGuard::IsRuntimeProfilerTick() {
333365
ExecutionAccess access(isolate_);
@@ -425,6 +457,10 @@ void StackGuard::ThreadLocal::Clear() {
425457
nesting_ = 0;
426458
postpone_interrupts_nesting_ = 0;
427459
interrupt_flags_ = 0;
460+
#ifdef QT_BUILD_SCRIPT_LIB
461+
user_callback_ = 0;
462+
user_data_ = 0;
463+
#endif
428464
}
429465

430466

@@ -775,6 +811,14 @@ MaybeObject* Execution::HandleStackGuardInterrupt() {
775811
if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
776812
DebugBreakHelper();
777813
}
814+
#endif
815+
#ifdef QT_BUILD_SCRIPT_LIB
816+
if (stack_guard->IsUserCallback()) {
817+
stack_guard->Continue(USERCALLBACK);
818+
stack_guard->RunUserCallbackNow();
819+
if (isolate->has_scheduled_exception() && !stack_guard->IsTerminateExecution())
820+
return isolate->PromoteScheduledException();
821+
}
778822
#endif
779823
if (stack_guard->IsPreempted()) RuntimePreempt();
780824
if (stack_guard->IsTerminateExecution()) {

src/3rdparty/v8/src/execution.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ enum InterruptFlag {
4040
PREEMPT = 1 << 3,
4141
TERMINATE = 1 << 4,
4242
RUNTIME_PROFILER_TICK = 1 << 5
43+
#ifdef QT_BUILD_SCRIPT_LIB
44+
, USERCALLBACK = 1 << 6
45+
#endif
4346
};
4447

4548
class Execution : public AllStatic {
@@ -179,6 +182,11 @@ class StackGuard {
179182
void TerminateExecution();
180183
bool IsRuntimeProfilerTick();
181184
void RequestRuntimeProfilerTick();
185+
#ifdef QT_BUILD_SCRIPT_LIB
186+
bool IsUserCallback();
187+
void ExecuteUserCallback(UserCallback callback, void *data);
188+
void RunUserCallbackNow();
189+
#endif
182190
#ifdef ENABLE_DEBUGGER_SUPPORT
183191
bool IsDebugBreak();
184192
void DebugBreak();
@@ -271,6 +279,10 @@ class StackGuard {
271279
int nesting_;
272280
int postpone_interrupts_nesting_;
273281
int interrupt_flags_;
282+
#ifdef QT_BUILD_SCRIPT_LIB
283+
UserCallback user_callback_;
284+
void *user_data_;
285+
#endif
274286
};
275287

276288
// TODO(isolates): Technically this could be calculated directly from a

0 commit comments

Comments
 (0)