| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8057315 commit 134a60c
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,18 @@ | |||
| 1 | + #ifndef SRC_ATOMIC_POLYFILL_H_ | ||
| 2 | + #define SRC_ATOMIC_POLYFILL_H_ | ||
| 3 | + | ||
| 4 | + #include "util.h" | ||
| 5 | + | ||
| 6 | + namespace nonstd { | ||
| 7 | + | ||
| 8 | + template <typename T> | ||
| 9 | + struct atomic { | ||
| 10 | + atomic() = default; | ||
| 11 | + T exchange(T value) { return __sync_lock_test_and_set(&value_, value); } | ||
| 12 | + T value_ = T(); | ||
| 13 | + DISALLOW_COPY_AND_ASSIGN(atomic); | ||
| 14 | + }; | ||
| 15 | + | ||
| 16 | + } // namespace nonstd | ||
| 17 | + | ||
| 18 | + #endif // SRC_ATOMIC_POLYFILL_H_ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,6 +86,14 @@ typedef int mode_t; | |||
| 86 | 86 | extern char **environ; | |
| 87 | 87 | #endif | |
| 88 | 88 | ||
| 89 | + #ifdef __APPLE__ | ||
| 90 | + #include "atomic-polyfill.h" // NOLINT(build/include_order) | ||
| 91 | + namespace node { template <typename T> using atomic = nonstd::atomic<T>; } | ||
| 92 | + #else | ||
| 93 | + #include <atomic> | ||
| 94 | + namespace node { template <typename T> using atomic = std::atomic<T>; } | ||
| 95 | + #endif | ||
| 96 | + | ||
| 89 | 97 | namespace node { | |
| 90 | 98 | ||
| 91 | 99 | using v8::Array; | |
@@ -153,7 +161,7 @@ static double prog_start_time; | |||
| 153 | 161 | static bool debugger_running; | |
| 154 | 162 | static uv_async_t dispatch_debug_messages_async; | |
| 155 | 163 | ||
| 156 | - static Isolate* node_isolate = nullptr; | ||
| 164 | + static node::atomic<Isolate*> node_isolate; | ||
| 157 | 165 | static v8::Platform* default_platform; | |
| 158 | 166 | ||
| 159 | 167 | ||
@@ -3410,28 +3418,46 @@ static void EnableDebug(Environment* env) { | |||
| 3410 | 3418 | } | |
| 3411 | 3419 | ||
| 3412 | 3420 | ||
| 3421 | + // Called from an arbitrary thread. | ||
| 3422 | + static void TryStartDebugger() { | ||
| 3423 | + // Call only async signal-safe functions here! Don't retry the exchange, | ||
| 3424 | + // it will deadlock when the thread is interrupted inside a critical section. | ||
| 3425 | + if (auto isolate = node_isolate.exchange(nullptr)) { | ||
| 3426 | + v8::Debug::DebugBreak(isolate); | ||
| 3427 | + uv_async_send(&dispatch_debug_messages_async); | ||
| 3428 | + CHECK_EQ(nullptr, node_isolate.exchange(isolate)); | ||
| 3429 | + } | ||
| 3430 | + } | ||
| 3431 | + | ||
| 3432 | + | ||
| 3413 | 3433 | // Called from the main thread. | |
| 3414 | 3434 | static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) { | |
| 3435 | + // Synchronize with signal handler, see TryStartDebugger. | ||
| 3436 | + Isolate* isolate; | ||
| 3437 | + do { | ||
| 3438 | + isolate = node_isolate.exchange(nullptr); | ||
| 3439 | + } while (isolate == nullptr); | ||
| 3440 | + | ||
| 3415 | 3441 | if (debugger_running == false) { | |
| 3416 | 3442 | fprintf(stderr, "Starting debugger agent.\n"); | |
| 3417 | 3443 | ||
| 3418 | - HandleScope scope(node_isolate); | ||
| 3419 | - Environment* env = Environment::GetCurrent(node_isolate); | ||
| 3444 | + HandleScope scope(isolate); | ||
| 3445 | + Environment* env = Environment::GetCurrent(isolate); | ||
| 3420 | 3446 | Context::Scope context_scope(env->context()); | |
| 3421 | 3447 | ||
| 3422 | 3448 | StartDebug(env, false); | |
| 3423 | 3449 | EnableDebug(env); | |
| 3424 | 3450 | } | |
| 3425 | - Isolate::Scope isolate_scope(node_isolate); | ||
| 3451 | + | ||
| 3452 | + Isolate::Scope isolate_scope(isolate); | ||
| 3426 | 3453 | v8::Debug::ProcessDebugMessages(); | |
| 3454 | + CHECK_EQ(nullptr, node_isolate.exchange(isolate)); | ||
| 3427 | 3455 | } | |
| 3428 | 3456 | ||
| 3429 | 3457 | ||
| 3430 | 3458 | #ifdef __POSIX__ | |
| 3431 | 3459 | static void EnableDebugSignalHandler(int signo) { | |
| 3432 | - // Call only async signal-safe functions here! | ||
| 3433 | - v8::Debug::DebugBreak(*static_cast<Isolate* volatile*>(&node_isolate)); | ||
| 3434 | - uv_async_send(&dispatch_debug_messages_async); | ||
| 3460 | + TryStartDebugger(); | ||
| 3435 | 3461 | } | |
| 3436 | 3462 | ||
| 3437 | 3463 | ||
@@ -3485,8 +3511,7 @@ static int RegisterDebugSignalHandler() { | |||
| 3485 | 3511 | ||
| 3486 | 3512 | #ifdef _WIN32 | |
| 3487 | 3513 | DWORD WINAPI EnableDebugThreadProc(void* arg) { | |
| 3488 | - v8::Debug::DebugBreak(*static_cast<Isolate* volatile*>(&node_isolate)); | ||
| 3489 | - uv_async_send(&dispatch_debug_messages_async); | ||
| 3514 | + TryStartDebugger(); | ||
| 3490 | 3515 | return 0; | |
| 3491 | 3516 | } | |
| 3492 | 3517 | ||
@@ -4006,7 +4031,8 @@ static void StartNodeInstance(void* arg) { | |||
| 4006 | 4031 | // Fetch a reference to the main isolate, so we have a reference to it | |
| 4007 | 4032 | // even when we need it to access it from another (debugger) thread. | |
| 4008 | 4033 | if (instance_data->is_main()) | |
| 4009 | - node_isolate = isolate; | ||
| 4034 | + CHECK_EQ(nullptr, node_isolate.exchange(isolate)); | ||
| 4035 | + | ||
| 4010 | 4036 | { | |
| 4011 | 4037 | Locker locker(isolate); | |
| 4012 | 4038 | Isolate::Scope isolate_scope(isolate); | |
@@ -4016,7 +4042,7 @@ static void StartNodeInstance(void* arg) { | |||
| 4016 | 4042 | array_buffer_allocator->set_env(env); | |
| 4017 | 4043 | Context::Scope context_scope(context); | |
| 4018 | 4044 | ||
| 4019 | - node_isolate->SetAbortOnUncaughtExceptionCallback( | ||
| 4045 | + isolate->SetAbortOnUncaughtExceptionCallback( | ||
| 4020 | 4046 | ShouldAbortOnUncaughtException); | |
| 4021 | 4047 | ||
| 4022 | 4048 | // Start debug agent when argv has --debug | |
@@ -4070,12 +4096,15 @@ static void StartNodeInstance(void* arg) { | |||
| 4070 | 4096 | env = nullptr; | |
| 4071 | 4097 | } | |
| 4072 | 4098 | ||
| 4099 | + if (instance_data->is_main()) { | ||
| 4100 | + // Synchronize with signal handler, see TryStartDebugger. | ||
| 4101 | + while (isolate != node_isolate.exchange(nullptr)); // NOLINT | ||
| 4102 | + } | ||
| 4103 | + | ||
| 4073 | 4104 | CHECK_NE(isolate, nullptr); | |
| 4074 | 4105 | isolate->Dispose(); | |
| 4075 | 4106 | isolate = nullptr; | |
| 4076 | 4107 | delete array_buffer_allocator; | |
| 4077 | - if (instance_data->is_main()) | ||
| 4078 | - node_isolate = nullptr; | ||
| 4079 | 4108 | } | |
| 4080 | 4109 | ||
| 4081 | 4110 | int Start(int argc, char** argv) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments