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 {
3940using ProfilerMap = std::unordered_map<Isolate*, WallProfiler*>;
4041
4142static std::atomic<ProfilerMap*> profilers (new ProfilerMap());
43+ static std::mutex update_profilers;
4244
4345#ifdef DD_WALL_USE_SIGPROF
4446static void (*old_handler)(int , siginfo_t *, void *) = nullptr;
@@ -391,21 +393,24 @@ WallProfiler::~WallProfiler() {
391393
392394template <typename F>
393395void 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
411416void WallProfiler::Dispose (Isolate* isolate) {
0 commit comments