Skip to content

Commit

Permalink
Fix random number generation after fork. (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
rnburn authored Aug 17, 2018
1 parent 9132e0d commit 2644ca2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
30 changes: 27 additions & 3 deletions zipkin/src/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <cstdint>
#include <iterator>
#include <limits>
#include <pthread.h>
#include <random>
#include <string>
#include <vector>
Expand All @@ -16,11 +17,34 @@
#include <zipkin/rapidjson/writer.h>

namespace zipkin {
uint64_t RandomUtil::generateId() {
static thread_local randutils::mt19937_64_rng rand_source;
return rand_source.engine()();
// Wrapper for a seeded random number generator that works with forking.
//
// See https://stackoverflow.com/q/51882689/4447365 and
// https://github.com/opentracing-contrib/nginx-opentracing/issues/52
namespace {
class TlsRandomNumberGenerator {
public:
TlsRandomNumberGenerator() { pthread_atfork(nullptr, nullptr, onFork); }

static std::mt19937_64 &engine() { return base_generator_.engine(); }

private:
static thread_local randutils::mt19937_64_rng base_generator_;

static void onFork() { base_generator_.seed(); }
};

thread_local randutils::mt19937_64_rng
TlsRandomNumberGenerator::base_generator_;
} // namespace

std::mt19937_64 &getTlsRandomEngine() {
static TlsRandomNumberGenerator rng;
return TlsRandomNumberGenerator::engine();
}

uint64_t RandomUtil::generateId() { return getTlsRandomEngine()(); }

bool StringUtil::atoul(const char *str, uint64_t &out, int base) {
if (strlen(str) == 0) {
return false;
Expand Down
5 changes: 3 additions & 2 deletions zipkin_opentracing/src/sampling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
#include <zipkin/randutils/randutils.h>

namespace zipkin {
std::mt19937_64 &getTlsRandomEngine();

bool ProbabilisticSampler::ShouldSample() {
static thread_local randutils::mt19937_rng rng;
std::bernoulli_distribution dist(sample_rate_);
return dist(rng.engine());
return dist(getTlsRandomEngine());
}
} // namespace zipkin

0 comments on commit 2644ca2

Please sign in to comment.