mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
signal.run: avoid deadlock during test destruction
This commit is contained in:
parent
9e34ba1458
commit
c5f59ddfb1
@ -32,9 +32,9 @@ class Sender : Thread
|
||||
Signal_transmitter _transmitter;
|
||||
unsigned const _interval_ms;
|
||||
bool const _verbose;
|
||||
bool _stop { false };
|
||||
bool volatile _stop { false };
|
||||
unsigned _submit_cnt { 0 };
|
||||
bool _idle { false };
|
||||
bool volatile _idle { false };
|
||||
|
||||
void entry()
|
||||
{
|
||||
@ -65,6 +65,14 @@ class Sender : Thread
|
||||
Thread::start();
|
||||
}
|
||||
|
||||
~Sender()
|
||||
{
|
||||
if (!_stop && Thread::myself() != this) {
|
||||
_stop = true;
|
||||
join();
|
||||
}
|
||||
}
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
@ -524,7 +532,7 @@ struct Nested_stress_test : Signal_test
|
||||
struct Sender : Thread
|
||||
{
|
||||
Signal_transmitter transmitter;
|
||||
bool destruct { false };
|
||||
bool volatile destruct { false };
|
||||
|
||||
Sender(Env &env, char const *name, Signal_context_capability cap)
|
||||
: Thread(env, name, 8*1024), transmitter(cap) { }
|
||||
@ -540,8 +548,10 @@ struct Nested_stress_test : Signal_test
|
||||
{
|
||||
Entrypoint ep;
|
||||
char const *name;
|
||||
unsigned count { 0 };
|
||||
bool destruct { false };
|
||||
unsigned count { 0 };
|
||||
unsigned level { 0 };
|
||||
bool volatile destruct { false };
|
||||
bool volatile ready_for_destruction { false };
|
||||
|
||||
Io_signal_handler<Receiver> handler { ep, *this, &Receiver::handle };
|
||||
|
||||
@ -554,7 +564,11 @@ struct Nested_stress_test : Signal_test
|
||||
* We have to get out of the nesting if the host wants to destroy
|
||||
* us to avoid a deadlock at the lock in the signal handler.
|
||||
*/
|
||||
if (destruct) { return; }
|
||||
if (destruct) {
|
||||
if (level == 0)
|
||||
ready_for_destruction = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* raise call counter */
|
||||
count++;
|
||||
@ -564,7 +578,10 @@ struct Nested_stress_test : Signal_test
|
||||
* gives zero, then unwind the whole nesting and start afresh.
|
||||
*/
|
||||
if ((count & ((1 << UNWIND_COUNT_MOD_LOG2) - 1)) != 0) {
|
||||
ep.wait_and_dispatch_one_io_signal(); }
|
||||
level ++;
|
||||
ep.wait_and_dispatch_one_io_signal();
|
||||
level --;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -599,26 +616,33 @@ struct Nested_stress_test : Signal_test
|
||||
/* tell timer not to send any signals anymore. */
|
||||
timer.sigh(Timer::Session::Signal_context_capability());
|
||||
|
||||
/* let senders stop burning our CPU time */
|
||||
sender_1.destruct = true;
|
||||
sender_2.destruct = true;
|
||||
sender_3.destruct = true;
|
||||
|
||||
/* let receivers unwind their nesting and stop with the next signal */
|
||||
receiver_1.destruct = true;
|
||||
receiver_2.destruct = true;
|
||||
receiver_3.destruct = true;
|
||||
|
||||
/*
|
||||
* Send final signals ourselves because otherwise we would have to
|
||||
* synchronize with the senders.
|
||||
* Wait until receiver threads get out of
|
||||
* wait_and_dispatch_one_io_signal, otherwise we may (dead)lock forever
|
||||
* during destruction of the Io_signal_handler.
|
||||
*/
|
||||
sender_1.transmitter.submit();
|
||||
sender_2.transmitter.submit();
|
||||
sender_3.transmitter.submit();
|
||||
log("waiting for receivers");
|
||||
|
||||
while (!receiver_1.ready_for_destruction) { }
|
||||
while (!receiver_2.ready_for_destruction) { }
|
||||
while (!receiver_3.ready_for_destruction) { }
|
||||
|
||||
/* let senders stop burning our CPU time */
|
||||
sender_1.destruct = true;
|
||||
sender_2.destruct = true;
|
||||
sender_3.destruct = true;
|
||||
|
||||
log ("waiting for senders");
|
||||
|
||||
/* wait until threads joined */
|
||||
sender_1.join(); sender_2.join(), sender_3.join();
|
||||
|
||||
log("destructing ...");
|
||||
}
|
||||
|
||||
void handle_poll()
|
||||
|
Loading…
Reference in New Issue
Block a user