diff --git a/repos/base-fiasco/include/base/native_types.h b/repos/base-fiasco/include/base/native_types.h index 3ee6ea8f5..86e1a01c7 100644 --- a/repos/base-fiasco/include/base/native_types.h +++ b/repos/base-fiasco/include/base/native_types.h @@ -39,7 +39,6 @@ namespace Genode { }; typedef Native_capability_tpl Native_capability; - typedef Fiasco::l4_threadid_t Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-fiasco/src/base/ipc/ipc.cc b/repos/base-fiasco/src/base/ipc/ipc.cc index 433d0f720..fffc92148 100644 --- a/repos/base-fiasco/src/base/ipc/ipc.cc +++ b/repos/base-fiasco/src/base/ipc/ipc.cc @@ -11,10 +11,15 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include #include +/* base-internal includes */ +#include + +/* Fiasco includes */ namespace Fiasco { #include #include @@ -28,26 +33,6 @@ using namespace Genode; ** Ipc_ostream ** *****************/ -void Ipc_ostream::_send() -{ - using namespace Fiasco; - - _snd_msg->send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0); - - l4_msgdope_t result; - l4_ipc_send(_dst.dst(), _snd_msg->addr(), _dst.local_name(), - *reinterpret_cast(&_snd_msg->buf[sizeof(umword_t)]), - L4_IPC_NEVER, &result); - - if (L4_IPC_IS_ERROR(result)) { - PERR("Ipc error %lx", L4_IPC_ERROR(result)); - throw Genode::Ipc_error(); - } - - _write_offset = sizeof(umword_t); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), _snd_msg(snd_msg), _dst(dst) @@ -60,45 +45,12 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : ** Ipc_istream ** *****************/ -void Ipc_istream::_wait() -{ - using namespace Fiasco; - - l4_msgdope_t result; - - /* - * Wait until we get a proper message and thereby - * ignore receive message cuts on the server-side. - * This error condition should be handled by the - * client. The server does not bother. - */ - do { - _rcv_msg->size_dope = L4_IPC_DOPE(_rcv_msg->size()>>2, 0); - - l4_ipc_wait(&_rcv_cs, _rcv_msg->addr(), - reinterpret_cast(&_rcv_msg->buf[0]), - reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), - L4_IPC_NEVER, &result); - - if (L4_IPC_IS_ERROR(result)) - PERR("Ipc error %lx", L4_IPC_ERROR(result)); - - } while (L4_IPC_IS_ERROR(result)); - - /* reset buffer read offset */ - _read_offset = sizeof(umword_t); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg): Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), Native_capability(Fiasco::l4_myself(), 0), _rcv_msg(rcv_msg) { using namespace Fiasco; - - _rcv_cs = L4_INVALID_ID; - _read_offset = sizeof(umword_t); } @@ -177,10 +129,38 @@ void Ipc_server::_prepare_next_reply_wait() void Ipc_server::_wait() { /* wait for new server request */ - try { Ipc_istream::_wait(); } catch (Blocking_canceled) { } + try { + + using namespace Fiasco; + + l4_msgdope_t result; + + /* + * Wait until we get a proper message and thereby + * ignore receive message cuts on the server-side. + * This error condition should be handled by the + * client. The server does not bother. + */ + do { + _rcv_msg->size_dope = L4_IPC_DOPE(_rcv_msg->size()>>2, 0); + + l4_ipc_wait(&_rcv_cs.caller, _rcv_msg->addr(), + reinterpret_cast(&_rcv_msg->buf[0]), + reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), + L4_IPC_NEVER, &result); + + if (L4_IPC_IS_ERROR(result)) + PERR("Ipc error %lx", L4_IPC_ERROR(result)); + + } while (L4_IPC_IS_ERROR(result)); + + /* reset buffer read offset */ + _read_offset = sizeof(umword_t); + + } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } @@ -226,7 +206,7 @@ void Ipc_server::_reply_wait() _write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg->addr(), Ipc_ostream::_dst.local_name(), *reinterpret_cast(&_snd_msg->buf[sizeof(umword_t)]), - &_rcv_cs, _rcv_msg->addr(), + &_rcv_cs.caller, _rcv_msg->addr(), reinterpret_cast(&_rcv_msg->buf[0]), reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), L4_IPC_SEND_TIMEOUT_0, &ipc_result); @@ -248,13 +228,18 @@ void Ipc_server::_reply_wait() } else _wait(); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg): +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) +: Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false) + Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false), _rcv_cs(cs) { } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-fiasco/src/include/base/internal/native_connection_state.h b/repos/base-fiasco/src/include/base/internal/native_connection_state.h new file mode 100644 index 000000000..f3a16e317 --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/native_connection_state.h @@ -0,0 +1,34 @@ +/* + * \brief Connection state + * \author Norman Feske + * \date 2016-03-03 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ +#define _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ + +/* Genode includes */ +#include + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +namespace Genode { struct Native_connection_state; } + + +struct Genode::Native_connection_state +{ + Fiasco::l4_threadid_t caller; +}; + + +#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */ diff --git a/repos/base-foc/include/base/native_types.h b/repos/base-foc/include/base/native_types.h index 9160f7031..efb68c59d 100644 --- a/repos/base-foc/include/base/native_types.h +++ b/repos/base-foc/include/base/native_types.h @@ -167,9 +167,6 @@ namespace Genode { Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); } bool valid() const { return (_idx != 0) && _idx->valid(); } }; - - - typedef int Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-foc/src/base/ipc/ipc.cc b/repos/base-foc/src/base/ipc/ipc.cc index 2aec85440..845f20699 100644 --- a/repos/base-foc/src/base/ipc/ipc.cc +++ b/repos/base-foc/src/base/ipc/ipc.cc @@ -184,17 +184,6 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned offset, ** Ipc_ostream ** *****************/ -void Ipc_ostream::_send() -{ - l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst); - tag = l4_ipc_send(_dst.dst(), l4_utcb(), tag, L4_IPC_NEVER); - if (ipc_error(tag, DEBUG_MSG)) - throw Ipc_error(); - - _write_offset = sizeof(l4_mword_t); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), @@ -208,35 +197,6 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) ** Ipc_istream ** *****************/ -/* Build with frame pointer to make GDB backtraces work. See issue #1061. */ -__attribute__((optimize("-fno-omit-frame-pointer"))) -__attribute__((noinline)) -void Ipc_istream::_wait() -{ - l4_umword_t label = 0; - addr_t rcv_cap_sel = _rcv_msg->rcv_cap_sel_base(); - for (int i = 0; i < Msgbuf_base::MAX_CAP_ARGS; i++) { - l4_utcb_br()->br[i] = rcv_cap_sel | L4_RCV_ITEM_SINGLE_CAP; - rcv_cap_sel += L4_CAP_SIZE; - } - l4_utcb_br()->bdr = 0; - - l4_msgtag_t tag; - do { - tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER); - } while (ipc_error(tag, DEBUG_MSG)); - - /* copy received label into message buffer */ - _rcv_msg->label(label); - - /* copy message from the UTCBs message registers to the receive buffer */ - copy_utcb_to_msgbuf(tag, _rcv_msg); - - /* reset unmarshaller */ - _read_offset = sizeof(l4_mword_t); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), @@ -303,7 +263,30 @@ void Ipc_server::_prepare_next_reply_wait() void Ipc_server::_wait() { /* wait for new server request */ - try { Ipc_istream::_wait(); } catch (Blocking_canceled) { } + try { + l4_umword_t label = 0; + addr_t rcv_cap_sel = _rcv_msg->rcv_cap_sel_base(); + for (int i = 0; i < Msgbuf_base::MAX_CAP_ARGS; i++) { + l4_utcb_br()->br[i] = rcv_cap_sel | L4_RCV_ITEM_SINGLE_CAP; + rcv_cap_sel += L4_CAP_SIZE; + } + l4_utcb_br()->bdr = 0; + + l4_msgtag_t tag; + do { + tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER); + } while (ipc_error(tag, DEBUG_MSG)); + + /* copy received label into message buffer */ + _rcv_msg->label(label); + + /* copy message from the UTCBs message registers to the receive buffer */ + copy_utcb_to_msgbuf(tag, _rcv_msg); + + /* reset unmarshaller */ + _read_offset = sizeof(l4_mword_t); + + } catch (Blocking_canceled) { } /* we only have an unknown implicit reply capability */ /* _dst = ???; */ @@ -361,9 +344,13 @@ void Ipc_server::_reply_wait() } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false) + _reply_needed(false), _rcv_cs(cs) { } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-foc/src/base/server/server.cc b/repos/base-foc/src/base/server/server.cc index eff3039a9..df33abafd 100644 --- a/repos/base-foc/src/base/server/server.cc +++ b/repos/base-foc/src/base/server/server.cc @@ -19,6 +19,9 @@ /* Genode includes */ #include +/* base-internal includes */ +#include + using namespace Genode; @@ -41,7 +44,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { - Ipc_server srv(&_snd_buf, &_rcv_buf); + Native_connection_state cs; + Ipc_server srv(cs, &_snd_buf, &_rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); diff --git a/repos/base-hw/include/base/native_types.h b/repos/base-hw/include/base/native_types.h index 6ae9e600d..a0ae9c7a8 100644 --- a/repos/base-hw/include/base/native_types.h +++ b/repos/base-hw/include/base/native_types.h @@ -17,9 +17,4 @@ #include -namespace Genode -{ - typedef int Native_connection_state; -} - #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-hw/src/base/ipc/ipc.cc b/repos/base-hw/src/base/ipc/ipc.cc index 665f1e0d1..18969f2d0 100644 --- a/repos/base-hw/src/base/ipc/ipc.cc +++ b/repos/base-hw/src/base/ipc/ipc.cc @@ -76,20 +76,15 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) ** Ipc_istream ** *****************/ -void Ipc_istream::_wait() -{ - /* FIXME: this shall be not supported */ - Kernel::pause_current_thread(); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), Native_capability(Thread_base::myself() ? Thread_base::myself()->native_thread().cap : Hw::_main_thread_cap), - _rcv_msg(rcv_msg), _rcv_cs(-1) -{ _read_offset = align_natural(RPC_OBJECT_ID_SIZE); } + _rcv_msg(rcv_msg) +{ + _read_offset = align_natural(RPC_OBJECT_ID_SIZE); +} Ipc_istream::~Ipc_istream() { } @@ -136,11 +131,14 @@ Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, ** Ipc_server ** ****************/ -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg) : +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, + Msgbuf_base *rcv_msg) +: Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false) { } + _reply_needed(false), _rcv_cs(cs) +{ } void Ipc_server::_prepare_next_reply_wait() @@ -214,3 +212,6 @@ void Ipc_server::_reply_wait() }, [&] () { upgrade_pd_session_quota(3*4096); }); } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-hw/src/base/server/server.cc b/repos/base-hw/src/base/server/server.cc index fcddad2a0..f8794745e 100644 --- a/repos/base-hw/src/base/server/server.cc +++ b/repos/base-hw/src/base/server/server.cc @@ -17,6 +17,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -39,7 +42,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { - Ipc_server srv(&_snd_buf, &_rcv_buf); + Native_connection_state cs; + Ipc_server srv(cs, &_snd_buf, &_rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); diff --git a/repos/base-linux/include/base/native_types.h b/repos/base-linux/include/base/native_types.h index affcd2432..d642981d8 100644 --- a/repos/base-linux/include/base/native_types.h +++ b/repos/base-linux/include/base/native_types.h @@ -41,17 +41,6 @@ namespace Genode { typedef Native_capability_tpl Native_capability; - /** - * The connection state is the socket handle of the RPC entrypoint - */ - struct Native_connection_state - { - int server_sd; - int client_sd; - - Native_connection_state() : server_sd(-1), client_sd(-1) { } - }; - enum { PARENT_SOCKET_HANDLE = 100 }; } diff --git a/repos/base-linux/src/base/env/platform_env.cc b/repos/base-linux/src/base/env/platform_env.cc index 347897c1a..b33c673c6 100644 --- a/repos/base-linux/src/base/env/platform_env.cc +++ b/repos/base-linux/src/base/env/platform_env.cc @@ -19,6 +19,7 @@ /* base-internal includes */ #include +#include using namespace Genode; diff --git a/repos/base-linux/src/base/ipc/ipc.cc b/repos/base-linux/src/base/ipc/ipc.cc index e5ed71800..7e0074c8f 100644 --- a/repos/base-linux/src/base/ipc/ipc.cc +++ b/repos/base-linux/src/base/ipc/ipc.cc @@ -37,6 +37,7 @@ /* base-internal includes */ #include #include +#include /* Linux includes */ #include @@ -452,12 +453,6 @@ void Ipc_ostream::_prepare_next_send() } -void Ipc_ostream::_send() -{ - PRAW("unexpected call to %s (%p)", __PRETTY_FUNCTION__, this); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg): Ipc_marshaller(snd_msg->buf, snd_msg->size()), _snd_msg(snd_msg), _dst(dst) { } @@ -477,12 +472,6 @@ void Ipc_istream::_prepare_next_receive() } -void Ipc_istream::_wait() -{ - PRAW("unexpected call to %s (%p)", __PRETTY_FUNCTION__, this); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller(rcv_msg->buf, rcv_msg->size()), @@ -491,32 +480,7 @@ Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) { } -Ipc_istream::~Ipc_istream() -{ - /* - * The association of the capability (client) socket must be invalidated on - * server destruction. We implement it here as the IPC server currently has - * no destructor. We have the plan to remove Ipc_istream and Ipc_ostream - * in the future and, then, move this into the server destructor. - * - * IPC clients have -1 as client_sd and need no disassociation. - */ - if (_rcv_cs.client_sd != -1) { - Genode::ep_sd_registry()->disassociate(_rcv_cs.client_sd); - - /* - * Reset thread role to non-server such that we can enter 'sleep_forever' - * without getting a warning. - */ - Thread_base *thread = Thread_base::myself(); - if (thread) - thread->native_thread().is_ipc_server = false; - } - - destroy_server_socket_pair(_rcv_cs); - _rcv_cs.client_sd = -1; - _rcv_cs.server_sd = -1; -} +Ipc_istream::~Ipc_istream() { } /**************** @@ -629,10 +593,11 @@ void Ipc_server::_reply_wait() } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false) + Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false), _rcv_cs(cs) { Thread_base *thread = Thread_base::myself(); @@ -660,3 +625,21 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) _prepare_next_reply_wait(); } + + +Ipc_server::~Ipc_server() +{ + Genode::ep_sd_registry()->disassociate(_rcv_cs.client_sd); + + /* + * Reset thread role to non-server such that we can enter 'sleep_forever' + * without getting a warning. + */ + Thread_base *thread = Thread_base::myself(); + if (thread) + thread->native_thread().is_ipc_server = false; + + destroy_server_socket_pair(_rcv_cs); + _rcv_cs.client_sd = -1; + _rcv_cs.server_sd = -1; +} diff --git a/repos/base-linux/src/core/include/platform_thread.h b/repos/base-linux/src/core/include/platform_thread.h index cff5dc66a..ac165a0c9 100644 --- a/repos/base-linux/src/core/include/platform_thread.h +++ b/repos/base-linux/src/core/include/platform_thread.h @@ -20,7 +20,10 @@ #include #include -/* Core includes */ +/* base-internal includes */ +#include + +/* core includes */ #include namespace Genode { diff --git a/repos/base-linux/src/include/base/internal/native_connection_state.h b/repos/base-linux/src/include/base/internal/native_connection_state.h new file mode 100644 index 000000000..2a7cc7cc4 --- /dev/null +++ b/repos/base-linux/src/include/base/internal/native_connection_state.h @@ -0,0 +1,28 @@ +/* + * \brief Connection state of incoming RPC request + * \author Norman Feske + * \date 2016-03-03 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ +#define _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ + +#include + +namespace Genode { struct Native_connection_state; } + + +struct Genode::Native_connection_state +{ + int server_sd = -1; + int client_sd = -1; +}; + +#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */ diff --git a/repos/base-nova/include/base/native_types.h b/repos/base-nova/include/base/native_types.h index bd172a325..3bad1694d 100644 --- a/repos/base-nova/include/base/native_types.h +++ b/repos/base-nova/include/base/native_types.h @@ -191,8 +191,6 @@ namespace Genode { */ bool trans_map() const { return _trans_map; } }; - - typedef int Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-nova/src/base/ipc/ipc.cc b/repos/base-nova/src/base/ipc/ipc.cc index 19a2dca1c..73a2c3b43 100644 --- a/repos/base-nova/src/base/ipc/ipc.cc +++ b/repos/base-nova/src/base/ipc/ipc.cc @@ -130,9 +130,6 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) ** Ipc_istream ** *****************/ -void Ipc_istream::_wait() { } - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), _rcv_msg(rcv_msg) { @@ -233,7 +230,11 @@ void Ipc_server::_reply() void Ipc_server::_reply_wait() { } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg) -: Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg) +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) +: + Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), _rcv_cs(cs) { } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index 7d4fb28cb..87c2ec832 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include /* NOVA includes */ #include @@ -120,7 +121,8 @@ void Rpc_entrypoint::_activation_entry() /* prepare ipc server object (copying utcb content to message buffer */ int opcode = 0; - Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf); + Native_connection_state cs; + Ipc_server srv(cs, &ep->_snd_buf, &ep->_rcv_buf); srv >> IPC_WAIT >> opcode; /* set default return value */ diff --git a/repos/base-okl4/include/base/native_types.h b/repos/base-okl4/include/base/native_types.h index 5580a27f5..54cfdb09e 100644 --- a/repos/base-okl4/include/base/native_types.h +++ b/repos/base-okl4/include/base/native_types.h @@ -39,7 +39,6 @@ namespace Genode { }; typedef Native_capability_tpl Native_capability; - typedef Okl4::L4_ThreadId_t Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-okl4/src/base/ipc/ipc.cc b/repos/base-okl4/src/base/ipc/ipc.cc index 100253d88..1a2e127a0 100644 --- a/repos/base-okl4/src/base/ipc/ipc.cc +++ b/repos/base-okl4/src/base/ipc/ipc.cc @@ -11,11 +11,16 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include #include #include +/* base-internal includes */ +#include + +/* OKL4 includes */ namespace Okl4 { extern "C" { #include #include @@ -98,23 +103,6 @@ static void copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned num_msg_words, ** Ipc_ostream ** *****************/ -void Ipc_ostream::_send() -{ - copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t), - _dst.local_name()); - - /* perform IPC send operation */ - L4_MsgTag_t rcv_tag = L4_Send(_dst.dst()); - - if (L4_IpcFailed(rcv_tag)) { - PERR("ipc error in _send."); - throw Genode::Ipc_error(); - } - - _write_offset = sizeof(umword_t); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), @@ -128,24 +116,6 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) ** Ipc_istream ** *****************/ -void Ipc_istream::_wait() -{ - /* - * Wait for IPC message - * - * The message tag (holding the size of the message) is located at - * message register 0 and implicitly addressed by 'L4_UntypedWords()'. - */ - L4_MsgTag_t rcv_tag = L4_Wait(&_rcv_cs); - - /* copy message from the UTCBs message registers to the receive buffer */ - copy_utcb_to_msgbuf(rcv_tag, _rcv_msg); - - /* reset unmarshaller */ - _read_offset = sizeof(umword_t); -} - - /** * Return the global thread ID of the calling thread * @@ -167,7 +137,6 @@ Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) Native_capability(thread_get_my_global_id(), 0), _rcv_msg(rcv_msg) { - _rcv_cs = Okl4::L4_nilthread; _read_offset = sizeof(umword_t); } @@ -231,10 +200,25 @@ void Ipc_server::_prepare_next_reply_wait() void Ipc_server::_wait() { /* wait for new server request */ - try { Ipc_istream::_wait(); } catch (Blocking_canceled) { } + try { + /* + * Wait for IPC message + * + * The message tag (holding the size of the message) is located at + * message register 0 and implicitly addressed by 'L4_UntypedWords()'. + */ + L4_MsgTag_t rcv_tag = L4_Wait(&_rcv_cs.caller); + + /* copy message from the UTCBs message registers to the receive buffer */ + copy_utcb_to_msgbuf(rcv_tag, _rcv_msg); + + /* reset unmarshaller */ + _read_offset = sizeof(umword_t); + + } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } @@ -264,7 +248,7 @@ void Ipc_server::_reply_wait() copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t), Ipc_ostream::_dst.local_name()); - L4_MsgTag_t rcv_tag = L4_ReplyWait(Ipc_ostream::_dst.dst(), &_rcv_cs); + L4_MsgTag_t rcv_tag = L4_ReplyWait(Ipc_ostream::_dst.dst(), &_rcv_cs.caller); /* * TODO: Check for IPC error @@ -274,7 +258,7 @@ void Ipc_server::_reply_wait() copy_utcb_to_msgbuf(rcv_tag, _rcv_msg); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); @@ -283,8 +267,13 @@ void Ipc_server::_reply_wait() } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) +: Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false) + _reply_needed(false), _rcv_cs(cs) { } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-okl4/src/include/base/internal/native_connection_state.h b/repos/base-okl4/src/include/base/internal/native_connection_state.h new file mode 100644 index 000000000..3f1215927 --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/native_connection_state.h @@ -0,0 +1,27 @@ +/* + * \brief Connection state + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ +#define _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ + +#include + +namespace Genode { struct Native_connection_state; } + + +struct Genode::Native_connection_state +{ + Okl4::L4_ThreadId_t caller; +}; + +#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */ diff --git a/repos/base-pistachio/include/base/native_types.h b/repos/base-pistachio/include/base/native_types.h index e22afa270..604ba02bf 100644 --- a/repos/base-pistachio/include/base/native_types.h +++ b/repos/base-pistachio/include/base/native_types.h @@ -36,8 +36,6 @@ namespace Genode { }; typedef Native_capability_tpl Native_capability; - - typedef Pistachio::L4_ThreadId_t Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk index 02524fd49..e60c33dc7 100644 --- a/repos/base-pistachio/lib/mk/base-common.mk +++ b/repos/base-pistachio/lib/mk/base-common.mk @@ -25,6 +25,9 @@ SRC_CC += thread/stack_allocator.cc SRC_CC += sleep.cc SRC_CC += rm_session_client.cc +# suppress warning caused by Pistachio's 'l4/message.h' +CC_WARN += -Wno-array-bounds + INC_DIR += $(REP_DIR)/src/include $(BASE_DIR)/src/include vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-pistachio/src/base/ipc/ipc.cc b/repos/base-pistachio/src/base/ipc/ipc.cc index 590316ed8..ce5ab0551 100644 --- a/repos/base-pistachio/src/base/ipc/ipc.cc +++ b/repos/base-pistachio/src/base/ipc/ipc.cc @@ -12,11 +12,16 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include #include #include +/* base-internal includes */ +#include + +/* Pistachio includes */ namespace Pistachio { #include #include @@ -41,40 +46,11 @@ using namespace Pistachio; #define IPCDEBUG(...) #endif + /***************** ** Ipc_ostream ** *****************/ -void Ipc_ostream::_send() -{ - IPCDEBUG("_send to 0x%08lx.\n", Ipc_ostream::_dst.dst().raw); - - L4_Msg_t msg; - L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf); - L4_Word_t local_name = Ipc_ostream::_dst.local_name(); - - L4_Clear(&msg); - - L4_Append(&msg, local_name); - L4_Append(&msg, sitem); - L4_Load(&msg); - - L4_MsgTag_t result = L4_Send(Ipc_ostream::_dst.dst()); - - /* - * Error indicator - * TODO Check what happened and print a nicer error message. - */ - if (L4_IpcFailed(result)) { - PERR("ipc error in _send."); - throw Genode::Ipc_error(); - } - - IPCDEBUG("_send successful\n"); - _write_offset = sizeof(umword_t); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), _snd_msg(snd_msg), _dst(dst) @@ -125,55 +101,12 @@ static inline void check_ipc_result(L4_MsgTag_t result, L4_Word_t error_code) } -void Ipc_istream::_wait() -{ - L4_MsgTag_t result; - L4_MsgBuffer_t msgbuf; - - IPCDEBUG("_wait.\n"); -retry: - - IPCDEBUG("_wait loop start (more than once means IpcError)\n"); - - L4_Clear (&msgbuf); - L4_Append (&msgbuf, L4_StringItem (_rcv_msg->size(), _rcv_msg->buf)); - L4_Accept(L4_UntypedWordsAcceptor); - L4_Accept(L4_StringItemsAcceptor, &msgbuf); - - // Wait for message. - result = L4_Wait(&_rcv_cs); - - if (L4_IpcFailed(result)) - goto retry; - - IPCDEBUG("Got something from 0x%x.\n", _rcv_cs); - L4_Msg_t msg; - - L4_Store(result, &msg); - - check_ipc_result(result, L4_ErrorCode()); - - /* get the local name */ - L4_Word_t local_name = L4_Get(&msg,0); - - /* - * Store local_name where badge() looks for it. - * XXX Check this... - */ - *((long *)_rcv_msg->buf) = local_name; - _read_offset = sizeof(umword_t); - - IPCDEBUG("_wait successful\n"); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), Native_capability(Pistachio::L4_Myself(), 0), _rcv_msg(rcv_msg) { IPCDEBUG("Ipc_istream constructed.\n"); - _rcv_cs = L4_nilthread; _read_offset = sizeof(umword_t); } @@ -246,10 +179,50 @@ void Ipc_server::_prepare_next_reply_wait() void Ipc_server::_wait() { /* wait for new server request */ - try { Ipc_istream::_wait(); } catch (Blocking_canceled) { } + try { + + L4_MsgTag_t result; + L4_MsgBuffer_t msgbuf; + + IPCDEBUG("_wait.\n"); + + do { + + IPCDEBUG("_wait loop start (more than once means IpcError)\n"); + + L4_Clear (&msgbuf); + L4_Append (&msgbuf, L4_StringItem (_rcv_msg->size(), _rcv_msg->buf)); + L4_Accept(L4_UntypedWordsAcceptor); + L4_Accept(L4_StringItemsAcceptor, &msgbuf); + + /* wait for message */ + result = L4_Wait(&_rcv_cs.caller); + + } while (L4_IpcFailed(result)); + + IPCDEBUG("Got something from 0x%x.\n", _rcv_cs.caller); + L4_Msg_t msg; + + L4_Store(result, &msg); + + check_ipc_result(result, L4_ErrorCode()); + + /* get the local name */ + L4_Word_t local_name = L4_Get(&msg,0); + + /* + * Store local_name where badge() looks for it. + * XXX Check this... + */ + *((long *)_rcv_msg->buf) = local_name; + _read_offset = sizeof(umword_t); + + IPCDEBUG("_wait successful\n"); + + } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } @@ -299,8 +272,8 @@ void Ipc_server::_reply_wait() L4_Accept(L4_StringItemsAcceptor, &msgbuf); L4_MsgTag_t result = L4_Ipc(Ipc_ostream::_dst.dst(), L4_anythread, - L4_Timeouts(L4_ZeroTime, L4_Never), &_rcv_cs); - IPCDEBUG("Got something from 0x%x.\n", L4_ThreadNo(L4_GlobalId(_rcv_cs))); + L4_Timeouts(L4_ZeroTime, L4_Never), &_rcv_cs.caller); + IPCDEBUG("Got something from 0x%x.\n", L4_ThreadNo(L4_GlobalId(_rcv_cs.caller))); /* error handling - check whether send or receive failed */ if (L4_IpcFailed(result)) { @@ -340,7 +313,7 @@ void Ipc_server::_reply_wait() IPCDEBUG("local_name = 0x%lx\n", badge()); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs, badge()); + Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); @@ -349,8 +322,12 @@ void Ipc_server::_reply_wait() } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false) + _reply_needed(false), _rcv_cs(cs) { } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-pistachio/src/include/base/internal/native_connection_state.h b/repos/base-pistachio/src/include/base/internal/native_connection_state.h new file mode 100644 index 000000000..1620cb0ed --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/native_connection_state.h @@ -0,0 +1,30 @@ +/* + * \brief Connection state + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ +#define _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ + +/* Pistachio includes */ +namespace Pistachio { +#include +} + +namespace Genode { struct Native_connection_state; } + + +struct Genode::Native_connection_state +{ + Pistachio::L4_ThreadId_t caller; +}; + +#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */ diff --git a/repos/base-sel4/include/base/native_types.h b/repos/base-sel4/include/base/native_types.h index 55a1154d6..50a93e4e1 100644 --- a/repos/base-sel4/include/base/native_types.h +++ b/repos/base-sel4/include/base/native_types.h @@ -98,8 +98,6 @@ namespace Genode { bool valid() const; }; - - typedef int Native_connection_state; } #endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */ diff --git a/repos/base-sel4/src/base/ipc/ipc.cc b/repos/base-sel4/src/base/ipc/ipc.cc index 09c3c71d1..0a54b79d2 100644 --- a/repos/base-sel4/src/base/ipc/ipc.cc +++ b/repos/base-sel4/src/base/ipc/ipc.cc @@ -277,14 +277,6 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap) ** Ipc_ostream ** *****************/ -void Ipc_ostream::_send() -{ - ASSERT(false); - - _write_offset = sizeof(umword_t); -} - - Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : Ipc_marshaller((char *)snd_msg->data(), snd_msg->size()), @@ -298,12 +290,6 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) ** Ipc_istream ** *****************/ -void Ipc_istream::_wait() -{ - ASSERT(false); -} - - Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : Ipc_unmarshaller((char *)rcv_msg->data(), rcv_msg->size()), @@ -411,12 +397,15 @@ void Ipc_server::_reply_wait() } -Ipc_server::Ipc_server(Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg) +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false) + _reply_needed(false), _rcv_cs(cs) { *static_cast(this) = Native_capability(Capability_space::create_ep_cap(*Thread_base::myself())); } + + +Ipc_server::~Ipc_server() { } diff --git a/repos/base-sel4/src/base/server/server.cc b/repos/base-sel4/src/base/server/server.cc index 371f923e1..b482b5bd9 100644 --- a/repos/base-sel4/src/base/server/server.cc +++ b/repos/base-sel4/src/base/server/server.cc @@ -21,6 +21,7 @@ /* base-internal includes */ #include +#include using namespace Genode; @@ -44,7 +45,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { - Ipc_server srv(&_snd_buf, &_rcv_buf); + Native_connection_state cs; + Ipc_server srv(cs, &_snd_buf, &_rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); diff --git a/repos/base/include/base/ipc.h b/repos/base/include/base/ipc.h index ff1eb3190..a64acf62f 100644 --- a/repos/base/include/base/ipc.h +++ b/repos/base/include/base/ipc.h @@ -31,7 +31,8 @@ namespace Genode { - enum Ipc_ostream_send { IPC_SEND }; + class Native_connection_state; + enum Ipc_istream_wait { IPC_WAIT }; enum Ipc_client_call { IPC_CALL }; enum Ipc_server_reply { IPC_REPLY }; @@ -223,11 +224,6 @@ class Genode::Ipc_ostream : public Ipc_marshaller */ void _prepare_next_send(); - /** - * Send message in _snd_msg to _dst - */ - void _send(); - /** * Insert capability to message buffer */ @@ -283,15 +279,6 @@ class Genode::Ipc_ostream : public Ipc_marshaller return *this; } - /** - * Issue the sending of the message buffer - */ - Ipc_ostream &operator << (Ipc_ostream_send) - { - _send(); - return *this; - } - /** * Return current 'IPC_SEND' destination * @@ -325,8 +312,7 @@ class Genode::Ipc_istream : public Ipc_unmarshaller, public Native_capability protected: - Msgbuf_base *_rcv_msg; - Native_connection_state _rcv_cs; + Msgbuf_base *_rcv_msg; /** * Obtain capability from message buffer @@ -340,11 +326,6 @@ class Genode::Ipc_istream : public Ipc_unmarshaller, public Native_capability */ void _prepare_next_receive(); - /** - * Wait for incoming message to be received in _rcv_msg - */ - void _wait(); - public: explicit Ipc_istream(Msgbuf_base *rcv_msg); @@ -356,15 +337,6 @@ class Genode::Ipc_istream : public Ipc_unmarshaller, public Native_capability */ long badge() { return _long_at_idx(0); } - /** - * Block for an incoming message filling the receive buffer - */ - Ipc_istream &operator >> (Ipc_istream_wait) - { - _wait(); - return *this; - } - /** * Read values from receive buffer */ @@ -530,6 +502,8 @@ class Genode::Ipc_server : public Ipc_istream, public Ipc_ostream bool _reply_needed; /* false for the first reply_wait */ + Native_connection_state &_rcv_cs; + void _prepare_next_reply_wait(); /** @@ -560,7 +534,10 @@ class Genode::Ipc_server : public Ipc_istream, public Ipc_ostream /** * Constructor */ - Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg); + Ipc_server(Native_connection_state &, + Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg); + + ~Ipc_server(); /** * Set return value of server call diff --git a/repos/base/src/base/server/server.cc b/repos/base/src/base/server/server.cc index 6a3745737..1325a9f63 100644 --- a/repos/base/src/base/server/server.cc +++ b/repos/base/src/base/server/server.cc @@ -19,6 +19,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -44,7 +47,8 @@ void Rpc_entrypoint::entry() { using Pool = Object_pool; - Ipc_server srv(&_snd_buf, &_rcv_buf); + Native_connection_state cs; + Ipc_server srv(cs, &_snd_buf, &_rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); diff --git a/repos/base/src/include/base/internal/native_connection_state.h b/repos/base/src/include/base/internal/native_connection_state.h new file mode 100644 index 000000000..9f3e87710 --- /dev/null +++ b/repos/base/src/include/base/internal/native_connection_state.h @@ -0,0 +1,21 @@ +/* + * \brief Dummy connection state + * \author Norman Feske + * \date 2016-03-03 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ +#define _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ + +#include + +namespace Genode { struct Native_connection_state { }; } + +#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */