Skip to content

Commit d812dbb

Browse files
addaleaxBridgeAR
authored andcommitted
src: refactor thread stopping mechanism
- Follow style guide for naming, e.g. use lower_snake_case for simple setters/getters. - For performance, use atomics instead of a mutex, and inline the corresponding getter/setter pair. PR-URL: nodejs#26757 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent de3b164 commit d812dbb

File tree

5 files changed

+29
-33
lines changed

5 files changed

+29
-33
lines changed

src/env-inl.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ inline void Environment::remove_sub_worker_context(worker::Worker* context) {
717717
}
718718

719719
inline bool Environment::is_stopping() const {
720-
return thread_stopper_.IsStopped();
720+
return thread_stopper_.is_stopped();
721721
}
722722

723723
inline performance::performance_state* Environment::performance_state() {
@@ -983,6 +983,14 @@ void Environment::ForEachBaseObject(T&& iterator) {
983983
}
984984
}
985985

986+
bool AsyncRequest::is_stopped() const {
987+
return stopped_.load();
988+
}
989+
990+
void AsyncRequest::set_stopped(bool flag) {
991+
stopped_.store(flag);
992+
}
993+
986994
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
987995
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
988996
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)

src/env.cc

+7-22
Original file line numberDiff line numberDiff line change
@@ -319,13 +319,13 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) {
319319
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
320320
uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
321321

322-
GetAsyncRequest()->Install(
322+
thread_stopper()->Install(
323323
this, static_cast<void*>(this), [](uv_async_t* handle) {
324324
Environment* env = static_cast<Environment*>(handle->data);
325325
uv_stop(env->event_loop());
326326
});
327-
GetAsyncRequest()->SetStopped(false);
328-
uv_unref(reinterpret_cast<uv_handle_t*>(GetAsyncRequest()->GetHandle()));
327+
thread_stopper()->set_stopped(false);
328+
uv_unref(reinterpret_cast<uv_handle_t*>(thread_stopper()->GetHandle()));
329329

330330
// Register clean-up cb to be called to clean up the handles
331331
// when the environment is freed, note that they are not cleaned in
@@ -344,7 +344,7 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) {
344344

345345
void Environment::ExitEnv() {
346346
set_can_call_into_js(false);
347-
GetAsyncRequest()->Stop();
347+
thread_stopper()->Stop();
348348
isolate_->TerminateExecution();
349349
}
350350

@@ -512,7 +512,7 @@ void Environment::RunCleanup() {
512512
started_cleanup_ = true;
513513
TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment),
514514
"RunCleanup", this);
515-
GetAsyncRequest()->Uninstall();
515+
thread_stopper()->Uninstall();
516516
CleanupHandles();
517517

518518
while (!cleanup_hooks_.empty()) {
@@ -877,49 +877,34 @@ char* Environment::Reallocate(char* data, size_t old_size, size_t size) {
877877
}
878878

879879
void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) {
880-
Mutex::ScopedLock lock(mutex_);
880+
CHECK_NULL(async_);
881881
env_ = env;
882882
async_ = new uv_async_t;
883883
async_->data = data;
884884
CHECK_EQ(uv_async_init(env_->event_loop(), async_, target), 0);
885885
}
886886

887887
void AsyncRequest::Uninstall() {
888-
Mutex::ScopedLock lock(mutex_);
889888
if (async_ != nullptr) {
890889
env_->CloseHandle(async_, [](uv_async_t* async) { delete async; });
891890
async_ = nullptr;
892891
}
893892
}
894893

895894
void AsyncRequest::Stop() {
896-
Mutex::ScopedLock lock(mutex_);
897-
stop_ = true;
895+
set_stopped(true);
898896
if (async_ != nullptr) uv_async_send(async_);
899897
}
900898

901-
void AsyncRequest::SetStopped(bool flag) {
902-
Mutex::ScopedLock lock(mutex_);
903-
stop_ = flag;
904-
}
905-
906-
bool AsyncRequest::IsStopped() const {
907-
Mutex::ScopedLock lock(mutex_);
908-
return stop_;
909-
}
910-
911899
uv_async_t* AsyncRequest::GetHandle() {
912-
Mutex::ScopedLock lock(mutex_);
913900
return async_;
914901
}
915902

916903
void AsyncRequest::MemoryInfo(MemoryTracker* tracker) const {
917-
Mutex::ScopedLock lock(mutex_);
918904
if (async_ != nullptr) tracker->TrackField("async_request", *async_);
919905
}
920906

921907
AsyncRequest::~AsyncRequest() {
922-
Mutex::ScopedLock lock(mutex_);
923908
CHECK_NULL(async_);
924909
}
925910

src/env.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "uv.h"
3939
#include "v8.h"
4040

41+
#include <atomic>
4142
#include <cstdint>
4243
#include <functional>
4344
#include <list>
@@ -518,18 +519,19 @@ class AsyncRequest : public MemoryRetainer {
518519
void Install(Environment* env, void* data, uv_async_cb target);
519520
void Uninstall();
520521
void Stop();
521-
void SetStopped(bool flag);
522-
bool IsStopped() const;
522+
inline void set_stopped(bool flag);
523+
inline bool is_stopped() const;
523524
uv_async_t* GetHandle();
524525
void MemoryInfo(MemoryTracker* tracker) const override;
526+
527+
525528
SET_MEMORY_INFO_NAME(AsyncRequest)
526529
SET_SELF_SIZE(AsyncRequest)
527530

528531
private:
529532
Environment* env_;
530533
uv_async_t* async_ = nullptr;
531-
mutable Mutex mutex_;
532-
bool stop_ = true;
534+
std::atomic_bool stopped_ {true};
533535
};
534536

535537
class Environment {
@@ -1049,7 +1051,7 @@ class Environment {
10491051
inline ExecutionMode execution_mode() { return execution_mode_; }
10501052

10511053
inline void set_execution_mode(ExecutionMode mode) { execution_mode_ = mode; }
1052-
inline AsyncRequest* GetAsyncRequest() { return &thread_stopper_; }
1054+
inline AsyncRequest* thread_stopper() { return &thread_stopper_; }
10531055

10541056
private:
10551057
inline void CreateImmediate(native_immediate_callback cb,

src/node.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -838,14 +838,14 @@ inline int StartNodeWithIsolate(Isolate* isolate,
838838
per_process::v8_platform.DrainVMTasks(isolate);
839839

840840
more = uv_loop_alive(env.event_loop());
841-
if (more && !env.GetAsyncRequest()->IsStopped()) continue;
841+
if (more && !env.is_stopping()) continue;
842842

843843
RunBeforeExit(&env);
844844

845845
// Emit `beforeExit` if the loop became alive either after emitting
846846
// event, or after running some callbacks.
847847
more = uv_loop_alive(env.event_loop());
848-
} while (more == true && !env.GetAsyncRequest()->IsStopped());
848+
} while (more == true && !env.is_stopping());
849849
env.performance_state()->Mark(
850850
node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
851851
}

src/node_worker.cc

+4-3
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Worker::Worker(Environment* env,
104104
bool Worker::is_stopped() const {
105105
Mutex::ScopedLock lock(mutex_);
106106
if (env_ != nullptr)
107-
return env_->GetAsyncRequest()->IsStopped();
107+
return env_->is_stopping();
108108
return stopped_;
109109
}
110110

@@ -222,7 +222,7 @@ void Worker::Run() {
222222
stopped_ = true;
223223
this->env_ = nullptr;
224224
}
225-
env_->GetAsyncRequest()->SetStopped(true);
225+
env_->thread_stopper()->set_stopped(true);
226226
env_->stop_sub_worker_contexts();
227227
env_->RunCleanup();
228228
RunAtExit(env_.get());
@@ -381,7 +381,8 @@ void Worker::OnThreadStopped() {
381381
Worker::~Worker() {
382382
Mutex::ScopedLock lock(mutex_);
383383

384-
CHECK(stopped_ || env_ == nullptr || env_->GetAsyncRequest()->IsStopped());
384+
CHECK(stopped_);
385+
CHECK_NULL(env_);
385386
CHECK(thread_joined_);
386387

387388
Debug(this, "Worker %llu destroyed", thread_id_);

0 commit comments

Comments
 (0)