@@ -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
@@ -1074,10 +1107,15 @@ Local<Value> WallProfiler::GetContext(Isolate* isolate) {
1074
1107
return Undefined (isolate);
1075
1108
}
1076
1109
1110
+ void WallProfiler::SetCurrentContextPtr (Isolate* isolate, Local<Value> value) {
1111
+ SignalMutex m (setInProgress_);
1112
+ SetContextPtr (curContext_, isolate, value);
1113
+ }
1114
+
1077
1115
void WallProfiler::SetContext (Isolate* isolate, Local<Value> value) {
1078
1116
#if NODE_MAJOR_VERSION >= 23
1079
1117
if (!useCPED_) {
1080
- curContext_. Set (isolate, value);
1118
+ SetCurrentContextPtr (isolate, value);
1081
1119
return ;
1082
1120
}
1083
1121
@@ -1103,15 +1141,12 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1103
1141
1104
1142
PersistentContextPtr* contextPtr = nullptr ;
1105
1143
auto profData = maybeProfData.ToLocalChecked ();
1144
+ SignalMutex m (setInProgress_);
1106
1145
if (profData->IsUndefined ()) {
1107
1146
contextPtr = new PersistentContextPtr (&deadContextPtrs_);
1108
1147
1109
1148
auto external = External::New (isolate, contextPtr);
1110
- setInProgress_.store (true , std::memory_order_relaxed);
1111
- std::atomic_signal_fence (std::memory_order_release);
1112
1149
auto maybeSetResult = cpedObj->SetPrivate (v8Ctx, localSymbol, external);
1113
- std::atomic_signal_fence (std::memory_order_release);
1114
- setInProgress_.store (false , std::memory_order_relaxed);
1115
1150
if (maybeSetResult.IsNothing ()) {
1116
1151
delete contextPtr;
1117
1152
return ;
@@ -1125,7 +1160,7 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1125
1160
1126
1161
contextPtr->Set (isolate, value);
1127
1162
#else
1128
- curContext_. Set (isolate, value);
1163
+ SetCurrentContextPtr (isolate, value);
1129
1164
#endif
1130
1165
}
1131
1166
@@ -1152,7 +1187,7 @@ ContextPtr WallProfiler::GetContextPtrSignalSafe(Isolate* isolate) {
1152
1187
ContextPtr WallProfiler::GetContextPtr (Isolate* isolate) {
1153
1188
#if NODE_MAJOR_VERSION >= 23
1154
1189
if (!useCPED_) {
1155
- return curContext_. Get () ;
1190
+ return curContext_;
1156
1191
}
1157
1192
1158
1193
if (!isolate->IsInUse ()) {
@@ -1180,7 +1215,7 @@ ContextPtr WallProfiler::GetContextPtr(Isolate* isolate) {
1180
1215
}
1181
1216
return ContextPtr ();
1182
1217
#else
1183
- return curContext_. Get () ;
1218
+ return curContext_;
1184
1219
#endif
1185
1220
}
1186
1221
0 commit comments