//------------------------------------------------------------------------------
// 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>
#endif
//==============================================================================
//================================== emSignal ==================================
//==============================================================================
class emSignal : public emUncopyable {
public:
// Class for a signal which can be sent (signaled) to all the engines
// of an emScheduler.
emSignal();
~emSignal();
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).
private:
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) {
RNode.Next=scheduler.PSList.Next;
scheduler.PSList.Next=&RNode;
}
}
inline bool emSignal::IsPending() const
{
return RNode.Next!=NULL;
}
#endif