genode/repos/base-hw/src/core/kernel/signal_receiver.h

328 lines
7.2 KiB
C
Raw Normal View History

/*
* \brief Kernel backend for asynchronous inter-process communication
* \author Martin Stein
* \date 2012-11-30
*/
/*
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__KERNEL__SIGNAL_RECEIVER_H_
#define _CORE__KERNEL__SIGNAL_RECEIVER_H_
/* Genode includes */
#include <base/signal.h>
#include <util/reconstructible.h>
#include <kernel/core_interface.h>
#include <object.h>
namespace Kernel
{
/**
* Ability to receive signals from signal receivers
*/
class Signal_handler;
2013-09-12 00:48:27 +02:00
/**
* Ability to destruct signal contexts
*/
class Signal_context_killer;
/**
* Signal types that are assigned to a signal receiver each
*/
class Signal_context;
/**
* Combines signal contexts to an entity that handlers can listen to
*/
class Signal_receiver;
}
class Kernel::Signal_handler
{
friend class Signal_receiver;
private:
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
/*
* Noncopyable
*/
Signal_handler(Signal_handler const &);
Signal_handler &operator = (Signal_handler const &);
typedef Genode::Fifo_element<Signal_handler> Fifo_element;
Fifo_element _handlers_fe { *this };
Signal_receiver * _receiver { nullptr };
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;
protected:
/***************
** Accessors **
***************/
Signal_receiver * receiver() const { return _receiver; }
public:
Signal_handler() { }
virtual ~Signal_handler();
2013-09-19 16:13:51 +02:00
/**
* Stop waiting for a signal receiver
*/
void cancel_waiting();
2013-09-12 00:48:27 +02:00
};
class Kernel::Signal_context_killer
{
friend class Signal_context;
2013-09-12 00:48:27 +02:00
private:
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
/*
* Noncopyable
*/
Signal_context_killer(Signal_context_killer const &);
Signal_context_killer &operator = (Signal_context_killer const &);
Signal_context * _context;
2013-09-12 00:48:27 +02: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-12 00:48:27 +02:00
/**
* Notice that pending kill operation is done
2013-09-12 00:48:27 +02:00
*/
virtual void _signal_context_kill_done() = 0;
/**
* Notice that pending kill operation failed
*/
virtual void _signal_context_kill_failed() = 0;
protected:
/***************
** Accessors **
***************/
Signal_context * context() const { return _context; }
public:
Signal_context_killer();
virtual ~Signal_context_killer();
2013-09-19 16:13:51 +02:00
/**
* Stop waiting for a signal context
*/
void cancel_waiting();
2013-09-12 00:48:27 +02:00
};
class Kernel::Signal_context : public Kernel::Object
{
friend class Signal_receiver;
friend class Signal_context_killer;
private:
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
/*
* Noncopyable
*/
Signal_context(Signal_context const &);
Signal_context &operator = (Signal_context const &);
typedef Genode::Fifo_element<Signal_context> Fifo_element;
Fifo_element _deliver_fe { *this };
Fifo_element _contexts_fe { *this };
Signal_receiver & _receiver;
addr_t const _imprint;
Signal_context_killer * _killer { nullptr };
unsigned _submits { 0 };
bool _ack { true };
bool _killed { false };
/**
* Tell receiver about the submits of the context if any
*/
2013-09-12 00:48:27 +02:00
void _deliverable();
/**
* Called by receiver when all submits have been delivered
*/
void _delivered();
/**
* Notice that the killer of the context has cancelled waiting
*/
void _killer_cancelled();
public:
/**
* Destructor
*/
~Signal_context();
/**
* Constructor
*
* \param r receiver that the context shall be assigned to
* \param imprint userland identification of the context
*
* \throw Assign_to_receiver_failed
*/
Signal_context(Signal_receiver & r, addr_t const imprint);
/**
* Submit the signal
*
* \param n number of submits
2013-09-12 00:48:27 +02:00
*
* \retval 0 succeeded
* \retval -1 failed
*/
int submit(unsigned const n);
/**
* Acknowledge delivery of signal
*/
void ack();
/**
* 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-12 00:48:27 +02:00
* \retval 0 succeeded
* \retval -1 failed
*/
int kill(Signal_context_killer * const k);
/**
* 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(Genode::Kernel_object<Signal_context> &c,
Signal_receiver & receiver,
addr_t const imprint)
{
return call(call_id_new_signal_context(), (Call_arg)&c,
(Call_arg)&receiver, (Call_arg)imprint);
}
/**
* Destruct a signal context
*
* \param context pointer to signal context kernel object
*/
static void syscall_destroy(Genode::Kernel_object<Signal_context> &c) {
call(call_id_delete_signal_context(), (Call_arg)&c); }
};
class Kernel::Signal_receiver : public Kernel::Object
{
friend class Signal_context;
2013-09-19 16:13:51 +02:00
friend class Signal_handler;
private:
typedef Genode::Signal Signal;
template <typename T> class Fifo : public Genode::Fifo<T> { };
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Fifo<Signal_handler::Fifo_element> _handlers { };
Fifo<Signal_context::Fifo_element> _deliver { };
Fifo<Signal_context::Fifo_element> _contexts { };
/**
* Recognize that context 'c' has submits to deliver
*/
void _add_deliverable(Signal_context * const c);
/**
* Deliver as much submits as possible
*/
void _listen();
2013-09-12 00:48:27 +02:00
/**
* Notice that a context of the receiver has been destructed
2013-09-12 00:48:27 +02:00
*
* \param c destructed context
2013-09-12 00:48:27 +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
*/
void _handler_cancelled(Signal_handler * const h);
/**
* Assign context 'c' to the receiver
*/
void _add_context(Signal_context * const c);
2013-09-12 00:48:27 +02:00
public:
~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
*/
int add_handler(Signal_handler * const h);
/**
* 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(Genode::Kernel_object<Signal_receiver> &r) {
return call(call_id_new_signal_receiver(), (Call_arg)&r); }
/**
* Syscall to destruct a signal receiver
*
* \param receiver pointer to signal receiver kernel object
*/
static void syscall_destroy(Genode::Kernel_object<Signal_receiver> &r) {
call(call_id_delete_signal_receiver(), (Call_arg)&r); }
2013-09-12 00:48:27 +02:00
};
#endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */