diff --git a/base-codezero/lib/mk/ipc.mk b/base-codezero/lib/mk/ipc.mk
index 302770253..9a85fb2e4 100644
--- a/base-codezero/lib/mk/ipc.mk
+++ b/base-codezero/lib/mk/ipc.mk
@@ -1,5 +1,6 @@
-SRC_CC = ipc.cc pager.cc
+SRC_CC = ipc.cc pager.cc ipc_marshal_cap.cc
INC_DIR += $(REP_DIR)/include/codezero/dummies
LIBS = cap_copy
-vpath %.cc $(REP_DIR)/src/base/ipc
+vpath %.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-fiasco/lib/mk/ipc.mk b/base-fiasco/lib/mk/ipc.mk
index aac0969d0..282f5ab24 100644
--- a/base-fiasco/lib/mk/ipc.mk
+++ b/base-fiasco/lib/mk/ipc.mk
@@ -1,4 +1,5 @@
-SRC_CC = ipc.cc pager.cc
+SRC_CC = ipc.cc pager.cc ipc_marshal_cap.cc
LIBS = cap_copy
-vpath %.cc $(REP_DIR)/src/base/ipc
+vpath %.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-foc/include/base/ipc.h b/base-foc/include/base/ipc.h
deleted file mode 100644
index 1f9312f14..000000000
--- a/base-foc/include/base/ipc.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * \brief Fiasco.OC-specific supplements to the IPC framework
- * \author Norman Feske
- * \author Stefan Kalkowski
- * \date 2010-01-27
- */
-
-/*
- * Copyright (C) 2010-2013 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__IPC_H_
-#define _INCLUDE__BASE__IPC_H_
-
-#include
-#include
-
-
-inline void Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
-{
- using namespace Fiasco;
-
- /* first transfer local capability value */
- _write_to_buf(cap.local());
-
- /* if it's a local capability we're done */
- if (cap.local())
- return;
-
- if (cap.valid()) {
- if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) {
- _write_to_buf(0);
- return;
- }
- }
-
- /* transfer capability id */
- _write_to_buf(cap.local_name());
-
- /* only transfer kernel-capability if it's a valid one */
- if (cap.valid())
- _snd_msg->snd_append_cap_sel(cap.dst());
-
- ASSERT(!cap.valid() ||
- l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst())),
- "Send invalid cap");
-}
-
-
-inline void Genode::Ipc_istream::_unmarshal_capability(Genode::Native_capability &cap)
-{
- using namespace Fiasco;
-
- long value = 0;
-
- /* get local capability pointer from message buffer */
- _read_from_buf(value);
-
- /* if it's a local capability, the pointer is marshalled in the id */
- if (value) {
- cap = Capability::local_cap((Native_capability*)value);
- return;
- }
-
- /* extract capability id from message buffer */
- _read_from_buf(value);
-
- /* if id is zero an invalid capability was transfered */
- if (!value) {
- cap = Native_capability();
- return;
- }
-
- /* try to insert received capability in the map and return it */
- cap = Native_capability(cap_map()->insert_map(value, _rcv_msg->rcv_cap_sel()));
-}
-
-#endif /* _INCLUDE__BASE__IPC_H_ */
diff --git a/base-foc/src/base/ipc/ipc.cc b/base-foc/src/base/ipc/ipc.cc
index f33b7b989..e693d6367 100644
--- a/base-foc/src/base/ipc/ipc.cc
+++ b/base-foc/src/base/ipc/ipc.cc
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
/* base-foc/src/base/lock */
#include /* for 'thread_get_my_native_id()' */
@@ -42,6 +43,66 @@ using namespace Genode;
using namespace Fiasco;
+/*****************************
+ ** IPC marshalling support **
+ *****************************/
+
+void Ipc_ostream::_marshal_capability(Native_capability const &cap)
+{
+ /* first transfer local capability value */
+ _write_to_buf(cap.local());
+
+ /* if it's a local capability we're done */
+ if (cap.local())
+ return;
+
+ if (cap.valid()) {
+ if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) {
+ _write_to_buf(0);
+ return;
+ }
+ }
+
+ /* transfer capability id */
+ _write_to_buf(cap.local_name());
+
+ /* only transfer kernel-capability if it's a valid one */
+ if (cap.valid())
+ _snd_msg->snd_append_cap_sel(cap.dst());
+
+ ASSERT(!cap.valid() ||
+ l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst())),
+ "Send invalid cap");
+}
+
+
+void Ipc_istream::_unmarshal_capability(Native_capability &cap)
+{
+ long value = 0;
+
+ /* get local capability pointer from message buffer */
+ _read_from_buf(value);
+
+ /* if it's a local capability, the pointer is marshalled in the id */
+ if (value) {
+ cap = Capability::local_cap((Native_capability*)value);
+ return;
+ }
+
+ /* extract capability id from message buffer */
+ _read_from_buf(value);
+
+ /* if id is zero an invalid capability was transfered */
+ if (!value) {
+ cap = Native_capability();
+ return;
+ }
+
+ /* try to insert received capability in the map and return it */
+ cap = Native_capability(cap_map()->insert_map(value, _rcv_msg->rcv_cap_sel()));
+}
+
+
/***************
** Utilities **
***************/
diff --git a/base-host/lib/mk/ipc.mk b/base-host/lib/mk/ipc.mk
index 6e3e9b51a..52ec507d5 100644
--- a/base-host/lib/mk/ipc.mk
+++ b/base-host/lib/mk/ipc.mk
@@ -1,4 +1,5 @@
-SRC_CC = ipc.cc
+SRC_CC = ipc.cc ipc_marshal_cap.cc
LIBS = cap_copy
-vpath ipc.cc $(REP_DIR)/src/base/ipc
+vpath ipc.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-hw/lib/mk/raw_ipc.mk b/base-hw/lib/mk/raw_ipc.mk
index d9a9b3214..3b85980e7 100644
--- a/base-hw/lib/mk/raw_ipc.mk
+++ b/base-hw/lib/mk/raw_ipc.mk
@@ -1,12 +1,13 @@
#
-# \brief Interprocess communication without thread implementations
+# \brief Inter-process communication without thread implementations
# \author Martin Stein
# \date 2012-04-16
#
# add C++ source files
-SRC_CC += ipc.cc
+SRC_CC += ipc.cc ipc_marshal_cap.cc
# declare source paths
-vpath ipc.cc $(REP_DIR)/src/base
+vpath ipc.cc $(REP_DIR)/src/base
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-linux/include/base/ipc.h b/base-linux/include/base/ipc.h
deleted file mode 100644
index 269c9cbed..000000000
--- a/base-linux/include/base/ipc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * \brief Linux-specific supplements to the IPC framework
- * \author Norman Feske
- * \date 2012-07-26
- */
-
-/*
- * Copyright (C) 2012-2013 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__IPC_H_
-#define _INCLUDE__BASE__IPC_H_
-
-#include
-
-
-inline void Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
-{
- if (cap.valid()) {
- _write_to_buf(cap.local_name());
-
- _snd_msg->append_cap(cap.dst().socket);
- } else {
- _write_to_buf(-1L);
- }
-}
-
-
-inline void Genode::Ipc_istream::_unmarshal_capability(Genode::Native_capability &cap)
-{
- long local_name = 0;
- _read_from_buf(local_name);
-
- if (local_name == -1) {
-
- /* construct invalid capability */
- cap = Genode::Native_capability();
-
- } else {
-
- /* construct valid capability */
- int const socket = _rcv_msg->read_cap();
- cap = Native_capability(Cap_dst_policy::Dst(socket), local_name);
- }
-}
-
-#endif /* _INCLUDE__BASE__IPC_H_ */
diff --git a/base-linux/src/base/ipc/ipc.cc b/base-linux/src/base/ipc/ipc.cc
index 0d2d25f8f..f967db7cb 100644
--- a/base-linux/src/base/ipc/ipc.cc
+++ b/base-linux/src/base/ipc/ipc.cc
@@ -46,6 +46,41 @@
using namespace Genode;
+/*****************************
+ ** IPC marshalling support **
+ *****************************/
+
+void Ipc_ostream::_marshal_capability(Native_capability const &cap)
+{
+ if (cap.valid()) {
+ _write_to_buf(cap.local_name());
+
+ _snd_msg->append_cap(cap.dst().socket);
+ } else {
+ _write_to_buf(-1L);
+ }
+}
+
+
+void Ipc_istream::_unmarshal_capability(Native_capability &cap)
+{
+ long local_name = 0;
+ _read_from_buf(local_name);
+
+ if (local_name == -1) {
+
+ /* construct invalid capability */
+ cap = Genode::Native_capability();
+
+ } else {
+
+ /* construct valid capability */
+ int const socket = _rcv_msg->read_cap();
+ cap = Native_capability(Cap_dst_policy::Dst(socket), local_name);
+ }
+}
+
+
namespace Genode {
/*
diff --git a/base-mb/lib/mk/ipc.mk b/base-mb/lib/mk/ipc.mk
index 50249b5a6..46a5dcd7f 100755
--- a/base-mb/lib/mk/ipc.mk
+++ b/base-mb/lib/mk/ipc.mk
@@ -1,6 +1,7 @@
-SRC_CC = ipc.cc
+SRC_CC = ipc.cc ipc_marshal_cap.cc
SRC_CC += pager.cc
LIBS += thread_context cap_copy
-vpath ipc.cc $(REP_DIR)/src/base/ipc
-vpath pager.cc $(REP_DIR)/src/base/ipc
+vpath ipc.cc $(REP_DIR)/src/base/ipc
+vpath pager.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-nova/include/base/ipc.h b/base-nova/include/base/ipc.h
deleted file mode 100644
index 5ada0551e..000000000
--- a/base-nova/include/base/ipc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * \brief NOVA-specific supplements to the IPC framework
- * \author Norman Feske
- * \date 2010-01-27
- */
-
-/*
- * Copyright (C) 2010-2013 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__IPC_H_
-#define _INCLUDE__BASE__IPC_H_
-
-#include
-
-
-inline void
-Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
-{
- if (cap.valid())
- _snd_msg->snd_append_pt_sel(cap.local_name(),
- cap.dst().rights(),
- cap.trans_map());
-}
-
-
-inline void
-Genode::Ipc_istream::_unmarshal_capability(Genode::Native_capability &cap)
-{
- addr_t pt_sel = _rcv_msg->rcv_pt_sel();
- cap = Native_capability(pt_sel);
-}
-
-#endif /* _INCLUDE__BASE__IPC_H_ */
diff --git a/base-nova/src/base/ipc/ipc.cc b/base-nova/src/base/ipc/ipc.cc
index 077184c82..e56d45fff 100644
--- a/base-nova/src/base/ipc/ipc.cc
+++ b/base-nova/src/base/ipc/ipc.cc
@@ -24,6 +24,26 @@ using namespace Genode;
using namespace Nova;
+/*****************************
+ ** IPC marshalling support **
+ *****************************/
+
+void Ipc_ostream::_marshal_capability(Native_capability const &cap)
+{
+ if (cap.valid())
+ _snd_msg->snd_append_pt_sel(cap.local_name(),
+ cap.dst().rights(),
+ cap.trans_map());
+}
+
+
+void Ipc_istream::_unmarshal_capability(Native_capability &cap)
+{
+ addr_t pt_sel = _rcv_msg->rcv_pt_sel();
+ cap = Native_capability(pt_sel);
+}
+
+
/***************
** Utilities **
***************/
diff --git a/base-okl4/lib/mk/ipc.mk b/base-okl4/lib/mk/ipc.mk
index aac0969d0..282f5ab24 100644
--- a/base-okl4/lib/mk/ipc.mk
+++ b/base-okl4/lib/mk/ipc.mk
@@ -1,4 +1,5 @@
-SRC_CC = ipc.cc pager.cc
+SRC_CC = ipc.cc pager.cc ipc_marshal_cap.cc
LIBS = cap_copy
-vpath %.cc $(REP_DIR)/src/base/ipc
+vpath %.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base-pistachio/lib/mk/ipc.mk b/base-pistachio/lib/mk/ipc.mk
index cc39f1793..6ba207822 100644
--- a/base-pistachio/lib/mk/ipc.mk
+++ b/base-pistachio/lib/mk/ipc.mk
@@ -1,7 +1,8 @@
-SRC_CC = ipc.cc pager.cc
+SRC_CC = ipc.cc pager.cc ipc_marshal_cap.cc
LIBS = cap_copy
# disable warning about array boundaries, caused by L4 headers
CC_WARN = -Wall -Wno-array-bounds
-vpath %.cc $(REP_DIR)/src/base/ipc
+vpath %.cc $(REP_DIR)/src/base/ipc
+vpath ipc_marshal_cap.cc $(BASE_DIR)/src/base/ipc
diff --git a/base/include/base/ipc.h b/base/include/base/ipc.h
index fe5c61971..7a06d34a7 100644
--- a/base/include/base/ipc.h
+++ b/base/include/base/ipc.h
@@ -1,41 +1,632 @@
/*
* \brief Generic IPC infrastructure
* \author Norman Feske
- * \date 2009-10-02
+ * \date 2006-06-12
*
- * This file is used for platforms that only use the generic IPC API. A platform
- * may extend the generic API with platform-specific marshalling operators by
- * providing a custom version of 'ipc.h' in its 'base-' repository.
+ * Most of the marshalling and unmarshallung code is generic for IPC
+ * implementations among different platforms. In addition to the generic
+ * marshalling items, platform-specific marshalling items can be realized
+ * via specialized stream operators defined in the platform-specific
+ * 'base/ipc.h'. Hence, this header file is never to be included directly.
+ * It should only be included by a platform-specific 'base/ipc.h' file.
*/
/*
- * Copyright (C) 2009-2013 Genode Labs GmbH
+ * Copyright (C) 2006-2013 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__IPC_H_
-#define _INCLUDE__BASE__IPC_H_
+#ifndef _INCLUDE__BASE__IPC_GENERIC_H_
+#define _INCLUDE__BASE__IPC_GENERIC_H_
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
-/**
- * Marshalling of capabilities as plain data representation
- */
-inline void
-Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
-{
- _write_to_buf(cap);
+namespace Genode {
+
+ enum Ipc_ostream_send { IPC_SEND };
+ enum Ipc_istream_wait { IPC_WAIT };
+ enum Ipc_client_call { IPC_CALL };
+ enum Ipc_server_reply { IPC_REPLY };
+ enum Ipc_server_reply_wait { IPC_REPLY_WAIT };
+
+
+ /*********************
+ ** Exception types **
+ *********************/
+
+ class Ipc_error : public Exception { };
+
+
+ /**
+ * Marshal arguments into send message buffer
+ */
+ class Ipc_marshaller
+ {
+ protected:
+
+ char *_sndbuf;
+ size_t _sndbuf_size;
+ unsigned _write_offset;
+
+ protected:
+
+ /**
+ * Write value to send buffer
+ */
+ template
+ void _write_to_buf(T const &value)
+ {
+ /* check buffer range */
+ if (_write_offset + sizeof(T) >= _sndbuf_size) return;
+
+ /* write integer to buffer */
+ *reinterpret_cast(&_sndbuf[_write_offset]) = value;
+
+ /* increment write pointer to next dword-aligned value */
+ _write_offset += align_natural(sizeof(T));
+ }
+
+ /**
+ * Write bytes to send buffer
+ */
+ void _write_to_buf(char const *src_addr, unsigned num_bytes)
+ {
+ /* check buffer range */
+ if (_write_offset + num_bytes >= _sndbuf_size) return;
+
+ /* copy buffer */
+ memcpy(&_sndbuf[_write_offset], src_addr, num_bytes);
+
+ /* increment write pointer to next dword-aligned value */
+ _write_offset += align_natural(num_bytes);
+ }
+
+ /**
+ * Write 'Rpc_in_buffer' to send buffer
+ */
+ void _write_buffer_to_buf(Rpc_in_buffer_base const &b)
+ {
+ size_t size = b.size();
+ _write_to_buf(size);
+ _write_to_buf(b.base(), size);
+ }
+
+ /**
+ * Write array to send buffer
+ */
+ template
+ void _write_to_buf(T const (&array)[N])
+ {
+ /* check buffer range */
+ if (_write_offset + sizeof(array) >= _sndbuf_size)
+ PERR("send buffer overrun");
+
+ memcpy(&_sndbuf[_write_offset], array, sizeof(array));
+ _write_offset += align_natural(sizeof(array));
+ }
+
+ public:
+
+ Ipc_marshaller(char *sndbuf, size_t sndbuf_size)
+ : _sndbuf(sndbuf), _sndbuf_size(sndbuf_size), _write_offset(0) { }
+ };
+
+
+ /**
+ * Unmarshal arguments from receive buffer
+ */
+ class Ipc_unmarshaller
+ {
+ protected:
+
+ char *_rcvbuf;
+ size_t _rcvbuf_size;
+ unsigned _read_offset;
+
+ protected:
+
+ /**
+ * Read value of type T from buffer
+ */
+ template
+ void _read_from_buf(T &value)
+ {
+ /* check receive buffer range */
+ if (_read_offset + sizeof(T) >= _rcvbuf_size) return;
+
+ /* return value from receive buffer */
+ value = *reinterpret_cast(&_rcvbuf[_read_offset]);
+
+ /* increment read pointer to next dword-aligned value */
+ _read_offset += align_natural(sizeof(T));
+ }
+
+ /**
+ * Read 'Rpc_in_buffer' from receive buffer
+ */
+ void _read_bytebuf_from_buf(Rpc_in_buffer_base &b)
+ {
+ size_t size = 0;
+ _read_from_buf(size);
+ b = Rpc_in_buffer_base(0, 0);
+
+ /*
+ * Check receive buffer range
+ *
+ * Note: The addr of the Rpc_in_buffer_base is a null pointer when this
+ * condition triggers.
+ */
+ if (_read_offset + size >= _rcvbuf_size) {
+ PERR("message buffer overrun");
+ return;
+ }
+
+ b = Rpc_in_buffer_base(&_rcvbuf[_read_offset], size);
+ _read_offset += align_natural(size);
+ }
+
+ /**
+ * Read array from receive buffer
+ */
+ template
+ void _read_from_buf(T (&array)[N])
+ {
+ if (_read_offset + sizeof(array) >= _rcvbuf_size) {
+ PERR("receive buffer overrun");
+ return;
+ }
+
+ memcpy(array, &_rcvbuf[_read_offset], sizeof(array));
+ _read_offset += align_natural(sizeof(array));
+ }
+
+ /**
+ * Read long value at specified byte index of receive buffer
+ */
+ long _long_at_idx(int idx) { return *(long *)(&_rcvbuf[idx]); }
+
+ public:
+
+ Ipc_unmarshaller(char *rcvbuf, size_t rcvbuf_size)
+ : _rcvbuf(rcvbuf), _rcvbuf_size(rcvbuf_size), _read_offset(0) { }
+ };
+
+
+ /**
+ * Stream for sending information via a capability to an endpoint
+ */
+ class Ipc_ostream : public Ipc_marshaller
+ {
+ protected:
+
+ Msgbuf_base *_snd_msg; /* send message buffer */
+ Native_capability _dst;
+
+ /**
+ * Reset marshaller and write badge at the beginning of the message
+ */
+ void _prepare_next_send();
+
+ /**
+ * Send message in _snd_msg to _dst
+ */
+ void _send();
+
+ /**
+ * Insert capability to message buffer
+ */
+ void _marshal_capability(Native_capability const &cap);
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg);
+
+ /**
+ * Return true if Ipc_ostream is ready for send
+ */
+ bool ready_for_send() const { return _dst.valid(); }
+
+ /**
+ * Insert value into send buffer
+ */
+ template
+ Ipc_ostream &operator << (T const &value)
+ {
+ _write_to_buf(value);
+ return *this;
+ }
+
+ /**
+ * Insert byte buffer to send buffer
+ */
+ Ipc_ostream &operator << (Rpc_in_buffer_base const &b)
+ {
+ _write_buffer_to_buf(b);
+ return *this;
+ }
+
+ /**
+ * Insert capability to send buffer
+ */
+ Ipc_ostream &operator << (Native_capability const &cap)
+ {
+ _marshal_capability(cap);
+ return *this;
+ }
+
+ /**
+ * Insert typed capability to send buffer
+ */
+ template
+ Ipc_ostream &operator << (Capability const &typed_cap)
+ {
+ _marshal_capability(typed_cap);
+ return *this;
+ }
+
+ /**
+ * Issue the sending of the message buffer
+ */
+ Ipc_ostream &operator << (Ipc_ostream_send)
+ {
+ _send();
+ return *this;
+ }
+
+ /**
+ * Return current 'IPC_SEND' destination
+ *
+ * This function is typically needed by a server than sends replies
+ * in a different order as the incoming calls.
+ */
+ Native_capability dst() const { return _dst; }
+
+ /**
+ * Set destination for the next 'IPC_SEND'
+ */
+ void dst(Native_capability const &dst) { _dst = dst; }
+ };
+
+
+ /**
+ * Stream for receiving information
+ */
+ class Ipc_istream : public Ipc_unmarshaller, public Native_capability
+ {
+ private:
+
+ /**
+ * Prevent 'Ipc_istream' objects from being copied
+ *
+ * Copying an 'Ipc_istream' object would result in a duplicated
+ * (and possibly inconsistent) connection state both the original
+ * and the copied object.
+ */
+ Ipc_istream(const Ipc_istream &);
+
+ protected:
+
+ Msgbuf_base *_rcv_msg;
+ Native_connection_state _rcv_cs;
+
+ /**
+ * Obtain capability from message buffer
+ */
+ void _unmarshal_capability(Native_capability &cap);
+
+ protected:
+
+ /**
+ * Reset unmarshaller
+ */
+ void _prepare_next_receive();
+
+ /**
+ * Wait for incoming message to be received in _rcv_msg
+ */
+ void _wait();
+
+ public:
+
+ explicit Ipc_istream(Msgbuf_base *rcv_msg);
+
+ ~Ipc_istream();
+
+ /**
+ * Read badge that was supplied with the message
+ */
+ 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
+ */
+ template
+ Ipc_istream &operator >> (T &value)
+ {
+ _read_from_buf(value);
+ return *this;
+ }
+
+ /**
+ * Read byte buffer from receive buffer
+ */
+ Ipc_istream &operator >> (Rpc_in_buffer_base &b)
+ {
+ _read_bytebuf_from_buf(b);
+ return *this;
+ }
+
+ /**
+ * Read byte buffer from receive buffer
+ */
+ template
+ Ipc_istream &operator >> (Rpc_in_buffer &b)
+ {
+ _read_bytebuf_from_buf(b);
+ return *this;
+ }
+
+ /**
+ * Read capability from receive buffer
+ */
+ Ipc_istream &operator >> (Native_capability &cap)
+ {
+ _unmarshal_capability(cap);
+ return *this;
+ }
+
+ /**
+ * Read typed capability from receive buffer
+ */
+ template
+ Ipc_istream &operator >> (Capability &typed_cap)
+ {
+ _unmarshal_capability(typed_cap);
+ return *this;
+ }
+ };
+
+
+ class Ipc_client: public Ipc_istream, public Ipc_ostream
+ {
+ protected:
+
+ int _result; /* result of most recent call */
+
+ void _prepare_next_call();
+
+ /**
+ * Send RPC message and wait for result
+ */
+ void _call();
+
+ /**
+ * Set return value if call to server failed
+ */
+ void ret(int retval)
+ {
+ *reinterpret_cast(&_rcvbuf[sizeof(umword_t)]) = retval;
+ }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg,
+ Msgbuf_base *rcv_msg);
+
+ /**
+ * Operator that issues an IPC call
+ *
+ * \throw Ipc_error
+ * \throw Blocking_canceled
+ */
+ Ipc_client &operator << (Ipc_client_call)
+ {
+ _call();
+ _read_from_buf(_result);
+ if (_result == ERR_INVALID_OBJECT) {
+ PERR("tried to call an invalid object");
+ throw Ipc_error();
+ }
+ return *this;
+ }
+
+ template
+ Ipc_client &operator << (T const &value)
+ {
+ _write_to_buf(value);
+ return *this;
+ }
+
+ Ipc_client &operator << (Rpc_in_buffer_base const &b)
+ {
+ _write_buffer_to_buf(b);
+ return *this;
+ }
+
+ template
+ Ipc_client &operator << (Rpc_in_buffer const &b)
+ {
+ _write_buffer_to_buf(b);
+ return *this;
+ }
+
+ Ipc_client &operator << (Native_capability const &cap)
+ {
+ _marshal_capability(cap);
+ return *this;
+ }
+
+ template
+ Ipc_client &operator << (Capability const &typed_cap)
+ {
+ _marshal_capability(typed_cap);
+ return *this;
+ }
+
+ Ipc_client &operator >> (Native_capability &cap)
+ {
+ _unmarshal_capability(cap);
+ return *this;
+ }
+
+ template
+ Ipc_client &operator >> (Capability &typed_cap)
+ {
+ _unmarshal_capability(typed_cap);
+ return *this;
+ }
+
+ template
+ Ipc_client &operator >> (T &value)
+ {
+ _read_from_buf(value);
+ return *this;
+ }
+
+ Ipc_client &operator >> (Rpc_in_buffer_base &b)
+ {
+ _read_bytebuf_from_buf(b);
+ return *this;
+ }
+
+ int result() const { return _result; }
+ };
+
+
+ class Ipc_server : public Ipc_istream, public Ipc_ostream
+ {
+ protected:
+
+ bool _reply_needed; /* false for the first reply_wait */
+
+ void _prepare_next_reply_wait();
+
+ /**
+ * Wait for incoming call
+ *
+ * In constrast to 'Ipc_istream::_wait()', this function stores the
+ * next reply destination from into 'dst' of the 'Ipc_ostream'.
+ */
+ void _wait();
+
+ /**
+ * Send reply to destination
+ *
+ * In contrast to 'Ipc_ostream::_send()', this function prepares
+ * the 'Ipc_server' to send another subsequent reply without the
+ * calling '_wait()' in between. This is needed when a server
+ * answers calls out of order.
+ */
+ void _reply();
+
+ /**
+ * Send result of previous RPC request and wait for new one
+ */
+ void _reply_wait();
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg);
+
+ /**
+ * Set return value of server call
+ */
+ void ret(int retval)
+ {
+ *reinterpret_cast(&_sndbuf[sizeof(umword_t)]) = retval;
+ }
+
+ /**
+ * Set reply destination
+ */
+ void dst(Native_capability const &reply_dst)
+ {
+ Ipc_ostream::dst(reply_dst);
+ _reply_needed = reply_dst.valid();
+ }
+
+ using Ipc_ostream::dst;
+
+ /**
+ * Block for an incoming message filling the receive buffer
+ */
+ Ipc_server &operator >> (Ipc_istream_wait)
+ {
+ _wait();
+ return *this;
+ }
+
+ /**
+ * Issue the sending of the message buffer
+ */
+ Ipc_server &operator << (Ipc_server_reply)
+ {
+ _reply();
+ return *this;
+ }
+
+ /**
+ * Reply current request and wait for a new one
+ */
+ Ipc_server &operator >> (Ipc_server_reply_wait)
+ {
+ _reply_wait();
+ return *this;
+ }
+
+ /**
+ * Write value to send buffer
+ *
+ * This operator is only used by test programs
+ */
+ template
+ Ipc_server &operator << (T const &value)
+ {
+ _write_to_buf(value);
+ return *this;
+ }
+
+ /**
+ * Read value from receive buffer
+ *
+ * This operator should only be used by the server framework for
+ * reading the function offset. The server-side processing of the
+ * payload is done using 'Ipc_istream' and 'Ipc_ostream'.
+ */
+ template
+ Ipc_server &operator >> (T &value)
+ {
+ _read_from_buf(value);
+ return *this;
+ }
+ };
}
-/**
- * Unmarshalling of capabilities as plain data representation
- */
-inline void
-Genode::Ipc_istream::_unmarshal_capability(Genode::Native_capability &cap)
-{
- _read_from_buf(cap);
-}
-
-#endif /* _INCLUDE__BASE__IPC_H_ */
+#endif /* _INCLUDE__BASE__IPC_GENERIC_H_ */
diff --git a/base/include/base/ipc_generic.h b/base/include/base/ipc_generic.h
deleted file mode 100644
index 7a06d34a7..000000000
--- a/base/include/base/ipc_generic.h
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * \brief Generic IPC infrastructure
- * \author Norman Feske
- * \date 2006-06-12
- *
- * Most of the marshalling and unmarshallung code is generic for IPC
- * implementations among different platforms. In addition to the generic
- * marshalling items, platform-specific marshalling items can be realized
- * via specialized stream operators defined in the platform-specific
- * 'base/ipc.h'. Hence, this header file is never to be included directly.
- * It should only be included by a platform-specific 'base/ipc.h' file.
- */
-
-/*
- * Copyright (C) 2006-2013 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__IPC_GENERIC_H_
-#define _INCLUDE__BASE__IPC_GENERIC_H_
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace Genode {
-
- enum Ipc_ostream_send { IPC_SEND };
- enum Ipc_istream_wait { IPC_WAIT };
- enum Ipc_client_call { IPC_CALL };
- enum Ipc_server_reply { IPC_REPLY };
- enum Ipc_server_reply_wait { IPC_REPLY_WAIT };
-
-
- /*********************
- ** Exception types **
- *********************/
-
- class Ipc_error : public Exception { };
-
-
- /**
- * Marshal arguments into send message buffer
- */
- class Ipc_marshaller
- {
- protected:
-
- char *_sndbuf;
- size_t _sndbuf_size;
- unsigned _write_offset;
-
- protected:
-
- /**
- * Write value to send buffer
- */
- template
- void _write_to_buf(T const &value)
- {
- /* check buffer range */
- if (_write_offset + sizeof(T) >= _sndbuf_size) return;
-
- /* write integer to buffer */
- *reinterpret_cast(&_sndbuf[_write_offset]) = value;
-
- /* increment write pointer to next dword-aligned value */
- _write_offset += align_natural(sizeof(T));
- }
-
- /**
- * Write bytes to send buffer
- */
- void _write_to_buf(char const *src_addr, unsigned num_bytes)
- {
- /* check buffer range */
- if (_write_offset + num_bytes >= _sndbuf_size) return;
-
- /* copy buffer */
- memcpy(&_sndbuf[_write_offset], src_addr, num_bytes);
-
- /* increment write pointer to next dword-aligned value */
- _write_offset += align_natural(num_bytes);
- }
-
- /**
- * Write 'Rpc_in_buffer' to send buffer
- */
- void _write_buffer_to_buf(Rpc_in_buffer_base const &b)
- {
- size_t size = b.size();
- _write_to_buf(size);
- _write_to_buf(b.base(), size);
- }
-
- /**
- * Write array to send buffer
- */
- template
- void _write_to_buf(T const (&array)[N])
- {
- /* check buffer range */
- if (_write_offset + sizeof(array) >= _sndbuf_size)
- PERR("send buffer overrun");
-
- memcpy(&_sndbuf[_write_offset], array, sizeof(array));
- _write_offset += align_natural(sizeof(array));
- }
-
- public:
-
- Ipc_marshaller(char *sndbuf, size_t sndbuf_size)
- : _sndbuf(sndbuf), _sndbuf_size(sndbuf_size), _write_offset(0) { }
- };
-
-
- /**
- * Unmarshal arguments from receive buffer
- */
- class Ipc_unmarshaller
- {
- protected:
-
- char *_rcvbuf;
- size_t _rcvbuf_size;
- unsigned _read_offset;
-
- protected:
-
- /**
- * Read value of type T from buffer
- */
- template
- void _read_from_buf(T &value)
- {
- /* check receive buffer range */
- if (_read_offset + sizeof(T) >= _rcvbuf_size) return;
-
- /* return value from receive buffer */
- value = *reinterpret_cast(&_rcvbuf[_read_offset]);
-
- /* increment read pointer to next dword-aligned value */
- _read_offset += align_natural(sizeof(T));
- }
-
- /**
- * Read 'Rpc_in_buffer' from receive buffer
- */
- void _read_bytebuf_from_buf(Rpc_in_buffer_base &b)
- {
- size_t size = 0;
- _read_from_buf(size);
- b = Rpc_in_buffer_base(0, 0);
-
- /*
- * Check receive buffer range
- *
- * Note: The addr of the Rpc_in_buffer_base is a null pointer when this
- * condition triggers.
- */
- if (_read_offset + size >= _rcvbuf_size) {
- PERR("message buffer overrun");
- return;
- }
-
- b = Rpc_in_buffer_base(&_rcvbuf[_read_offset], size);
- _read_offset += align_natural(size);
- }
-
- /**
- * Read array from receive buffer
- */
- template
- void _read_from_buf(T (&array)[N])
- {
- if (_read_offset + sizeof(array) >= _rcvbuf_size) {
- PERR("receive buffer overrun");
- return;
- }
-
- memcpy(array, &_rcvbuf[_read_offset], sizeof(array));
- _read_offset += align_natural(sizeof(array));
- }
-
- /**
- * Read long value at specified byte index of receive buffer
- */
- long _long_at_idx(int idx) { return *(long *)(&_rcvbuf[idx]); }
-
- public:
-
- Ipc_unmarshaller(char *rcvbuf, size_t rcvbuf_size)
- : _rcvbuf(rcvbuf), _rcvbuf_size(rcvbuf_size), _read_offset(0) { }
- };
-
-
- /**
- * Stream for sending information via a capability to an endpoint
- */
- class Ipc_ostream : public Ipc_marshaller
- {
- protected:
-
- Msgbuf_base *_snd_msg; /* send message buffer */
- Native_capability _dst;
-
- /**
- * Reset marshaller and write badge at the beginning of the message
- */
- void _prepare_next_send();
-
- /**
- * Send message in _snd_msg to _dst
- */
- void _send();
-
- /**
- * Insert capability to message buffer
- */
- void _marshal_capability(Native_capability const &cap);
-
- public:
-
- /**
- * Constructor
- */
- Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg);
-
- /**
- * Return true if Ipc_ostream is ready for send
- */
- bool ready_for_send() const { return _dst.valid(); }
-
- /**
- * Insert value into send buffer
- */
- template
- Ipc_ostream &operator << (T const &value)
- {
- _write_to_buf(value);
- return *this;
- }
-
- /**
- * Insert byte buffer to send buffer
- */
- Ipc_ostream &operator << (Rpc_in_buffer_base const &b)
- {
- _write_buffer_to_buf(b);
- return *this;
- }
-
- /**
- * Insert capability to send buffer
- */
- Ipc_ostream &operator << (Native_capability const &cap)
- {
- _marshal_capability(cap);
- return *this;
- }
-
- /**
- * Insert typed capability to send buffer
- */
- template
- Ipc_ostream &operator << (Capability const &typed_cap)
- {
- _marshal_capability(typed_cap);
- return *this;
- }
-
- /**
- * Issue the sending of the message buffer
- */
- Ipc_ostream &operator << (Ipc_ostream_send)
- {
- _send();
- return *this;
- }
-
- /**
- * Return current 'IPC_SEND' destination
- *
- * This function is typically needed by a server than sends replies
- * in a different order as the incoming calls.
- */
- Native_capability dst() const { return _dst; }
-
- /**
- * Set destination for the next 'IPC_SEND'
- */
- void dst(Native_capability const &dst) { _dst = dst; }
- };
-
-
- /**
- * Stream for receiving information
- */
- class Ipc_istream : public Ipc_unmarshaller, public Native_capability
- {
- private:
-
- /**
- * Prevent 'Ipc_istream' objects from being copied
- *
- * Copying an 'Ipc_istream' object would result in a duplicated
- * (and possibly inconsistent) connection state both the original
- * and the copied object.
- */
- Ipc_istream(const Ipc_istream &);
-
- protected:
-
- Msgbuf_base *_rcv_msg;
- Native_connection_state _rcv_cs;
-
- /**
- * Obtain capability from message buffer
- */
- void _unmarshal_capability(Native_capability &cap);
-
- protected:
-
- /**
- * Reset unmarshaller
- */
- void _prepare_next_receive();
-
- /**
- * Wait for incoming message to be received in _rcv_msg
- */
- void _wait();
-
- public:
-
- explicit Ipc_istream(Msgbuf_base *rcv_msg);
-
- ~Ipc_istream();
-
- /**
- * Read badge that was supplied with the message
- */
- 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
- */
- template
- Ipc_istream &operator >> (T &value)
- {
- _read_from_buf(value);
- return *this;
- }
-
- /**
- * Read byte buffer from receive buffer
- */
- Ipc_istream &operator >> (Rpc_in_buffer_base &b)
- {
- _read_bytebuf_from_buf(b);
- return *this;
- }
-
- /**
- * Read byte buffer from receive buffer
- */
- template
- Ipc_istream &operator >> (Rpc_in_buffer &b)
- {
- _read_bytebuf_from_buf(b);
- return *this;
- }
-
- /**
- * Read capability from receive buffer
- */
- Ipc_istream &operator >> (Native_capability &cap)
- {
- _unmarshal_capability(cap);
- return *this;
- }
-
- /**
- * Read typed capability from receive buffer
- */
- template
- Ipc_istream &operator >> (Capability &typed_cap)
- {
- _unmarshal_capability(typed_cap);
- return *this;
- }
- };
-
-
- class Ipc_client: public Ipc_istream, public Ipc_ostream
- {
- protected:
-
- int _result; /* result of most recent call */
-
- void _prepare_next_call();
-
- /**
- * Send RPC message and wait for result
- */
- void _call();
-
- /**
- * Set return value if call to server failed
- */
- void ret(int retval)
- {
- *reinterpret_cast(&_rcvbuf[sizeof(umword_t)]) = retval;
- }
-
- public:
-
- /**
- * Constructor
- */
- Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg,
- Msgbuf_base *rcv_msg);
-
- /**
- * Operator that issues an IPC call
- *
- * \throw Ipc_error
- * \throw Blocking_canceled
- */
- Ipc_client &operator << (Ipc_client_call)
- {
- _call();
- _read_from_buf(_result);
- if (_result == ERR_INVALID_OBJECT) {
- PERR("tried to call an invalid object");
- throw Ipc_error();
- }
- return *this;
- }
-
- template
- Ipc_client &operator << (T const &value)
- {
- _write_to_buf(value);
- return *this;
- }
-
- Ipc_client &operator << (Rpc_in_buffer_base const &b)
- {
- _write_buffer_to_buf(b);
- return *this;
- }
-
- template
- Ipc_client &operator << (Rpc_in_buffer const &b)
- {
- _write_buffer_to_buf(b);
- return *this;
- }
-
- Ipc_client &operator << (Native_capability const &cap)
- {
- _marshal_capability(cap);
- return *this;
- }
-
- template
- Ipc_client &operator << (Capability const &typed_cap)
- {
- _marshal_capability(typed_cap);
- return *this;
- }
-
- Ipc_client &operator >> (Native_capability &cap)
- {
- _unmarshal_capability(cap);
- return *this;
- }
-
- template
- Ipc_client &operator >> (Capability &typed_cap)
- {
- _unmarshal_capability(typed_cap);
- return *this;
- }
-
- template
- Ipc_client &operator >> (T &value)
- {
- _read_from_buf(value);
- return *this;
- }
-
- Ipc_client &operator >> (Rpc_in_buffer_base &b)
- {
- _read_bytebuf_from_buf(b);
- return *this;
- }
-
- int result() const { return _result; }
- };
-
-
- class Ipc_server : public Ipc_istream, public Ipc_ostream
- {
- protected:
-
- bool _reply_needed; /* false for the first reply_wait */
-
- void _prepare_next_reply_wait();
-
- /**
- * Wait for incoming call
- *
- * In constrast to 'Ipc_istream::_wait()', this function stores the
- * next reply destination from into 'dst' of the 'Ipc_ostream'.
- */
- void _wait();
-
- /**
- * Send reply to destination
- *
- * In contrast to 'Ipc_ostream::_send()', this function prepares
- * the 'Ipc_server' to send another subsequent reply without the
- * calling '_wait()' in between. This is needed when a server
- * answers calls out of order.
- */
- void _reply();
-
- /**
- * Send result of previous RPC request and wait for new one
- */
- void _reply_wait();
-
- public:
-
- /**
- * Constructor
- */
- Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg);
-
- /**
- * Set return value of server call
- */
- void ret(int retval)
- {
- *reinterpret_cast(&_sndbuf[sizeof(umword_t)]) = retval;
- }
-
- /**
- * Set reply destination
- */
- void dst(Native_capability const &reply_dst)
- {
- Ipc_ostream::dst(reply_dst);
- _reply_needed = reply_dst.valid();
- }
-
- using Ipc_ostream::dst;
-
- /**
- * Block for an incoming message filling the receive buffer
- */
- Ipc_server &operator >> (Ipc_istream_wait)
- {
- _wait();
- return *this;
- }
-
- /**
- * Issue the sending of the message buffer
- */
- Ipc_server &operator << (Ipc_server_reply)
- {
- _reply();
- return *this;
- }
-
- /**
- * Reply current request and wait for a new one
- */
- Ipc_server &operator >> (Ipc_server_reply_wait)
- {
- _reply_wait();
- return *this;
- }
-
- /**
- * Write value to send buffer
- *
- * This operator is only used by test programs
- */
- template
- Ipc_server &operator << (T const &value)
- {
- _write_to_buf(value);
- return *this;
- }
-
- /**
- * Read value from receive buffer
- *
- * This operator should only be used by the server framework for
- * reading the function offset. The server-side processing of the
- * payload is done using 'Ipc_istream' and 'Ipc_ostream'.
- */
- template
- Ipc_server &operator >> (T &value)
- {
- _read_from_buf(value);
- return *this;
- }
- };
-}
-
-#endif /* _INCLUDE__BASE__IPC_GENERIC_H_ */
diff --git a/base/src/base/ipc/ipc_marshal_cap.cc b/base/src/base/ipc/ipc_marshal_cap.cc
new file mode 100644
index 000000000..3d62b3b03
--- /dev/null
+++ b/base/src/base/ipc/ipc_marshal_cap.cc
@@ -0,0 +1,34 @@
+/*
+ * \brief Marshalling/unmarshalling of plain-data capabilities
+ * \author Norman Feske
+ * \date 2013-02-13
+ */
+
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include
+
+using namespace Genode;
+
+
+/**
+ * Marshalling of capabilities as plain data representation
+ */
+void Ipc_ostream::_marshal_capability(Native_capability const &cap)
+{
+ _write_to_buf(cap);
+}
+
+
+/**
+ * Unmarshalling of capabilities as plain data representation
+ */
+void Ipc_istream::_unmarshal_capability(Native_capability &cap)
+{
+ _read_from_buf(cap);
+}
diff --git a/qt4/src/lib/qnitpickerviewwidget/qnitpickerviewwidget.cpp b/qt4/src/lib/qnitpickerviewwidget/qnitpickerviewwidget.cpp
index 70bdf86dd..5ac234ebf 100644
--- a/qt4/src/lib/qnitpickerviewwidget/qnitpickerviewwidget.cpp
+++ b/qt4/src/lib/qnitpickerviewwidget/qnitpickerviewwidget.cpp
@@ -4,7 +4,7 @@
* \date 2010-08-26
*/
-#include
+#include
#include