// emSignal.h
// Copyright (C) 2005-2008,2010 Oliver Hamann.
// Homepage: http://eaglemode.sourceforge.net/
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#ifndef emSignal_h
#define emSignal_h

#ifndef emScheduler_h
#include <emCore/emScheduler.h>

//================================== emSignal ==================================

class emSignal : public emUncopyable {


        // Class for a signal which can be sent (signaled) to all the engines
        // of an emScheduler.


        void Signal(emScheduler & scheduler);
                // Signal this signal. Please even read the comments on
                // emEngine::AddWakeUpSignal, emEngine::Signal and
                // emEngine::IsSignaled.

        bool IsPending() const;
                // If a signal is signaled, it is always pending until the end
                // or beginning of the schedulers call to an emEngine::Cycle.

        void Abort();
                // Abort any signaling of this signal. No engine will see this
                // signal signaled before it is signaled again (but engines
                // could already have been woken up, except this is called in
                // the pending phase of the signal).


        friend class emScheduler;
        friend class emEngine;

        struct Link {
                emEngine * Engine;
                Link * * ELThisPtr;
                Link * ELNext;
                emSignal * Signal;
                Link * * SLThisPtr;
                Link * SLNext;
                unsigned int RefCount;

        emScheduler::SignalRingNode RNode;
                // Node for the list of pending signals (emScheduler::PSList).

        Link * ELFirst;
                // First element in the list of connected engines.

        emUInt64 Clock;
                // State of emScheduler::Clock after signaling this signal,
                // modified at end of pending phase.

inline void emSignal::Signal(emScheduler & scheduler)
        if (!RNode.Next) {

inline bool emSignal::IsPending() const
        return RNode.Next!=NULL;