Skip to content

Commit deed1e3

Browse files
authored
[SDK] Fix memory leak in TlsRandomNumberGenerator() constructor (open-telemetry#2661)
1 parent 4520aa5 commit deed1e3

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

sdk/src/common/random.cc

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "src/common/random.h"
66
#include "src/common/platform/fork.h"
77

8+
#include <atomic>
89
#include <cstring>
910
#include <random>
1011

@@ -26,12 +27,17 @@ class TlsRandomNumberGenerator
2627
TlsRandomNumberGenerator() noexcept
2728
{
2829
Seed();
29-
platform::AtFork(nullptr, nullptr, OnFork);
30+
if (!flag.test_and_set())
31+
{
32+
platform::AtFork(nullptr, nullptr, OnFork);
33+
}
3034
}
3135

3236
static FastRandomNumberGenerator &engine() noexcept { return engine_; }
3337

3438
private:
39+
static std::atomic_flag flag;
40+
3541
static thread_local FastRandomNumberGenerator engine_;
3642

3743
static void OnFork() noexcept { Seed(); }
@@ -44,6 +50,7 @@ class TlsRandomNumberGenerator
4450
}
4551
};
4652

53+
std::atomic_flag TlsRandomNumberGenerator::flag;
4754
thread_local FastRandomNumberGenerator TlsRandomNumberGenerator::engine_{};
4855
} // namespace
4956

sdk/test/common/random_test.cc

+27
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
#include "src/common/random.h"
55

66
#include <algorithm>
7+
#include <atomic>
78
#include <iterator>
9+
#include <thread>
10+
#include <vector>
811

912
#include <gtest/gtest.h>
1013
using opentelemetry::sdk::common::Random;
@@ -34,3 +37,27 @@ TEST(RandomTest, GenerateRandomBuffer)
3437
std::equal(std::begin(buf1_vector), std::end(buf1_vector), std::begin(buf2_vector)));
3538
}
3639
}
40+
41+
void doSomethingOnce(std::atomic_uint *count)
42+
{
43+
static std::atomic_flag flag;
44+
if (!flag.test_and_set())
45+
{
46+
(*count)++;
47+
}
48+
}
49+
50+
TEST(RandomTest, AtomicFlagMultiThreadTest)
51+
{
52+
std::vector<std::thread> threads;
53+
std::atomic_uint count(0);
54+
for (int i = 0; i < 10; ++i)
55+
{
56+
threads.push_back(std::thread(doSomethingOnce, &count));
57+
}
58+
for (auto &t : threads)
59+
{
60+
t.join();
61+
}
62+
EXPECT_EQ(1, count.load());
63+
}

0 commit comments

Comments
 (0)