mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
Fix: Avoid deadlock during cleanup of entrypoint
Invoke cancel_blocking before calling the cleanup portal of the rpc_entrypoint. If a rpc_entrypoint is blocked in a semaphore the cleanup call gets stuck forever.
This commit is contained in:
parent
f328f3786b
commit
33334b4f4b
@ -162,12 +162,12 @@ Pager_object::~Pager_object()
|
||||
revoke(Obj_crd(_pt_sel, 0), true);
|
||||
|
||||
/* Make sure nobody is in the handler anymore by doing an IPC to a
|
||||
* local cap pointing to same serving thread. When the call returns
|
||||
* we know that nobody is handled by this object anymore, because
|
||||
* all remotely available portals had been revoked beforehand.
|
||||
*/
|
||||
* local cap pointing to same serving thread. When the call returns
|
||||
* we know that nobody is handled by this object anymore, because
|
||||
* all remotely available portals had been revoked beforehand.
|
||||
*/
|
||||
Utcb *utcb = (Utcb *)Thread_base::myself()->utcb();
|
||||
utcb->mtd = 0;
|
||||
utcb->set_msg_word(0);
|
||||
if (uint8_t res = call(_pt_cleanup))
|
||||
PERR("failure - cleanup call failed res=%d", res);
|
||||
|
||||
|
@ -173,10 +173,17 @@ void Rpc_entrypoint::entry()
|
||||
|
||||
void Rpc_entrypoint::_leave_server_object(Rpc_object_base *obj)
|
||||
{
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
if (obj == _curr_obj)
|
||||
cancel_blocking();
|
||||
}
|
||||
|
||||
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb());
|
||||
/* don't call ourself */
|
||||
if (utcb != reinterpret_cast<Nova::Utcb *>(&_context->utcb)) {
|
||||
utcb->mtd = 0;
|
||||
utcb->set_msg_word(0);
|
||||
if (Nova::call(obj->cap().dst() + 1))
|
||||
PERR("could not clean up entry point");
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ void Thread_base::_init_platform_thread()
|
||||
_tid.pd_sel = cap_selector_allocator()->pd_sel();
|
||||
|
||||
/* create running semaphore required for locking */
|
||||
int res = Nova::create_sm(_tid.rs_sel, _tid.pd_sel, 0);
|
||||
uint8_t res = Nova::create_sm(_tid.rs_sel, _tid.pd_sel, 0);
|
||||
if (res)
|
||||
PERR("create_sm returned %d", res);
|
||||
PERR("create_sm returned %u", res);
|
||||
}
|
||||
|
||||
|
||||
@ -61,3 +61,8 @@ void Thread_base::start()
|
||||
* On NOVA, core never starts regular threads.
|
||||
*/
|
||||
}
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
Nova::sm_ctrl(_tid.rs_sel, Nova::SEMAPHORE_UP);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user