@@ -58,6 +58,20 @@ using namespace v8;
58
58
59
59
namespace dd {
60
60
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
+
61
75
// Maximum number of rounds in the GetV8ToEpochOffset
62
76
static constexpr int MAX_EPOCH_OFFSET_ATTEMPTS = 20 ;
63
77
@@ -620,7 +634,18 @@ void WallProfiler::Dispose(Isolate* isolate, bool removeFromMap) {
620
634
}
621
635
}
622
636
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;
624
649
std::vector<PersistentContextPtr*>* dead;
625
650
Persistent<Object> per;
626
651
@@ -648,6 +673,14 @@ class PersistentContextPtr : AtomicContextPtr {
648
673
WeakCallbackType::kParameter );
649
674
}
650
675
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
+
651
684
friend class WallProfiler ;
652
685
};
653
686
@@ -1073,10 +1106,15 @@ Local<Value> WallProfiler::GetContext(Isolate* isolate) {
1073
1106
return Undefined (isolate);
1074
1107
}
1075
1108
1109
+ void WallProfiler::SetCurrentContextPtr (Isolate* isolate, Local<Value> value) {
1110
+ SignalMutex m (setInProgress_);
1111
+ SetContextPtr (curContext_, isolate, value);
1112
+ }
1113
+
1076
1114
void WallProfiler::SetContext (Isolate* isolate, Local<Value> value) {
1077
1115
#if NODE_MAJOR_VERSION >= 23
1078
1116
if (!useCPED_) {
1079
- curContext_. Set (isolate, value);
1117
+ SetCurrentContextPtr (isolate, value);
1080
1118
return ;
1081
1119
}
1082
1120
@@ -1102,15 +1140,12 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1102
1140
1103
1141
PersistentContextPtr* contextPtr = nullptr ;
1104
1142
auto profData = maybeProfData.ToLocalChecked ();
1143
+ SignalMutex m (setInProgress_);
1105
1144
if (profData->IsUndefined ()) {
1106
1145
contextPtr = new PersistentContextPtr (&deadContextPtrs_);
1107
1146
1108
1147
auto external = External::New (isolate, contextPtr);
1109
- setInProgress_.store (true , std::memory_order_relaxed);
1110
- std::atomic_signal_fence (std::memory_order_release);
1111
1148
auto maybeSetResult = cpedObj->SetPrivate (v8Ctx, localSymbol, external);
1112
- std::atomic_signal_fence (std::memory_order_release);
1113
- setInProgress_.store (false , std::memory_order_relaxed);
1114
1149
if (maybeSetResult.IsNothing ()) {
1115
1150
delete contextPtr;
1116
1151
return ;
@@ -1124,7 +1159,7 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1124
1159
1125
1160
contextPtr->Set (isolate, value);
1126
1161
#else
1127
- curContext_. Set (isolate, value);
1162
+ SetCurrentContextPtr (isolate, value);
1128
1163
#endif
1129
1164
}
1130
1165
@@ -1151,7 +1186,7 @@ ContextPtr WallProfiler::GetContextPtrSignalSafe(Isolate* isolate) {
1151
1186
ContextPtr WallProfiler::GetContextPtr (Isolate* isolate) {
1152
1187
#if NODE_MAJOR_VERSION >= 23
1153
1188
if (!useCPED_) {
1154
- return curContext_. Get () ;
1189
+ return curContext_;
1155
1190
}
1156
1191
1157
1192
if (!isolate->IsInUse ()) {
@@ -1179,7 +1214,7 @@ ContextPtr WallProfiler::GetContextPtr(Isolate* isolate) {
1179
1214
}
1180
1215
return ContextPtr ();
1181
1216
#else
1182
- return curContext_. Get () ;
1217
+ return curContext_;
1183
1218
#endif
1184
1219
}
1185
1220
0 commit comments