Handling exceptions from worker threads is broken when multiple routes are checked in several threads in plan mode. Multi-threading happens here:
|
std::vector<std::exception_ptr> thread_exceptions(nb_buckets, nullptr); |
|
|
|
auto run_check = [&](unsigned bucket, |
|
const std::vector<Index>& vehicle_ranks) { |
|
for (auto v : vehicle_ranks) { |
|
auto search = v_rank_to_actual_route_rank.find(v); |
|
assert(search != v_rank_to_actual_route_rank.end()); |
|
const auto route_rank = search->second; |
|
|
|
try { |
|
routes[route_rank] = choose_ETA(input, v, input.vehicles[v].steps); |
|
} catch (...) { |
|
thread_exceptions[bucket] = std::current_exception(); |
|
} |
|
} |
|
}; |
|
std::vector<std::thread> solving_threads; |
|
|
|
for (unsigned i = 0; i < nb_buckets; ++i) { |
|
solving_threads.emplace_back(run_check, i, thread_ranks[i]); |
|
} |
|
|
|
for (unsigned i = 0; i < nb_buckets; ++i) { |
|
solving_threads[i].join(); |
|
|
|
if (thread_exceptions[i] != nullptr) { |
|
std::rethrow_exception(thread_exceptions[i]); |
|
} |
|
} |
The puzzling part is that the exception is properly rethrown and handled in main when running a single worker thread. Using a version of the docs example where I added service_after and service_before keys to force an infeasible route (example_3.txt):
$ vroom -c -i example_3.txt -t 2
terminate called without an active exception
Aborted (core dumped)
$ vroom -c -i example_3.txt -t 1
[Error] Infeasible route for vehicle 1.
{"code":2,"error":"Infeasible route for vehicle 1."}
I've used a std::vector<std::exception_ptr>> to store one std::exception_ptr per thread and be able to rethrow the exception. The same problem applies to the latest commits in #450 and my current attempts for #417.
Handling exceptions from worker threads is broken when multiple routes are checked in several threads in plan mode. Multi-threading happens here:
vroom/src/algorithms/validation/check.cpp
Lines 57 to 85 in ffa1c6d
The puzzling part is that the exception is properly rethrown and handled in main when running a single worker thread. Using a version of the docs example where I added
service_afterandservice_beforekeys to force an infeasible route (example_3.txt):I've used a
std::vector<std::exception_ptr>>to store onestd::exception_ptrper thread and be able to rethrow the exception. The same problem applies to the latest commits in #450 and my current attempts for #417.