Skip to content

Commit 1e03494

Browse files
authored
Merge pull request #2947 from PaulBoersma/master
parallel threads have unique IDs, for error handling
2 parents f4e3033 + 61d7aa2 commit 1e03494

5 files changed

Lines changed: 33 additions & 7 deletions

File tree

melder/MelderThread.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@
1616
* along with this work. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19-
#include "MelderThread.h"
19+
#include "melder.h"
2020

2121
integer MelderThread_getNumberOfProcessors () {
2222
//return 1; // un-comment-out to force single-threading
2323
return Melder_clippedLeft (1_integer, uinteger_to_integer_a (std::thread::hardware_concurrency ()));
2424
}
2525

26-
/* global */ std::thread::id theMelder_error_threadId;
26+
/* global */ std::atomic <integer> theMelder_error_threadId;
27+
28+
integer Melder_thisThread_getUniqueID () {
29+
static std::atomic <integer> uniqueID = 0;
30+
static thread_local integer thisThread_uniqueID = uniqueID ++;
31+
//TRACE
32+
trace (thisThread_uniqueID);
33+
return thisThread_uniqueID;
34+
}
2735

2836
integer MelderThread_computeNumberOfThreads (
2937
const integer numberOfElements,
@@ -90,7 +98,7 @@ void MelderThread_run (
9098
spawns [ispawn0]. join ();
9199
}
92100
if (*p_errorFlag) {
93-
theMelder_error_threadId = std::this_thread::get_id (); // TODO: make this truly unique
101+
theMelder_error_threadId = Melder_thisThread_getUniqueID ();
94102
throw MelderError(); // turn the error flag back into a MelderError
95103
}
96104
}

melder/MelderThread.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ integer MelderThread_computeNumberOfThreads (
3030
bool useRandom
3131
);
3232

33+
/*
34+
The following is a replacement for std::this_thread::get_id(),
35+
which is not guaranteeed to return a unique ID.
36+
37+
A case where this matters is if a throwing thread has finished,
38+
and then a new thread is created with the same idea and quickly throws as well.
39+
Admittedly, this is rare, but it is not impossible and it is easy to prevent it.
40+
*/
41+
integer Melder_thisThread_getUniqueID ();
42+
3343
#define MelderThread_TRY \
3444
try {
3545

melder/melder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <new> // placement new
3434
#include <algorithm> // std::min
3535
#include <limits> // std::numeric_limits<double>::max(), std::numeric_limits<double>::lowest()
36-
#include <thread>
36+
#include <atomic> // std::atomic<integer>
3737

3838
/*
3939
Law of Demeter for class functions defined outside class definition.
@@ -83,6 +83,7 @@
8383

8484
#include "MelderArg.h" // MelderArg (requires Melder_double, MelderFile, Melder_VEC)
8585
#include "MelderString.h" // MelderString_append (requires MelderArg)
86+
#include "MelderThread.h" // Melder_thisThread_getUniqueID
8687
#include "melder_textencoding.h" // Melder_length_utf8, Melder_32to8 (requires MelderString)
8788
#include "melder_debug.h" // trace (requires MelderFile, MelderArg, MelderString), Melder_debug
8889
#include "MelderFile.h" // MelderFile_open (requires MelderFile), MelderFile_write (requires MelderArg)

melder/melder_error.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ conststring32 Melder_getError () {
9393
}
9494

9595
void Melder_appendError_noLine (const MelderArg& arg) {
96+
std::lock_guard lock (theMelder_error_mutex);
97+
if (Melder_hasError ()) {
98+
if (Melder_thisThread_getUniqueID () != theMelder_error_threadId)
99+
return;
100+
} else {
101+
theMelder_error_threadId = Melder_thisThread_getUniqueID ();
102+
}
96103
MelderError::_append (arg._arg);
97104
}
98105

melder/melder_error.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MelderError {
2323
static void _append (conststring32 message);
2424
};
2525
extern std::mutex theMelder_error_mutex;
26-
extern std::thread::id theMelder_error_threadId;
26+
extern std::atomic <integer> theMelder_error_threadId;
2727

2828
bool Melder_hasError ();
2929
bool Melder_hasError (conststring32 partialError);
@@ -70,10 +70,10 @@ template <typename... Args>
7070
void Melder_appendError (const MelderArg& first, Args... rest) {
7171
std::lock_guard lock (theMelder_error_mutex);
7272
if (Melder_hasError ()) {
73-
if (std::this_thread::get_id () != theMelder_error_threadId)
73+
if (Melder_thisThread_getUniqueID () != theMelder_error_threadId)
7474
return;
7575
} else {
76-
theMelder_error_threadId = std::this_thread::get_id ();
76+
theMelder_error_threadId = Melder_thisThread_getUniqueID ();
7777
}
7878
_recursiveTemplate_Melder_appendError (first, rest...);
7979
MelderError::_append (U"\n");

0 commit comments

Comments
 (0)