diff --git a/base-nova/include/base/ipc_msgbuf.h b/base-nova/include/base/ipc_msgbuf.h index c18a85a37c..5bcec79ac7 100644 --- a/base-nova/include/base/ipc_msgbuf.h +++ b/base-nova/include/base/ipc_msgbuf.h @@ -50,7 +50,7 @@ namespace Genode { /** * Base of portal receive window */ - int _rcv_pt_base; + addr_t _rcv_pt_base; struct { addr_t sel; @@ -64,9 +64,9 @@ namespace Genode { unsigned _rcv_pt_sel_max; /** - * Flag set to true if receive window must be re-initialized + * Number of capabilities which has been received, reported by the kernel. */ - bool _rcv_dirty; + unsigned _rcv_items; char _msg_start[]; /* symbol marks start of message */ @@ -75,12 +75,17 @@ namespace Genode { /** * Constructor */ - Msgbuf_base() : _rcv_dirty(true) + Msgbuf_base() : _rcv_pt_base(~0UL), _rcv_items(0) { rcv_reset(); snd_reset(); } + ~Msgbuf_base() + { + rcv_reset(); + } + /* * Begin of actual message buffer */ @@ -156,11 +161,16 @@ namespace Genode { return 0; } + /** + * Return true if receive window must be re-initialized + */ + bool rcv_invalid() { return _rcv_pt_base == ~0UL; } + /** * Return true if receive window must be re-initialized * * After reading portal selectors from the message buffer using - * 'rcv_pt_sel()', we assume that the IDC call populared the + * 'rcv_pt_sel()', we assume that the IDC call populated the * current receive window with one or more portal capabilities. * To enable the reception of portal capability selectors for the * next IDC, we need a fresh receive window. @@ -231,10 +241,8 @@ namespace Genode { */ void rcv_prepare_pt_sel_window(Nova::Utcb *utcb) { - if (rcv_dirty()) { + if (rcv_invalid() || rcv_cleanup(true)) _rcv_pt_base = cap_selector_allocator()->alloc(MAX_CAP_ARGS_LOG2); - _rcv_dirty = false; - } /* register receive window at the UTCB */ utcb->crd_rcv = Nova::Obj_crd(rcv_pt_base(),MAX_CAP_ARGS_LOG2); diff --git a/base-nova/src/base/ipc/ipc.cc b/base-nova/src/base/ipc/ipc.cc index 8047de2a4a..fa29666d44 100644 --- a/base-nova/src/base/ipc/ipc.cc +++ b/base-nova/src/base/ipc/ipc.cc @@ -49,8 +49,6 @@ static void copy_utcb_to_msgbuf(Nova::Utcb *utcb, Msgbuf_base *rcv_msg) mword_t *dst = (mword_t *)&msg_buf[0]; for (unsigned i = 0; i < num_msg_words; i++) *dst++ = *src++; - - rcv_msg->rcv_reset(); } @@ -151,6 +149,7 @@ void Ipc_client::_call() PERR("call returned %u", res); } + _rcv_msg->post_ipc(utcb); copy_utcb_to_msgbuf(utcb, _rcv_msg); _snd_msg->snd_reset(); diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index a504e64085..14e1bc40ec 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -133,6 +133,7 @@ void Rpc_entrypoint::_activation_entry() Rpc_entrypoint *ep = static_cast(Thread_base::myself()); Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf); + ep->_rcv_buf.post_ipc(reinterpret_cast(ep->utcb())); /* destination of next reply */ srv.dst(Native_capability(id_pt, srv.badge()));