Skip to content

Commit 4a97423

Browse files
committed
Safe atomics, take 2
1 parent 1e2ed00 commit 4a97423

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

bindings/profilers/wall.cc

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <atomic>
1818
#include <cstdint>
1919
#include <memory>
20+
#include <mutex>
2021
#include <vector>
2122

2223
#include <nan.h>
@@ -39,6 +40,7 @@ namespace dd {
3940
using ProfilerMap = std::unordered_map<Isolate*, WallProfiler*>;
4041

4142
static std::atomic<ProfilerMap*> profilers(new ProfilerMap());
43+
static std::mutex update_profilers;
4244

4345
#ifdef DD_WALL_USE_SIGPROF
4446
static void (*old_handler)(int, siginfo_t*, void*) = nullptr;
@@ -391,21 +393,24 @@ WallProfiler::~WallProfiler() {
391393

392394
template <typename F>
393395
void updateProfilers(F updateFn) {
396+
std::lock_guard<std::mutex> lock(update_profilers);
394397
auto currProfilers = profilers.load(std::memory_order_acquire);
398+
// Wait until sighandler is done using the map
399+
while (!currProfilers) {
400+
currProfilers = profilers.load(std::memory_order_relaxed);
401+
}
402+
auto newProfilers = new ProfilerMap(*currProfilers);
403+
updateFn(newProfilers);
404+
// Wait until sighandler is done using the map before installing a new map.
405+
// The value in profilers is either nullptr or currProfilers.
395406
for (;;) {
396-
while (!currProfilers) {
397-
currProfilers = profilers.load(std::memory_order_relaxed);
398-
}
399-
auto newProfilers = new ProfilerMap(*currProfilers);
400-
updateFn(newProfilers);
407+
ProfilerMap* currProfilers2 = currProfilers;
401408
if (profilers.compare_exchange_weak(
402-
currProfilers, newProfilers, std::memory_order_acq_rel)) {
403-
delete currProfilers;
409+
currProfilers2, newProfilers, std::memory_order_acq_rel)) {
404410
break;
405-
} else {
406-
delete newProfilers;
407411
}
408412
}
413+
delete currProfilers;
409414
}
410415

411416
void WallProfiler::Dispose(Isolate* isolate) {

0 commit comments

Comments
 (0)