-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
bugSomething isn't workingSomething isn't workinggood first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is needed
Description
Usage of tf::Semaphore with exception like below leads to a deadlock (where user always waits for task graph to finish), it happens because Semaphore keeps some of waiting tasks in its list, and the main task queue does not have those tasks.
void semaphore_complex1(int semaphore_size) {
tf::Executor executor(semaphore_size * 4);
tf::Taskflow taskflow;
tf::Semaphore semaphore(semaphore_size);
tf::Task init = taskflow.emplace([]() {});
for (size_t i = 0; i < semaphore_size * 4; ++i)
{
tf::Task A = taskflow.emplace([]() {});
tf::Task B = taskflow.emplace([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
throw std::runtime_error("exception");
});
tf::Task C = taskflow.emplace([]() {});
tf::Task D = taskflow.emplace([]() {});
init.precede(A);
A.precede(B);
B.precede(C);
C.precede(D);
A.acquire(semaphore);
D.release(semaphore);
}
REQUIRE(semaphore.value() == semaphore_size);
auto future = executor.run(taskflow);
auto fn = [&]() {
auto res = future.wait_for(std::chrono::seconds(60));
if (res == std::future_status::timeout)
{
FAIL("Timeout");
}
FAIL("No exception?!");
};
// when B throws the exception, D will not run and thus semaphore is not released
REQUIRE_THROWS_WITH_AS(fn(), "exception", std::runtime_error);
REQUIRE(semaphore.value() == 0);
// reset the semaphore to a clean state before running the taskflow again
semaphore.reset();
REQUIRE(semaphore.value() == semaphore_size);
// run it again
REQUIRE_THROWS_WITH_AS(fn(), "exception", std::runtime_error);
}
TEST_CASE("Exception.Semaphore.Complex.4threads" * doctest::timeout(300)) {
semaphore_complex1(4);
}
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workinggood first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is needed