Skip to content

Commit

Permalink
fix: use portable C++ RNG
Browse files Browse the repository at this point in the history
I used "A Tour of C++, Third Edition" (ISBN-10 0136816487) as inspiration for the Random class.
This replaces all occurrences of `rand()` and `srand()`.
  • Loading branch information
bryanhonof committed Oct 1, 2024
1 parent 14f029d commit dfd1ce7
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 9 deletions.
5 changes: 0 additions & 5 deletions src/libmain/shared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ void initNix(bool loadConfig)
/* Initialise the PRNG. */
struct timeval tv;
gettimeofday(&tv, 0);
#ifndef _WIN32
srandom(tv.tv_usec);
#endif
srand(tv.tv_usec);


}

Expand Down
3 changes: 2 additions & 1 deletion src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "topo-sort.hh"
#include "callback.hh"
#include "local-store.hh" // TODO remove, along with remaining downcasts
#include "random.hh"

#include <regex>
#include <queue>
Expand Down Expand Up @@ -803,7 +804,7 @@ void replaceValidPath(const Path & storePath, const Path & tmpPath)
tmpPath (the replacement), so we have to move it out of the
way first. We'd better not be interrupted here, because if
we're repairing (say) Glibc, we end up with a broken system. */
Path oldPath = fmt("%1%.old-%2%-%3%", storePath, getpid(), rand());
Path oldPath = fmt("%1%.old-%2%-%3%", storePath, getpid(), Random{}());
if (pathExists(storePath))
movePath(storePath, oldPath);

Expand Down
3 changes: 2 additions & 1 deletion src/libstore/indirect-root-store.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "indirect-root-store.hh"
#include "random.hh"

namespace nix {

Expand All @@ -8,7 +9,7 @@ void IndirectRootStore::makeSymlink(const Path & link, const Path & target)
createDirs(dirOf(link));

/* Create the new symlink. */
Path tempLink = fmt("%1%.tmp-%2%-%3%", link, getpid(), rand());
Path tempLink = fmt("%1%.tmp-%2%-%3%", link, getpid(), Random{}());
createSymlink(target, tempLink);

/* Atomically replace the old one. */
Expand Down
3 changes: 2 additions & 1 deletion src/libstore/optimise-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "signals.hh"
#include "posix-fs-canonicalise.hh"
#include "posix-source-accessor.hh"
#include "random.hh"

#include <cstdlib>
#include <cstring>
Expand Down Expand Up @@ -222,7 +223,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
its timestamp back to 0. */
MakeReadOnly makeReadOnly(mustToggle ? dirOfPath : "");

std::filesystem::path tempLink = fmt("%1%/.tmp-link-%2%-%3%", realStoreDir, getpid(), rand());
std::filesystem::path tempLink = fmt("%1%/.tmp-link-%2%-%3%", realStoreDir, getpid(), Random{}());

try {
std::filesystem::create_hard_link(linkPath, tempLink);
Expand Down
3 changes: 2 additions & 1 deletion src/libstore/sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "util.hh"
#include "url.hh"
#include "signals.hh"
#include "random.hh"

#include <sqlite3.h>

Expand Down Expand Up @@ -258,7 +259,7 @@ void handleSQLiteBusy(const SQLiteBusy & e, time_t & nextWarning)
is likely to fail again. */
checkInterrupt();
/* <= 0.1s */
std::this_thread::sleep_for(std::chrono::milliseconds { rand() % 100 });
std::this_thread::sleep_for(std::chrono::milliseconds { Random{0, 100}() });
}

}
1 change: 1 addition & 0 deletions src/libutil/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ headers = [config_h] + files(
'util.hh',
'variant-wrapper.hh',
'xml-writer.hh',
'random.hh'
)

if host_machine.system() == 'linux'
Expand Down
28 changes: 28 additions & 0 deletions src/libutil/random.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <random>
#include <limits>

namespace nix {

// Inspired by the book "A Tour of C++, Third Edition" (ISBN-10 0136816487)
class Random
{
public:
Random(int low = std::numeric_limits<int>::min(), int high = std::numeric_limits<int>::max())
: re(std::random_device{}())
, dist(low, high){};
int operator()()
{
return dist(re);
}
void seed(int s)
{
re.seed(s);
}
private:
std::default_random_engine re;
std::uniform_int_distribution<int> dist;
};

} // namespace nix

0 comments on commit dfd1ce7

Please sign in to comment.