base: remove 'Native_connection_state' from API

Issue #1832
This commit is contained in:
Norman Feske 2016-03-11 21:47:12 +01:00 committed by Christian Helmuth
parent da5d182ad3
commit 4cdfb9bc2f
30 changed files with 389 additions and 364 deletions

View File

@ -39,7 +39,6 @@ namespace Genode {
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
typedef Fiasco::l4_threadid_t Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -11,10 +11,15 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <base/ipc.h>
#include <base/blocking.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sys/syscalls.h>
@ -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<l4_umword_t *>(&_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<l4_umword_t *>(&_rcv_msg->buf[0]),
reinterpret_cast<l4_umword_t *>(&_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<l4_umword_t *>(&_rcv_msg->buf[0]),
reinterpret_cast<l4_umword_t *>(&_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<l4_umword_t *>(&_snd_msg->buf[sizeof(umword_t)]),
&_rcv_cs, _rcv_msg->addr(),
&_rcv_cs.caller, _rcv_msg->addr(),
reinterpret_cast<l4_umword_t *>(&_rcv_msg->buf[0]),
reinterpret_cast<l4_umword_t *>(&_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() { }

View File

@ -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 <base/stdint.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode { struct Native_connection_state; }
struct Genode::Native_connection_state
{
Fiasco::l4_threadid_t caller;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */

View File

@ -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_ */

View File

@ -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() { }

View File

@ -19,6 +19,9 @@
/* Genode includes */
#include <base/rpc_server.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
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();

View File

@ -17,9 +17,4 @@
#include <base/native_capability.h>
namespace Genode
{
typedef int Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -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<unsigned>(RPC_OBJECT_ID_SIZE); }
_rcv_msg(rcv_msg)
{
_read_offset = align_natural<unsigned>(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() { }

View File

@ -17,6 +17,9 @@
#include <base/env.h>
#include <util/retry.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
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();

View File

@ -41,17 +41,6 @@ namespace Genode {
typedef Native_capability_tpl<Cap_dst_policy> 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 };
}

View File

@ -19,6 +19,7 @@
/* base-internal includes */
#include <base/internal/platform_env.h>
#include <base/internal/native_connection_state.h>
using namespace Genode;

View File

@ -37,6 +37,7 @@
/* base-internal includes */
#include <base/internal/socket_descriptor_registry.h>
#include <base/internal/native_thread.h>
#include <base/internal/native_connection_state.h>
/* Linux includes */
#include <linux_syscalls.h>
@ -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;
}

View File

@ -20,7 +20,10 @@
#include <base/thread_state.h>
#include <cpu_session/cpu_session.h>
/* Core includes */
/* base-internal includes */
#include <base/internal/native_connection_state.h>
/* core includes */
#include <pager.h>
namespace Genode {

View File

@ -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 <base/stdint.h>
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_ */

View File

@ -191,8 +191,6 @@ namespace Genode {
*/
bool trans_map() const { return _trans_map; }
};
typedef int Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -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() { }

View File

@ -20,6 +20,7 @@
/* base-internal includes */
#include <base/internal/stack.h>
#include <base/internal/native_connection_state.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -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 */

View File

@ -39,7 +39,6 @@ namespace Genode {
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
typedef Okl4::L4_ThreadId_t Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -11,11 +11,16 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <base/ipc.h>
#include <base/native_types.h>
#include <base/blocking.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
/* OKL4 includes */
namespace Okl4 { extern "C" {
#include <l4/config.h>
#include <l4/types.h>
@ -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() { }

View File

@ -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 <base/stdint.h>
namespace Genode { struct Native_connection_state; }
struct Genode::Native_connection_state
{
Okl4::L4_ThreadId_t caller;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */

View File

@ -36,8 +36,6 @@ namespace Genode {
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
typedef Pistachio::L4_ThreadId_t Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -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

View File

@ -12,11 +12,16 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <base/ipc.h>
#include <base/blocking.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
/* Pistachio includes */
namespace Pistachio {
#include <l4/types.h>
#include <l4/ipc.h>
@ -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() { }

View File

@ -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 <l4/types.h>
}
namespace Genode { struct Native_connection_state; }
struct Genode::Native_connection_state
{
Pistachio::L4_ThreadId_t caller;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */

View File

@ -98,8 +98,6 @@ namespace Genode {
bool valid() const;
};
typedef int Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -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<Native_capability *>(this) =
Native_capability(Capability_space::create_ep_cap(*Thread_base::myself()));
}
Ipc_server::~Ipc_server() { }

View File

@ -21,6 +21,7 @@
/* base-internal includes */
#include <base/internal/capability_space_sel4.h>
#include <base/internal/native_connection_state.h>
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();

View File

@ -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

View File

@ -19,6 +19,9 @@
#include <base/rpc_server.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/native_connection_state.h>
using namespace Genode;
@ -44,7 +47,8 @@ void Rpc_entrypoint::entry()
{
using Pool = Object_pool<Rpc_object_base>;
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();

View File

@ -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 <base/stdint.h>
namespace Genode { struct Native_connection_state { }; }
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_CONNECTION_STATE_H_ */