From e0d9a04f67bd9e8ed1bcebf1804d7743e143cfcc Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 18 Sep 2020 13:39:52 +0200 Subject: [PATCH] libc: resolve circular dependency in fork This patch is a follow-up for the commit "libc: use monitor for fork". It removes the use of the monitor mechanism from the 'Local_clone_service::close' RPC function because the fork_ep must stay responsive for the destruction and creation of 'Child' objects. Issue #3874 --- repos/libports/src/lib/libc/fork.cc | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/repos/libports/src/lib/libc/fork.cc b/repos/libports/src/lib/libc/fork.cc index d2e92276ae..4f3a9cdd07 100644 --- a/repos/libports/src/lib/libc/fork.cc +++ b/repos/libports/src/lib/libc/fork.cc @@ -354,32 +354,41 @@ struct Libc::Local_clone_service : Noncopyable typedef Local_service Service; + Child_ready &_child_ready; + + Io_signal_handler _child_ready_handler; + + void _handle_child_ready() + { + _child_ready.child_ready(); + + monitor().trigger_monitor_examination(); + } + struct Factory : Local_service::Factory { - Session &_session; - Child_ready &_child_ready; + Session &_session; + Signal_context_capability _started_sigh; - Factory(Session &session, Child_ready &child_ready) - : _session(session), _child_ready(child_ready) { } + Factory(Session &session, Signal_context_capability started_sigh) + : _session(session), _started_sigh(started_sigh) { } Session &create(Args const &, Affinity) override { return _session; } void upgrade(Session &, Args const &) override { } - void destroy(Session &) override - { - monitor().monitor([&] { - _child_ready.child_ready(); - return Fn::COMPLETE; - }); - } + void destroy(Session &) override { Signal_transmitter(_started_sigh).submit(); } } _factory; Service service { _factory }; Local_clone_service(Env &env, Entrypoint &ep, Child_ready &child_ready) - : _session(env, ep), _factory(_session, child_ready) { } + : + _session(env, ep), _child_ready(child_ready), + _child_ready_handler(env.ep(), *this, &Local_clone_service::_handle_child_ready), + _factory(_session, _child_ready_handler) + { } };