Commit a4ceb6a28f57dee5ce2e8fe4c4ce8fce43c6b83d

Authored by Charles Otto
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.
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&lt;int&gt; Common::RandSample(int n, int max, int min, bool unique) @@ -50,8 +52,6 @@ QList&lt;int&gt; 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 &amp;argc, char *argv[], QString sdkPath, bool use_ @@ -891,6 +891,8 @@ void br::Context::initialize(int &amp;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 &amp;templates, int classes, int i @@ -35,7 +35,6 @@ static TemplateList Downsample(const TemplateList &amp;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());