Skip to content

Commit 38a5e12

Browse files
Fix build issues on Mac by removing jthread
1 parent c42c2c8 commit 38a5e12

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

include/bioimage_cpp/detail/threading.hxx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ inline std::size_t normalize_thread_count(
3030

3131
// Split [0, number_of_work_items) into n_threads contiguous chunks and invoke
3232
// `chunk(thread_id, begin, end)` on each chunk. Thread 0 runs on the calling
33-
// thread; threads 1..n_threads-1 run in parallel std::jthreads. The caller is
33+
// thread; threads 1..n_threads-1 run in parallel std::threads. The caller is
3434
// responsible for picking n_threads via normalize_thread_count and for the
3535
// thread safety of `chunk`.
3636
//
@@ -70,17 +70,27 @@ void parallel_for_chunks(
7070
}
7171
};
7272

73-
// jthread's destructor joins, so a failure while creating a later worker
74-
// cannot destroy an earlier still-joinable thread and terminate the
75-
// process. We still join explicitly below to rethrow only after all work
76-
// has completed.
77-
std::vector<std::jthread> threads;
73+
// A joinable std::thread whose destructor runs without a prior join calls
74+
// std::terminate. If spawning a later worker throws (e.g. the OS refuses a
75+
// new thread), the threads vector would otherwise destroy the already
76+
// joinable workers and terminate the process, so join them first and then
77+
// rethrow. (std::jthread would join on destruction automatically, but it is
78+
// not available in AppleClang's libc++, and portable macOS wheels are a
79+
// hard requirement.)
80+
std::vector<std::thread> threads;
7881
threads.reserve(n_threads > 0 ? n_threads - 1 : 0);
79-
for (std::size_t thread_id = 1; thread_id < n_threads; ++thread_id) {
80-
const auto [begin, end] = bounds(thread_id);
81-
threads.emplace_back([thread_id, begin, end, &guarded_chunk]() {
82-
guarded_chunk(thread_id, begin, end);
83-
});
82+
try {
83+
for (std::size_t thread_id = 1; thread_id < n_threads; ++thread_id) {
84+
const auto [begin, end] = bounds(thread_id);
85+
threads.emplace_back([thread_id, begin, end, &guarded_chunk]() {
86+
guarded_chunk(thread_id, begin, end);
87+
});
88+
}
89+
} catch (...) {
90+
for (auto &thread : threads) {
91+
thread.join();
92+
}
93+
throw;
8494
}
8595
const auto [begin, end] = bounds(0);
8696
guarded_chunk(0, begin, end);

0 commit comments

Comments
 (0)