2013-09-06 01:27:53 +02:00
|
|
|
/*
|
|
|
|
* \brief Kernel backend for asynchronous inter-process communication
|
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2012-11-30
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2012-2017 Genode Labs GmbH
|
2013-09-06 01:27:53 +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-06 01:27:53 +02:00
|
|
|
*/
|
|
|
|
|
2017-04-12 10:06:29 +02:00
|
|
|
#ifndef _CORE__KERNEL__SIGNAL_RECEIVER_H_
|
|
|
|
#define _CORE__KERNEL__SIGNAL_RECEIVER_H_
|
2013-09-06 01:27:53 +02:00
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/signal.h>
|
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
#include <kernel/core_interface.h>
|
2013-09-06 01:27:53 +02:00
|
|
|
#include <kernel/object.h>
|
|
|
|
|
|
|
|
namespace Kernel
|
|
|
|
{
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
2013-11-14 13:29:47 +01:00
|
|
|
* Ability to receive signals from signal receivers
|
2013-09-06 01:36:03 +02:00
|
|
|
*/
|
|
|
|
class Signal_handler;
|
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
/**
|
|
|
|
* Ability to destruct signal contexts
|
|
|
|
*/
|
|
|
|
class Signal_context_killer;
|
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
|
|
|
* Signal types that are assigned to a signal receiver each
|
|
|
|
*/
|
|
|
|
class Signal_context;
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
|
|
|
* Combines signal contexts to an entity that handlers can listen to
|
|
|
|
*/
|
2013-09-06 01:27:53 +02:00
|
|
|
class Signal_receiver;
|
2013-09-06 01:36:03 +02:00
|
|
|
}
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-11-14 13:29:47 +01:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
class Kernel::Signal_handler
|
|
|
|
{
|
|
|
|
friend class Signal_receiver;
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
private:
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
|
|
|
|
|
2013-09-17 10:44:14 +02:00
|
|
|
Fifo_element _handlers_fe;
|
|
|
|
Signal_receiver * _receiver;
|
2013-09-12 21:13:22 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Let the handler block for signal receipt
|
|
|
|
*
|
|
|
|
* \param receiver the signal pool that the thread blocks for
|
|
|
|
*/
|
|
|
|
virtual void _await_signal(Signal_receiver * const receiver) = 0;
|
2013-09-12 00:48:27 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Signal delivery backend
|
|
|
|
*
|
|
|
|
* \param base signal-data base
|
|
|
|
* \param size signal-data size
|
|
|
|
*/
|
2013-09-12 21:13:22 +02:00
|
|
|
virtual void _receive_signal(void * const base, size_t const size) = 0;
|
2013-09-06 01:36:03 +02:00
|
|
|
|
2013-11-28 00:42:48 +01:00
|
|
|
protected:
|
|
|
|
|
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
Signal_receiver * receiver() const { return _receiver; }
|
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
public:
|
|
|
|
|
2015-04-16 11:25:23 +02:00
|
|
|
Signal_handler();
|
|
|
|
virtual ~Signal_handler();
|
2013-09-19 16:13:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop waiting for a signal receiver
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void cancel_waiting();
|
2013-09-12 00:48:27 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class Kernel::Signal_context_killer
|
|
|
|
{
|
|
|
|
friend class Signal_context;
|
2013-09-06 01:36:03 +02:00
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
private:
|
2013-09-06 01:36:03 +02:00
|
|
|
|
2013-09-17 10:44:14 +02:00
|
|
|
Signal_context * _context;
|
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
/**
|
2013-12-06 00:12:43 +01:00
|
|
|
* Notice that the kill operation is pending
|
2013-09-12 00:48:27 +02:00
|
|
|
*/
|
|
|
|
virtual void _signal_context_kill_pending() = 0;
|
2013-09-06 01:36:03 +02:00
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
/**
|
2013-12-06 00:12:43 +01:00
|
|
|
* Notice that pending kill operation is done
|
2013-09-12 00:48:27 +02:00
|
|
|
*/
|
|
|
|
virtual void _signal_context_kill_done() = 0;
|
2013-09-17 10:44:14 +02:00
|
|
|
|
2013-12-06 00:12:43 +01:00
|
|
|
/**
|
|
|
|
* Notice that pending kill operation failed
|
|
|
|
*/
|
|
|
|
virtual void _signal_context_kill_failed() = 0;
|
|
|
|
|
2013-11-28 00:42:48 +01:00
|
|
|
protected:
|
|
|
|
|
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
Signal_context * context() const { return _context; }
|
|
|
|
|
2013-09-17 10:44:14 +02:00
|
|
|
public:
|
|
|
|
|
2015-04-16 11:25:23 +02:00
|
|
|
Signal_context_killer();
|
|
|
|
virtual ~Signal_context_killer();
|
2013-09-19 16:13:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop waiting for a signal context
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void cancel_waiting();
|
2013-09-12 00:48:27 +02:00
|
|
|
};
|
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
class Kernel::Signal_context : public Kernel::Object
|
2013-09-06 01:36:03 +02:00
|
|
|
{
|
|
|
|
friend class Signal_receiver;
|
2013-09-17 10:44:14 +02:00
|
|
|
friend class Signal_context_killer;
|
2013-09-06 01:36:03 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef Genode::Fifo_element<Signal_context> Fifo_element;
|
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
Fifo_element _deliver_fe;
|
|
|
|
Fifo_element _contexts_fe;
|
2013-09-06 01:36:03 +02:00
|
|
|
Signal_receiver * const _receiver;
|
2017-08-21 15:34:27 +02:00
|
|
|
addr_t const _imprint;
|
2013-09-06 01:36:03 +02:00
|
|
|
unsigned _submits;
|
|
|
|
bool _ack;
|
2013-12-06 00:12:43 +01:00
|
|
|
bool _killed;
|
2013-09-12 00:48:27 +02:00
|
|
|
Signal_context_killer * _killer;
|
2013-09-06 01:27:53 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-06 01:36:03 +02:00
|
|
|
* Tell receiver about the submits of the context if any
|
2013-09-06 01:27:53 +02:00
|
|
|
*/
|
2013-09-12 00:48:27 +02:00
|
|
|
void _deliverable();
|
2013-09-06 01:27:53 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by receiver when all submits have been delivered
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _delivered();
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-17 10:44:14 +02:00
|
|
|
/**
|
2013-12-06 00:12:43 +01:00
|
|
|
* Notice that the killer of the context has cancelled waiting
|
2013-09-17 10:44:14 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _killer_cancelled();
|
2013-09-17 10:44:14 +02:00
|
|
|
|
2013-12-06 00:12:43 +01:00
|
|
|
public:
|
2013-10-30 13:56:57 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
~Signal_context();
|
|
|
|
|
2013-10-30 15:49:12 +01:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \param r receiver that the context shall be assigned to
|
|
|
|
* \param imprint userland identification of the context
|
|
|
|
*
|
|
|
|
* \throw Assign_to_receiver_failed
|
|
|
|
*/
|
2017-08-21 15:34:27 +02:00
|
|
|
Signal_context(Signal_receiver * const r, addr_t const imprint);
|
2013-10-30 15:49:12 +01:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
|
|
|
* Submit the signal
|
|
|
|
*
|
|
|
|
* \param n number of submits
|
2013-09-12 00:48:27 +02:00
|
|
|
*
|
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
2013-09-06 01:36:03 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
int submit(unsigned const n);
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
|
|
|
* Acknowledge delivery of signal
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void ack();
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
/**
|
|
|
|
* Destruct context or prepare to do it as soon as delivery is done
|
|
|
|
*
|
2013-09-12 00:48:27 +02:00
|
|
|
* \param killer object that shall receive progress reports
|
2013-09-06 01:36:03 +02:00
|
|
|
*
|
2013-09-12 00:48:27 +02:00
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
2013-09-06 01:36:03 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
int kill(Signal_context_killer * const k);
|
2015-05-19 14:18:40 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a signal context and assign it to a signal receiver
|
|
|
|
*
|
|
|
|
* \param p memory donation for the kernel signal-context object
|
|
|
|
* \param receiver pointer to signal receiver kernel object
|
|
|
|
* \param imprint user label of the signal context
|
|
|
|
*
|
|
|
|
* \retval capability id of the new kernel object
|
|
|
|
*/
|
|
|
|
static capid_t syscall_create(void * p,
|
|
|
|
Signal_receiver * const receiver,
|
2015-06-22 14:44:28 +02:00
|
|
|
addr_t const imprint)
|
2015-05-19 14:18:40 +02:00
|
|
|
{
|
|
|
|
return call(call_id_new_signal_context(), (Call_arg)p,
|
|
|
|
(Call_arg)receiver, (Call_arg)imprint);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct a signal context
|
|
|
|
*
|
|
|
|
* \param context pointer to signal context kernel object
|
|
|
|
*/
|
|
|
|
static void syscall_destroy(Signal_context * const context) {
|
|
|
|
call(call_id_delete_signal_context(), (Call_arg)context); }
|
2013-09-06 01:36:03 +02:00
|
|
|
};
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
class Kernel::Signal_receiver : public Kernel::Object
|
2013-09-06 01:36:03 +02:00
|
|
|
{
|
|
|
|
friend class Signal_context;
|
2013-09-19 16:13:51 +02:00
|
|
|
friend class Signal_handler;
|
2013-09-06 01:36:03 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef Genode::Signal Signal;
|
|
|
|
|
|
|
|
template <typename T> class Fifo : public Genode::Fifo<T> { };
|
|
|
|
|
|
|
|
Fifo<Signal_handler::Fifo_element> _handlers;
|
2013-09-12 00:48:27 +02:00
|
|
|
Fifo<Signal_context::Fifo_element> _deliver;
|
|
|
|
Fifo<Signal_context::Fifo_element> _contexts;
|
2013-09-06 01:27:53 +02:00
|
|
|
|
|
|
|
/**
|
2013-09-06 01:36:03 +02:00
|
|
|
* Recognize that context 'c' has submits to deliver
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _add_deliverable(Signal_context * const c);
|
2013-09-06 01:36:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Deliver as much submits as possible
|
2013-09-06 01:27:53 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _listen();
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2013-09-12 00:48:27 +02:00
|
|
|
/**
|
2013-12-06 00:12:43 +01:00
|
|
|
* Notice that a context of the receiver has been destructed
|
2013-09-12 00:48:27 +02:00
|
|
|
*
|
2013-12-06 11:53:08 +01:00
|
|
|
* \param c destructed context
|
2013-09-12 00:48:27 +02:00
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _context_destructed(Signal_context * const c);
|
2013-09-12 00:48:27 +02:00
|
|
|
|
2013-09-19 16:13:51 +02:00
|
|
|
/**
|
|
|
|
* Notice that handler 'h' has cancelled waiting
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _handler_cancelled(Signal_handler * const h);
|
2013-09-17 10:44:14 +02:00
|
|
|
|
2013-10-30 15:49:12 +01:00
|
|
|
/**
|
|
|
|
* Assign context 'c' to the receiver
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
void _add_context(Signal_context * const c);
|
2013-09-12 00:48:27 +02:00
|
|
|
|
2013-09-06 01:36:03 +02:00
|
|
|
public:
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2015-04-16 11:25:23 +02:00
|
|
|
~Signal_receiver();
|
2013-09-12 00:48:27 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Let a handler 'h' wait for signals of the receiver
|
|
|
|
*
|
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
2015-04-16 11:25:23 +02:00
|
|
|
int add_handler(Signal_handler * const h);
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2015-05-19 14:18:40 +02:00
|
|
|
/**
|
|
|
|
* Syscall to create a signal receiver
|
|
|
|
*
|
|
|
|
* \param p memory donation for the kernel signal-receiver object
|
|
|
|
*
|
|
|
|
* \retval capability id of the new kernel object
|
|
|
|
*/
|
|
|
|
static capid_t syscall_create(void * p) {
|
|
|
|
return call(call_id_new_signal_receiver(), (Call_arg)p); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Syscall to destruct a signal receiver
|
|
|
|
*
|
|
|
|
* \param receiver pointer to signal receiver kernel object
|
|
|
|
*/
|
|
|
|
static void syscall_destroy(Signal_receiver * const receiver) {
|
|
|
|
call(call_id_delete_signal_receiver(), (Call_arg)receiver); }
|
2013-09-12 00:48:27 +02:00
|
|
|
};
|
2013-09-06 01:27:53 +02:00
|
|
|
|
2017-04-12 10:06:29 +02:00
|
|
|
#endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */
|