2013-09-05 13:40:54 +02:00
|
|
|
/*
|
2013-09-13 01:06:54 +02:00
|
|
|
* \brief Backend for end points of synchronous interprocess communication
|
2013-09-05 13:40:54 +02:00
|
|
|
* \author Martin Stein
|
2015-05-19 14:18:40 +02:00
|
|
|
* \author Stefan Kalkowski
|
2013-09-05 13:40:54 +02:00
|
|
|
* \date 2012-11-30
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2019-01-29 19:29:03 +01:00
|
|
|
* Copyright (C) 2012-2019 Genode Labs GmbH
|
2013-09-05 13:40:54 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
|
|
|
|
2017-04-12 10:06:29 +02:00
|
|
|
#ifndef _CORE__KERNEL__IPC_NODE_H_
|
|
|
|
#define _CORE__KERNEL__IPC_NODE_H_
|
2013-09-05 13:40:54 +02:00
|
|
|
|
2019-04-19 18:41:14 +02:00
|
|
|
/* Genode includes */
|
|
|
|
#include <util/fifo.h>
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
namespace Kernel
|
|
|
|
{
|
2019-04-19 18:41:14 +02:00
|
|
|
class Thread;
|
2015-05-19 14:18:40 +02:00
|
|
|
|
2013-09-05 13:40:54 +02:00
|
|
|
/**
|
2013-09-13 01:06:54 +02:00
|
|
|
* Backend for end points of synchronous interprocess communication
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
|
|
|
class Ipc_node;
|
|
|
|
}
|
|
|
|
|
2019-04-20 02:44:59 +02:00
|
|
|
class Kernel::Ipc_node
|
2013-09-05 13:40:54 +02:00
|
|
|
{
|
2019-04-20 02:44:59 +02:00
|
|
|
private:
|
|
|
|
|
|
|
|
using Queue_item = Genode::Fifo_element<Ipc_node>;
|
|
|
|
using Queue = Genode::Fifo<Queue_item>;
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
enum State
|
|
|
|
{
|
2015-09-15 13:20:35 +02:00
|
|
|
INACTIVE = 1,
|
|
|
|
AWAIT_REPLY = 2,
|
|
|
|
AWAIT_REQUEST = 3,
|
2013-09-05 13:40:54 +02:00
|
|
|
};
|
|
|
|
|
2019-04-20 02:44:59 +02:00
|
|
|
Thread &_thread;
|
|
|
|
Queue_item _request_queue_item { *this };
|
|
|
|
State _state { INACTIVE };
|
|
|
|
Ipc_node *_caller { nullptr };
|
|
|
|
Ipc_node *_callee { nullptr };
|
|
|
|
bool _help { false };
|
|
|
|
Queue _request_queue { };
|
2013-11-28 00:44:54 +01:00
|
|
|
|
2013-09-05 13:40:54 +02:00
|
|
|
/**
|
|
|
|
* Buffer next request from request queue in 'r' to handle it
|
|
|
|
*/
|
base/core: use references instead of pointers
This patch replaces the former prominent use of pointers by references
wherever feasible. This has the following benefits:
* The contract between caller and callee becomes more obvious. When
passing a reference, the contract says that the argument cannot be
a null pointer. The caller is responsible to ensure that. Therefore,
the use of reference eliminates the need to add defensive null-pointer
checks at the callee site, which sometimes merely exist to be on the
safe side. The bottom line is that the code becomes easier to follow.
* Reference members must be initialized via an object initializer,
which promotes a programming style that avoids intermediate object-
construction states. Within core, there are still a few pointers
as member variables left though. E.g., caused by the late association
of 'Platform_thread' objects with their 'Platform_pd' objects.
* If no pointers are present as member variables, we don't need to
manually provide declarations of a private copy constructor and
an assignment operator to avoid -Weffc++ errors "class ... has
pointer data members [-Werror=effc++]".
This patch also changes a few system bindings on NOVA and Fiasco.OC,
e.g., the return value of the global 'cap_map' accessor has become a
reference. Hence, the patch touches a few places outside of core.
Fixes #3135
2019-01-24 22:00:01 +01:00
|
|
|
void _receive_request(Ipc_node &caller);
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Receive a given reply if one is expected
|
|
|
|
*/
|
base/core: use references instead of pointers
This patch replaces the former prominent use of pointers by references
wherever feasible. This has the following benefits:
* The contract between caller and callee becomes more obvious. When
passing a reference, the contract says that the argument cannot be
a null pointer. The caller is responsible to ensure that. Therefore,
the use of reference eliminates the need to add defensive null-pointer
checks at the callee site, which sometimes merely exist to be on the
safe side. The bottom line is that the code becomes easier to follow.
* Reference members must be initialized via an object initializer,
which promotes a programming style that avoids intermediate object-
construction states. Within core, there are still a few pointers
as member variables left though. E.g., caused by the late association
of 'Platform_thread' objects with their 'Platform_pd' objects.
* If no pointers are present as member variables, we don't need to
manually provide declarations of a private copy constructor and
an assignment operator to avoid -Weffc++ errors "class ... has
pointer data members [-Werror=effc++]".
This patch also changes a few system bindings on NOVA and Fiasco.OC,
e.g., the return value of the global 'cap_map' accessor has become a
reference. Hence, the patch touches a few places outside of core.
Fixes #3135
2019-01-24 22:00:01 +01:00
|
|
|
void _receive_reply(Ipc_node &callee);
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert 'r' into request queue, buffer it if we were waiting for it
|
|
|
|
*/
|
base/core: use references instead of pointers
This patch replaces the former prominent use of pointers by references
wherever feasible. This has the following benefits:
* The contract between caller and callee becomes more obvious. When
passing a reference, the contract says that the argument cannot be
a null pointer. The caller is responsible to ensure that. Therefore,
the use of reference eliminates the need to add defensive null-pointer
checks at the callee site, which sometimes merely exist to be on the
safe side. The bottom line is that the code becomes easier to follow.
* Reference members must be initialized via an object initializer,
which promotes a programming style that avoids intermediate object-
construction states. Within core, there are still a few pointers
as member variables left though. E.g., caused by the late association
of 'Platform_thread' objects with their 'Platform_pd' objects.
* If no pointers are present as member variables, we don't need to
manually provide declarations of a private copy constructor and
an assignment operator to avoid -Weffc++ errors "class ... has
pointer data members [-Werror=effc++]".
This patch also changes a few system bindings on NOVA and Fiasco.OC,
e.g., the return value of the global 'cap_map' accessor has become a
reference. Hence, the patch touches a few places outside of core.
Fixes #3135
2019-01-24 22:00:01 +01:00
|
|
|
void _announce_request(Ipc_node &node);
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-16 17:01:52 +02:00
|
|
|
* Cancel all requests in request queue
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _cancel_request_queue();
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-16 17:01:52 +02:00
|
|
|
* Cancel request in outgoing buffer
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _cancel_outbuf_request();
|
2013-09-05 13:40:54 +02:00
|
|
|
|
2013-09-16 17:01:52 +02:00
|
|
|
/**
|
|
|
|
* Cancel request in incoming buffer
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _cancel_inbuf_request();
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-16 17:01:52 +02:00
|
|
|
* A request 'r' in inbuf or request queue was cancelled by sender
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
base/core: use references instead of pointers
This patch replaces the former prominent use of pointers by references
wherever feasible. This has the following benefits:
* The contract between caller and callee becomes more obvious. When
passing a reference, the contract says that the argument cannot be
a null pointer. The caller is responsible to ensure that. Therefore,
the use of reference eliminates the need to add defensive null-pointer
checks at the callee site, which sometimes merely exist to be on the
safe side. The bottom line is that the code becomes easier to follow.
* Reference members must be initialized via an object initializer,
which promotes a programming style that avoids intermediate object-
construction states. Within core, there are still a few pointers
as member variables left though. E.g., caused by the late association
of 'Platform_thread' objects with their 'Platform_pd' objects.
* If no pointers are present as member variables, we don't need to
manually provide declarations of a private copy constructor and
an assignment operator to avoid -Weffc++ errors "class ... has
pointer data members [-Werror=effc++]".
This patch also changes a few system bindings on NOVA and Fiasco.OC,
e.g., the return value of the global 'cap_map' accessor has become a
reference. Hence, the patch touches a few places outside of core.
Fixes #3135
2019-01-24 22:00:01 +01:00
|
|
|
void _announced_request_cancelled(Ipc_node &node);
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-16 17:01:52 +02:00
|
|
|
* The request in the outbuf was cancelled by receiver
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _outbuf_request_cancelled();
|
2013-09-16 17:01:52 +02:00
|
|
|
|
2014-12-01 15:10:33 +01:00
|
|
|
/**
|
|
|
|
* Return wether we are the source of a helping relationship
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
bool _helps_outbuf_dst();
|
2014-12-01 15:10:33 +01:00
|
|
|
|
2013-09-16 17:01:52 +02:00
|
|
|
/**
|
2019-04-19 18:41:14 +02:00
|
|
|
* Make the class noncopyable because it has pointer members
|
2013-09-16 17:01:52 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
Ipc_node(const Ipc_node&) = delete;
|
2013-09-16 17:01:52 +02:00
|
|
|
|
|
|
|
/**
|
2019-04-19 18:41:14 +02:00
|
|
|
* Make the class noncopyable because it has pointer members
|
2013-09-16 17:01:52 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
const Ipc_node& operator=(const Ipc_node&) = delete;
|
|
|
|
|
|
|
|
public:
|
2014-04-04 13:41:04 +02:00
|
|
|
|
|
|
|
/**
|
2019-04-19 18:41:14 +02:00
|
|
|
* Destructor
|
2014-04-04 13:41:04 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
~Ipc_node();
|
2014-04-04 13:41:04 +02:00
|
|
|
|
|
|
|
/**
|
2019-04-19 18:41:14 +02:00
|
|
|
* Constructor
|
2014-04-04 13:41:04 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
Ipc_node(Thread &thread);
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a request and wait for the according reply
|
|
|
|
*
|
2015-05-19 14:18:40 +02:00
|
|
|
* \param callee targeted IPC node
|
2014-12-01 15:10:33 +01:00
|
|
|
* \param help wether the request implies a helping relationship
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
bool can_send_request();
|
2019-04-25 02:45:03 +02:00
|
|
|
void send_request(Ipc_node &callee,
|
|
|
|
bool help);
|
2014-12-01 15:10:33 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return root destination of the helping-relation tree we are in
|
|
|
|
*/
|
2019-04-25 02:45:03 +02:00
|
|
|
Thread &helping_sink();
|
2014-12-01 15:10:33 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call function 'f' of type 'void (Ipc_node *)' for each helper
|
|
|
|
*/
|
|
|
|
template <typename F> void for_each_helper(F f)
|
|
|
|
{
|
|
|
|
/* if we have a helper in the receive buffer, call 'f' for it */
|
2019-04-25 02:45:03 +02:00
|
|
|
if (_caller && _caller->_help) f(_caller->_thread);
|
2014-12-01 15:10:33 +01:00
|
|
|
|
|
|
|
/* call 'f' for each helper in our request queue */
|
2019-04-20 02:44:59 +02:00
|
|
|
_request_queue.for_each([f] (Queue_item &item) {
|
|
|
|
Ipc_node &node { item.object() };
|
2019-04-25 02:45:03 +02:00
|
|
|
if (node._help) f(node._thread);
|
2019-04-20 02:44:59 +02:00
|
|
|
});
|
2013-09-05 13:40:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wait until a request has arrived and load it for handling
|
|
|
|
*
|
2014-03-27 12:20:55 +01:00
|
|
|
* \return wether a request could be received already
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
2019-04-19 18:41:14 +02:00
|
|
|
bool can_await_request();
|
2019-04-25 02:45:03 +02:00
|
|
|
void await_request();
|
2013-09-05 13:40:54 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reply to last request if there's any
|
|
|
|
*/
|
2015-05-19 14:18:40 +02:00
|
|
|
void send_reply();
|
2013-09-16 17:01:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If IPC node waits, cancel '_outbuf' to stop waiting
|
2013-09-05 13:40:54 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void cancel_waiting();
|
2015-05-19 14:18:40 +02:00
|
|
|
|
2019-04-25 02:45:03 +02:00
|
|
|
bool awaits_request() const { return _state == AWAIT_REQUEST; }
|
2013-09-05 13:40:54 +02:00
|
|
|
};
|
|
|
|
|
2017-04-12 10:06:29 +02:00
|
|
|
#endif /* _CORE__KERNEL__IPC_NODE_H_ */
|