| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3bb085d commit 55e94cb
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -60,6 +60,8 @@ static uv_async_t start_io_thread_async; | |||
| 60 | 60 | // This is just an additional check to make sure start_io_thread_async | |
| 61 | 61 | // is not accidentally re-used or used when uninitialized. | |
| 62 | 62 | static std::atomic_bool start_io_thread_async_initialized { false }; | |
| 63 | + // Protects the Agent* stored in start_io_thread_async.data. | ||
| 64 | + static Mutex start_io_thread_async_mutex; | ||
| 63 | 65 | ||
| 64 | 66 | class StartIoTask : public Task { | |
| 65 | 67 | public: | |
@@ -97,6 +99,8 @@ static void StartIoThreadWakeup(int signo) { | |||
| 97 | 99 | inline void* StartIoThreadMain(void* unused) { | |
| 98 | 100 | for (;;) { | |
| 99 | 101 | uv_sem_wait(&start_io_thread_semaphore); | |
| 102 | + Mutex::ScopedLock lock(start_io_thread_async_mutex); | ||
| 103 | + | ||
| 100 | 104 | CHECK(start_io_thread_async_initialized); | |
| 101 | 105 | Agent* agent = static_cast<Agent*>(start_io_thread_async.data); | |
| 102 | 106 | if (agent != nullptr) | |
@@ -157,6 +161,7 @@ static int StartDebugSignalHandler() { | |||
| 157 | 161 | ||
| 158 | 162 | #ifdef _WIN32 | |
| 159 | 163 | DWORD WINAPI StartIoThreadProc(void* arg) { | |
| 164 | + Mutex::ScopedLock lock(start_io_thread_async_mutex); | ||
| 160 | 165 | CHECK(start_io_thread_async_initialized); | |
| 161 | 166 | Agent* agent = static_cast<Agent*>(start_io_thread_async.data); | |
| 162 | 167 | if (agent != nullptr) | |
@@ -748,14 +753,7 @@ Agent::Agent(Environment* env) | |||
| 748 | 753 | debug_options_(env->options()->debug_options()), | |
| 749 | 754 | host_port_(env->inspector_host_port()) {} | |
| 750 | 755 | ||
| 751 | - Agent::~Agent() { | ||
| 752 | - if (start_io_thread_async.data == this) { | ||
| 753 | - CHECK(start_io_thread_async_initialized.exchange(false)); | ||
| 754 | - start_io_thread_async.data = nullptr; | ||
| 755 | - // This is global, will never get freed | ||
| 756 | - uv_close(reinterpret_cast<uv_handle_t*>(&start_io_thread_async), nullptr); | ||
| 757 | - } | ||
| 758 | - } | ||
| 756 | + Agent::~Agent() {} | ||
| 759 | 757 | ||
| 760 | 758 | bool Agent::Start(const std::string& path, | |
| 761 | 759 | const DebugOptions& options, | |
@@ -768,6 +766,7 @@ bool Agent::Start(const std::string& path, | |||
| 768 | 766 | ||
| 769 | 767 | client_ = std::make_shared<NodeInspectorClient>(parent_env_, is_main); | |
| 770 | 768 | if (parent_env_->owns_inspector()) { | |
| 769 | + Mutex::ScopedLock lock(start_io_thread_async_mutex); | ||
| 771 | 770 | CHECK_EQ(start_io_thread_async_initialized.exchange(true), false); | |
| 772 | 771 | CHECK_EQ(0, uv_async_init(parent_env_->event_loop(), | |
| 773 | 772 | &start_io_thread_async, | |
@@ -776,6 +775,20 @@ bool Agent::Start(const std::string& path, | |||
| 776 | 775 | start_io_thread_async.data = this; | |
| 777 | 776 | // Ignore failure, SIGUSR1 won't work, but that should not block node start. | |
| 778 | 777 | StartDebugSignalHandler(); | |
| 778 | + | ||
| 779 | + parent_env_->AddCleanupHook([](void* data) { | ||
| 780 | + Environment* env = static_cast<Environment*>(data); | ||
| 781 | + | ||
| 782 | + { | ||
| 783 | + Mutex::ScopedLock lock(start_io_thread_async_mutex); | ||
| 784 | + start_io_thread_async.data = nullptr; | ||
| 785 | + } | ||
| 786 | + | ||
| 787 | + // This is global, will never get freed | ||
| 788 | + env->CloseHandle(&start_io_thread_async, [](uv_async_t*) { | ||
| 789 | + CHECK(start_io_thread_async_initialized.exchange(false)); | ||
| 790 | + }); | ||
| 791 | + }, parent_env_); | ||
| 779 | 792 | } | |
| 780 | 793 | ||
| 781 | 794 | AtExit(parent_env_, [](void* env) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments