diff --git a/base-hw/src/core/kernel/irq.h b/base-hw/src/core/kernel/irq.h index 9cd2a79d16..dd6b760a30 100644 --- a/base-hw/src/core/kernel/irq.h +++ b/base-hw/src/core/kernel/irq.h @@ -142,7 +142,7 @@ class Kernel::Irq Irq(unsigned const irq_id) : Pool::Item(irq_id), - Signal_context(this) + Signal_context(this, 0) { _pool()->insert(this); _disable(); diff --git a/base-hw/src/core/kernel/signal_receiver.cc b/base-hw/src/core/kernel/signal_receiver.cc index 694b84091a..8f5a8f44bb 100644 --- a/base-hw/src/core/kernel/signal_receiver.cc +++ b/base-hw/src/core/kernel/signal_receiver.cc @@ -45,10 +45,10 @@ void Signal_context::_deliverable() Signal_context::~Signal_context() { _receiver->_context_killed(this); } -Signal_context::Signal_context(Signal_receiver * const r) +Signal_context::Signal_context(Signal_receiver * const r, unsigned const imprint) : _deliver_fe(this), _contexts_fe(this), _receiver(r), - _imprint(Object::id()), _submits(0), _ack(1), _kill(0), _killer(0) + _imprint(imprint), _submits(0), _ack(1), _kill(0), _killer(0) { - r->add_context(this); + if (r->_add_context(this)) { throw Assign_to_receiver_failed(); } } diff --git a/base-hw/src/core/kernel/signal_receiver.h b/base-hw/src/core/kernel/signal_receiver.h index 71d32b598e..b75eec7cfa 100644 --- a/base-hw/src/core/kernel/signal_receiver.h +++ b/base-hw/src/core/kernel/signal_receiver.h @@ -231,18 +231,6 @@ class Kernel::Signal_context */ void _killer_cancelled() { _killer = 0; } - /** - * Constructor that is used by signal receivers - * - * \param r receiver that the context is assigned to - * \param imprint userland identification of the context - */ - Signal_context(Signal_receiver * const r, unsigned const imprint) - : - _deliver_fe(this), _contexts_fe(this), _receiver(r), - _imprint(imprint), _submits(0), _ack(1), _kill(0), _killer(0) - { } - /** * Hook to install in-kernel handler for acks at specific signal types */ @@ -250,13 +238,6 @@ class Kernel::Signal_context protected: - /** - * Constructor that is used by - * - * \param r receiver that the context is assigned to - */ - Signal_context(Signal_receiver * const r); - /** * Destructor */ @@ -264,6 +245,21 @@ class Kernel::Signal_context public: + /** + * Exception types + */ + struct Assign_to_receiver_failed { }; + + /** + * 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 * const r, unsigned const imprint); + /** * Submit the signal * @@ -411,6 +407,19 @@ class Kernel::Signal_receiver _handlers.remove(&h->_handlers_fe); } + /** + * Assign context 'c' to the receiver + * + * \retval 0 succeeded + * \retval -1 failed + */ + int _add_context(Signal_context * const c) + { + if (_kill) { return -1; } + _contexts.enqueue(&c->_contexts_fe); + return 0; + } + /*************************** ** Signal_context_killer ** @@ -453,37 +462,6 @@ class Kernel::Signal_receiver return 0; } - /** - * Create a context that is assigned to the receiver - * - * \param p memory destination - * \param imprint userland identification of context - * - * \retval 0 succeeded - * \retval -1 failed - */ - int new_context(void * p, unsigned imprint) - { - if (_kill) { return -1; } - new (p) Signal_context(this, imprint); - Signal_context * const c = (Signal_context *)p; - _contexts.enqueue(&c->_contexts_fe); - return 0; - } - - /** - * Assign context 'c' to the receiver - * - * \retval 0 succeeded - * \retval -1 failed - */ - int add_context(Signal_context * const c) - { - if (_kill) { return -1; } - _contexts.enqueue(&c->_contexts_fe); - return 0; - } - /** * Return wether any of the contexts of this receiver is deliverable */ diff --git a/base-hw/src/core/kernel/thread.cc b/base-hw/src/core/kernel/thread.cc index 69706304b6..97b242aebe 100644 --- a/base-hw/src/core/kernel/thread.cc +++ b/base-hw/src/core/kernel/thread.cc @@ -746,14 +746,13 @@ void Thread::_syscall_new_signal_context() /* create and assign context*/ void * const p = (void *)user_arg_1(); unsigned const imprint = user_arg_3(); - if (r->new_context(p, imprint)) { - PERR("failed to create signal context"); + try { + Signal_context * const c = new (p) Signal_context(r, imprint); + user_arg_0(c->id()); + } catch (Signal_context::Assign_to_receiver_failed) { + PERR("failed to assign context to receiver"); user_arg_0(0); - return; } - /* return context name */ - Signal_context * const c = (Signal_context *)p; - user_arg_0(c->id()); }