Skip to content

Commit 9ae8154

Browse files
committed
Remove AtomicContextPtr in favor of setInProgress_
1 parent 79114c1 commit 9ae8154

File tree

2 files changed

+47
-43
lines changed

2 files changed

+47
-43
lines changed

bindings/profilers/wall.cc

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,20 @@ using namespace v8;
5858

5959
namespace dd {
6060

61+
class SignalMutex {
62+
std::atomic<bool>& mutex_;
63+
64+
inline void store(bool value) {
65+
std::atomic_signal_fence(std::memory_order_release);
66+
mutex_.store(value, std::memory_order_relaxed);
67+
}
68+
69+
public:
70+
inline SignalMutex(std::atomic<bool>& mutex) : mutex_(mutex) { store(true); }
71+
72+
inline ~SignalMutex() { store(false); }
73+
};
74+
6175
// Maximum number of rounds in the GetV8ToEpochOffset
6276
static constexpr int MAX_EPOCH_OFFSET_ATTEMPTS = 20;
6377

@@ -620,7 +634,18 @@ void WallProfiler::Dispose(Isolate* isolate, bool removeFromMap) {
620634
}
621635
}
622636

623-
class PersistentContextPtr : AtomicContextPtr {
637+
void SetContextPtr(ContextPtr& contextPtr,
638+
Isolate* isolate,
639+
Local<Value> value) {
640+
if (contextPtr) {
641+
contextPtr = std::make_shared<Global<Value>>(isolate, value);
642+
} else {
643+
contextPtr.reset();
644+
}
645+
}
646+
647+
class PersistentContextPtr {
648+
ContextPtr context;
624649
std::vector<PersistentContextPtr*>* dead;
625650
Persistent<Object> per;
626651

@@ -648,6 +673,14 @@ class PersistentContextPtr : AtomicContextPtr {
648673
WeakCallbackType::kParameter);
649674
}
650675

676+
void Set(Isolate* isolate, const Local<Value>& value) {
677+
SetContextPtr(context, isolate, value);
678+
}
679+
680+
ContextPtr Get() const {
681+
return context;
682+
}
683+
651684
friend class WallProfiler;
652685
};
653686

@@ -1073,10 +1106,15 @@ Local<Value> WallProfiler::GetContext(Isolate* isolate) {
10731106
return Undefined(isolate);
10741107
}
10751108

1109+
void WallProfiler::SetCurrentContextPtr(Isolate* isolate, Local<Value> value) {
1110+
SignalMutex m(setInProgress_);
1111+
SetContextPtr(curContext_, isolate, value);
1112+
}
1113+
10761114
void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
10771115
#if NODE_MAJOR_VERSION >= 23
10781116
if (!useCPED_) {
1079-
curContext_.Set(isolate, value);
1117+
SetCurrentContextPtr(isolate, value);
10801118
return;
10811119
}
10821120

@@ -1102,15 +1140,12 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
11021140

11031141
PersistentContextPtr* contextPtr = nullptr;
11041142
auto profData = maybeProfData.ToLocalChecked();
1143+
SignalMutex m(setInProgress_);
11051144
if (profData->IsUndefined()) {
11061145
contextPtr = new PersistentContextPtr(&deadContextPtrs_);
11071146

11081147
auto external = External::New(isolate, contextPtr);
1109-
setInProgress_.store(true, std::memory_order_relaxed);
1110-
std::atomic_signal_fence(std::memory_order_release);
11111148
auto maybeSetResult = cpedObj->SetPrivate(v8Ctx, localSymbol, external);
1112-
std::atomic_signal_fence(std::memory_order_release);
1113-
setInProgress_.store(false, std::memory_order_relaxed);
11141149
if (maybeSetResult.IsNothing()) {
11151150
delete contextPtr;
11161151
return;
@@ -1124,7 +1159,7 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
11241159

11251160
contextPtr->Set(isolate, value);
11261161
#else
1127-
curContext_.Set(isolate, value);
1162+
SetCurrentContextPtr(isolate, value);
11281163
#endif
11291164
}
11301165

@@ -1151,7 +1186,7 @@ ContextPtr WallProfiler::GetContextPtrSignalSafe(Isolate* isolate) {
11511186
ContextPtr WallProfiler::GetContextPtr(Isolate* isolate) {
11521187
#if NODE_MAJOR_VERSION >= 23
11531188
if (!useCPED_) {
1154-
return curContext_.Get();
1189+
return curContext_;
11551190
}
11561191

11571192
if (!isolate->IsInUse()) {
@@ -1179,7 +1214,7 @@ ContextPtr WallProfiler::GetContextPtr(Isolate* isolate) {
11791214
}
11801215
return ContextPtr();
11811216
#else
1182-
return curContext_.Get();
1217+
return curContext_;
11831218
#endif
11841219
}
11851220

bindings/profilers/wall.hh

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,39 +38,6 @@ struct Result {
3838

3939
using ContextPtr = std::shared_ptr<v8::Global<v8::Value>>;
4040

41-
/**
42-
* Class that allows atomic updates to a ContextPtr. Since update of shared_ptr
43-
* is not atomic, we use a pointer that alternates between pointing to one of
44-
* two shared_ptrs instead, and we use atomic operations to update the pointer.
45-
*/
46-
class AtomicContextPtr {
47-
ContextPtr ptr1;
48-
ContextPtr ptr2;
49-
std::atomic<ContextPtr*> currentPtr = &ptr1;
50-
51-
void Set(v8::Isolate* isolate, v8::Local<v8::Value> value) {
52-
auto oldPtr = currentPtr.load(std::memory_order_relaxed);
53-
std::atomic_signal_fence(std::memory_order_acquire);
54-
auto newPtr = oldPtr == &ptr1 ? &ptr2 : &ptr1;
55-
if (!value->IsNullOrUndefined()) {
56-
*newPtr = std::make_shared<v8::Global<v8::Value>>(isolate, value);
57-
} else {
58-
newPtr->reset();
59-
}
60-
std::atomic_signal_fence(std::memory_order_release);
61-
currentPtr.store(newPtr, std::memory_order_relaxed);
62-
std::atomic_signal_fence(std::memory_order_release);
63-
}
64-
65-
ContextPtr Get() {
66-
auto ptr = currentPtr.load(std::memory_order_relaxed);
67-
std::atomic_signal_fence(std::memory_order_acquire);
68-
return ptr ? *ptr : ContextPtr();
69-
}
70-
71-
friend class WallProfiler;
72-
};
73-
7441
class PersistentContextPtr;
7542

7643
class WallProfiler : public Nan::ObjectWrap {
@@ -85,7 +52,7 @@ class WallProfiler : public Nan::ObjectWrap {
8552

8653
bool useCPED_ = false;
8754
// If we aren't using the CPED, we use a single context ptr stored here.
88-
AtomicContextPtr curContext_;
55+
ContextPtr curContext_;
8956
// Otherwise we'll use a private symbol to store the context in CPED objects.
9057
v8::Global<v8::Private> cpedSymbol_;
9158
// We track live context pointers in a set to avoid memory leaks. They will
@@ -151,6 +118,8 @@ class WallProfiler : public Nan::ObjectWrap {
151118
ContextPtr GetContextPtr(v8::Isolate* isolate);
152119
ContextPtr GetContextPtrSignalSafe(v8::Isolate* isolate);
153120

121+
void SetCurrentContextPtr(v8::Isolate* isolate, v8::Local<v8::Value> context);
122+
154123
public:
155124
/**
156125
* @param samplingPeriodMicros sampling interval, in microseconds

0 commit comments

Comments
 (0)