mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +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);
|
revoke(Obj_crd(_pt_sel, 0), true);
|
||||||
|
|
||||||
/* Make sure nobody is in the handler anymore by doing an IPC to a
|
/* 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
|
* local cap pointing to same serving thread. When the call returns
|
||||||
* we know that nobody is handled by this object anymore, because
|
* we know that nobody is handled by this object anymore, because
|
||||||
* all remotely available portals had been revoked beforehand.
|
* all remotely available portals had been revoked beforehand.
|
||||||
*/
|
*/
|
||||||
Utcb *utcb = (Utcb *)Thread_base::myself()->utcb();
|
Utcb *utcb = (Utcb *)Thread_base::myself()->utcb();
|
||||||
utcb->mtd = 0;
|
utcb->set_msg_word(0);
|
||||||
if (uint8_t res = call(_pt_cleanup))
|
if (uint8_t res = call(_pt_cleanup))
|
||||||
PERR("failure - cleanup call failed res=%d", res);
|
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)
|
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());
|
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb());
|
||||||
/* don't call ourself */
|
/* don't call ourself */
|
||||||
if (utcb != reinterpret_cast<Nova::Utcb *>(&_context->utcb)) {
|
if (utcb != reinterpret_cast<Nova::Utcb *>(&_context->utcb)) {
|
||||||
utcb->mtd = 0;
|
utcb->set_msg_word(0);
|
||||||
if (Nova::call(obj->cap().dst() + 1))
|
if (Nova::call(obj->cap().dst() + 1))
|
||||||
PERR("could not clean up entry point");
|
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();
|
_tid.pd_sel = cap_selector_allocator()->pd_sel();
|
||||||
|
|
||||||
/* create running semaphore required for locking */
|
/* 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)
|
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.
|
* On NOVA, core never starts regular threads.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thread_base::cancel_blocking()
|
||||||
|
{
|
||||||
|
Nova::sm_ctrl(_tid.rs_sel, Nova::SEMAPHORE_UP);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user