Commit a4ceb6a28f57dee5ce2e8fe4c4ce8fce43c6b83d
1 parent
d16f9df0
Clarify use of Common::seedRNG
Common::seedRNG uses a static variable to ensure that the RNG is seeded exactly once per run of OpenBR. In spite of this, seedRNG was called from several places, although the function would have an effect exactly once. This commit adds thread safety to seedRNG (previously the use of a static variable was unsafe, although it could only cause a rather minor problem). More importantly call seedRNG only from Context::initialize. If it is desirable to call seedRNG more than once, changes will need to be made to support doing that in a meaningful way.
Showing
3 changed files
with
6 additions
and
5 deletions
openbr/core/common.cpp
| @@ -15,11 +15,15 @@ | @@ -15,11 +15,15 @@ | ||
| 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 15 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| 16 | 16 | ||
| 17 | #include "common.h" | 17 | #include "common.h" |
| 18 | +#include <QMutex> | ||
| 18 | 19 | ||
| 19 | using namespace std; | 20 | using namespace std; |
| 20 | 21 | ||
| 21 | /**** GLOBAL ****/ | 22 | /**** GLOBAL ****/ |
| 22 | void Common::seedRNG() { | 23 | void Common::seedRNG() { |
| 24 | + static QMutex seedControl; | ||
| 25 | + QMutexLocker lock(&seedControl); | ||
| 26 | + | ||
| 23 | static bool seeded = false; | 27 | static bool seeded = false; |
| 24 | if (!seeded) { | 28 | if (!seeded) { |
| 25 | srand(0); // We seed with 0 instead of time(NULL) to have reproducible randomness | 29 | srand(0); // We seed with 0 instead of time(NULL) to have reproducible randomness |
| @@ -29,8 +33,6 @@ void Common::seedRNG() { | @@ -29,8 +33,6 @@ void Common::seedRNG() { | ||
| 29 | 33 | ||
| 30 | QList<int> Common::RandSample(int n, int max, int min, bool unique) | 34 | QList<int> Common::RandSample(int n, int max, int min, bool unique) |
| 31 | { | 35 | { |
| 32 | - seedRNG(); | ||
| 33 | - | ||
| 34 | QList<int> samples; samples.reserve(n); | 36 | QList<int> samples; samples.reserve(n); |
| 35 | int range = max-min; | 37 | int range = max-min; |
| 36 | if (range <= 0) qFatal("Non-positive range."); | 38 | if (range <= 0) qFatal("Non-positive range."); |
| @@ -50,8 +52,6 @@ QList<int> Common::RandSample(int n, int max, int min, bool unique) | @@ -50,8 +52,6 @@ QList<int> Common::RandSample(int n, int max, int min, bool unique) | ||
| 50 | 52 | ||
| 51 | QList<int> Common::RandSample(int n, const QSet<int> &values, bool unique) | 53 | QList<int> Common::RandSample(int n, const QSet<int> &values, bool unique) |
| 52 | { | 54 | { |
| 53 | - seedRNG(); | ||
| 54 | - | ||
| 55 | QList<int> valueList = values.toList(); | 55 | QList<int> valueList = values.toList(); |
| 56 | if (unique && (values.size() <= n)) return valueList; | 56 | if (unique && (values.size() <= n)) return valueList; |
| 57 | 57 |
openbr/openbr_plugin.cpp
| @@ -891,6 +891,8 @@ void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_ | @@ -891,6 +891,8 @@ void br::Context::initialize(int &argc, char *argv[], QString sdkPath, bool use_ | ||
| 891 | 891 | ||
| 892 | qInstallMessageHandler(messageHandler); | 892 | qInstallMessageHandler(messageHandler); |
| 893 | 893 | ||
| 894 | + Common::seedRNG(); | ||
| 895 | + | ||
| 894 | // Search for SDK | 896 | // Search for SDK |
| 895 | if (sdkPath.isEmpty()) { | 897 | if (sdkPath.isEmpty()) { |
| 896 | QStringList checkPaths; checkPaths << QDir::currentPath() << QCoreApplication::applicationDirPath(); | 898 | QStringList checkPaths; checkPaths << QDir::currentPath() << QCoreApplication::applicationDirPath(); |
openbr/plugins/independent.cpp
| @@ -35,7 +35,6 @@ static TemplateList Downsample(const TemplateList &templates, int classes, int i | @@ -35,7 +35,6 @@ static TemplateList Downsample(const TemplateList &templates, int classes, int i | ||
| 35 | if ((classes != std::numeric_limits<int>::max()) && (uniqueLabels.size() < classes)) | 35 | if ((classes != std::numeric_limits<int>::max()) && (uniqueLabels.size() < classes)) |
| 36 | qWarning("Downsample requested %d classes but only %d are available.", classes, uniqueLabels.size()); | 36 | qWarning("Downsample requested %d classes but only %d are available.", classes, uniqueLabels.size()); |
| 37 | 37 | ||
| 38 | - Common::seedRNG(); | ||
| 39 | QList<QString> selectedLabels = uniqueLabels; | 38 | QList<QString> selectedLabels = uniqueLabels; |
| 40 | if (classes < uniqueLabels.size()) { | 39 | if (classes < uniqueLabels.size()) { |
| 41 | std::random_shuffle(selectedLabels.begin(), selectedLabels.end()); | 40 | std::random_shuffle(selectedLabels.begin(), selectedLabels.end()); |