summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-06-19 18:20:35 +0200
committerStephan Bergmann <sbergman@redhat.com>2019-06-19 21:38:22 +0200
commitce2d4017f11b5afa9ddda1fa7e81d4c710b1c367 (patch)
tree598aeabdd2ad7fd7e98eb8f41659f7c596d00321 /comphelper
parent8f324c74c134101c2fba64c3041a1438aba42c61 (diff)
Lock comphelper::rng internals for multi-threaded access
With `--convert-to pdf xlsx/tdf116206-1.xlsx` with xlsx/tdf116206-1.xlsx as obtained by bin/get-bugzilla-attachments-by-mimetype (i.e., the attachment "Example file with lots of random data" at <https://bugs.documentfoundation.org/show_bug.cgi?id=116206#c0>), my ASan+UBSan build will eventually fail with > .../include/c++/10.0.0/bits/random.tcc:461:25: runtime error: index 624 out of bounds for type 'unsigned long [624]' > #0 in std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>::operator()() at .../include/c++/10.0.0/bits/random.tcc:461:25 > #1 in double std::generate_canonical<double, 53ul, std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&) at .../include/c++/10.0.0/bits/random.tcc:3336:23 > #2 in std::__detail::_Adaptor<std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>, double>::operator()() at .../include/c++/10.0.0/bits/random.h:179:11 > #3 in double std::uniform_real_distribution<double>::operator()<std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&, std::uniform_real_distribution<double>::param_type const&) at .../include/c++/10.0.0/bits/random.h:1857:12 > #4 in double std::uniform_real_distribution<double>::operator()<std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&) at .../include/c++/10.0.0/bits/random.h:1848:24 > #5 in comphelper::rng::uniform_real_distribution(double, double) at comphelper/source/misc/random.cxx:104:12 > #6 in ScInterpreter::ScRandom() at sc/source/core/tool/interpr1.cxx:1768:21 > #7 in ScInterpreter::Interpret() at sc/source/core/tool/interpr4.cxx:4026:43 > #8 in ScFormulaCell::InterpretTail(ScInterpreterContext&, ScFormulaCell::ScInterpretTailParameter) at sc/source/core/data/formulacell.cxx:1905:23 > #9 in ScColumn::CalculateInThread(ScInterpreterContext&, int, unsigned long, unsigned int, unsigned int) at sc/source/core/data/column2.cxx:2964:15 > #10 in ScTable::CalculateInColumnInThread(ScInterpreterContext&, short, int, unsigned long, unsigned int, unsigned int) at sc/source/core/data/table1.cxx:2476:16 > #11 in ScDocument::CalculateInColumnInThread(ScInterpreterContext&, ScAddress const&, unsigned long, unsigned int, unsigned int) at sc/source/core/data/documen8.cxx:422:11 > #12 in ScFormulaCell::InterpretFormulaGroupThreading(sc::FormulaLogger::GroupScope&, bool&, bool&, int, int)::Executor::doWork() at sc/source/core/data/formulacell.cxx:4714:29 > #13 in comphelper::ThreadTask::exec() at comphelper/source/misc/threadpool.cxx:279:9 > #14 in comphelper::ThreadPool::ThreadWorker::execute() at comphelper/source/misc/threadpool.cxx:83:24 > #15 in salhelper::Thread::run() at salhelper/source/thread.cxx:40:9 [...] suggesting that there is racy concurrent access to the internals of singleton std::mt19937 comphelper::rng::RandomNumberGenerator::global_rng. Change-Id: I8209b3903918c567fc832abbb84c8fbcc08e444b Reviewed-on: https://gerrit.libreoffice.org/74368 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/source/misc/random.cxx18
1 files changed, 14 insertions, 4 deletions
diff --git a/comphelper/source/misc/random.cxx b/comphelper/source/misc/random.cxx
index bfb4de15aee5..ddc970efe321 100644
--- a/comphelper/source/misc/random.cxx
+++ b/comphelper/source/misc/random.cxx
@@ -15,6 +15,7 @@
#include <sal/log.hxx>
#include <assert.h>
#include <time.h>
+#include <mutex>
#include <random>
#include <stdexcept>
#if defined HAVE_VALGRIND_HEADERS
@@ -39,6 +40,7 @@ namespace rng
struct RandomNumberGenerator
{
+ std::mutex mutex;
STD_RNG_ALGO global_rng;
RandomNumberGenerator()
{
@@ -79,21 +81,27 @@ class theRandomNumberGenerator : public rtl::Static<RandomNumberGenerator, theRa
int uniform_int_distribution(int a, int b)
{
std::uniform_int_distribution<int> dist(a, b);
- return dist(theRandomNumberGenerator::get().global_rng);
+ auto & gen = theRandomNumberGenerator::get();
+ std::scoped_lock<std::mutex> g(gen.mutex);
+ return dist(gen.global_rng);
}
// uniform ints [a,b] distribution
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
{
std::uniform_int_distribution<unsigned int> dist(a, b);
- return dist(theRandomNumberGenerator::get().global_rng);
+ auto & gen = theRandomNumberGenerator::get();
+ std::scoped_lock<std::mutex> g(gen.mutex);
+ return dist(gen.global_rng);
}
// uniform size_t [a,b] distribution
size_t uniform_size_distribution(size_t a, size_t b)
{
std::uniform_int_distribution<size_t> dist(a, b);
- return dist(theRandomNumberGenerator::get().global_rng);
+ auto & gen = theRandomNumberGenerator::get();
+ std::scoped_lock<std::mutex> g(gen.mutex);
+ return dist(gen.global_rng);
}
// uniform size_t [a,b) distribution
@@ -101,7 +109,9 @@ double uniform_real_distribution(double a, double b)
{
assert(a < b);
std::uniform_real_distribution<double> dist(a, b);
- return dist(theRandomNumberGenerator::get().global_rng);
+ auto & gen = theRandomNumberGenerator::get();
+ std::scoped_lock<std::mutex> g(gen.mutex);
+ return dist(gen.global_rng);
}
} // namespace