macssh/GUSI/include/GUSISignal.h

150 lines
7.4 KiB
C++
Executable File

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// % Project : GUSI - Grand Unified Socket Interface
// % File : GUSISignal.nw - Signal engine
// % Author : Matthias Neeracher
// % Language : C++
// %
// % $Log$
// % Revision 1.1.1.1 2001/03/03 21:50:13 chombier
// % Initial import
// %
// % Revision 1.7 2000/10/16 04:08:51 neeri
// % Add binary compatibility for CW SIGINT
// %
// % Revision 1.6 2000/05/23 07:18:03 neeri
// % Improve formatting
// %
// % Revision 1.5 2000/03/15 07:22:07 neeri
// % Enforce alignment choices
// %
// % Revision 1.4 1999/12/13 03:07:25 neeri
// % Releasing 2.0.2
// %
// % Revision 1.3 1999/11/15 07:20:18 neeri
// % Safe context setup
// %
// % Revision 1.2 1999/08/26 05:45:09 neeri
// % Fixes for literate edition of source code
// %
// % Revision 1.1 1999/06/30 07:42:07 neeri
// % Getting ready to release 2.0b3
// %
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// \chapter{Signal support}
//
// We support signals in the half assed way characteristic for GUSI's approach to
// asynchronous issues: Delivery is very much synchronous, basically within [[Yield]]
// calls. Signal handling behavior is encapsulated in the classes [[GUSISigContext]] and
// [[GUSISigProcess]] whose instances are manufactured by a [[GUSISigFactory]].
//
// <GUSISignal.h>=
#ifndef _GUSISIGNAL_
#define _GUSISIGNAL_
#include <signal.h>
#ifdef GUSI_SOURCE
#include <ConditionalMacros.h>
#if PRAGMA_STRUCT_ALIGN
#pragma options align=native
#endif
// \section{Definition of the signal handling engine}
//
// A [[GUSISigProcess]] contains the per-process signal state. [[GetAction]] and [[SetAction]] manipulate the
// action associated with a signal, [[Pending]] returns the set of pending signals, [[Post]] marks a signal
// as pending (but possibly blocked), and [[Raise]] executes a signal (which we have determined is not
// blocked).
//
// <Definition of class [[GUSISigProcess]]>=
class GUSISigContext;
class GUSISigProcess {
public:
virtual struct sigaction & GetAction(int sig);
virtual int SetAction(int sig, const struct sigaction & act);
virtual sigset_t Pending() const;
virtual void ClearPending(sigset_t clear);
virtual void Post(int sig);
virtual bool Raise(int sig, GUSISigContext * context);
virtual ~GUSISigProcess();
protected:
// [[GUSISigProcess]] stores the signal handlers and the set of signals pending against the process.
//
// <Privatissima of [[GUSISigProcess]]>=
sigset_t fPending;
struct sigaction fAction[NSIG-1];
// Some actions can't be caught and/or ignored. [[CantCatch]] and [[CantIgnore]] report those.
//
// <Privatissima of [[GUSISigProcess]]>=
virtual bool CantCatch(int sig);
virtual bool CantIgnore(int sig);
// The default behavior for many signals is to abort the process.
//
// <Privatissima of [[GUSISigProcess]]>=
virtual bool DefaultAction(int sig, const struct sigaction & act);
friend class GUSISigFactory;
GUSISigProcess();
};
// A [[GUSISigContext]] contains the per-thread signal state, primarily blocking info. To support
// [[pthread_kill]], we have out own set of pending signals. [[GetBlocked]] and [[SetBlocked]] manipulate
// the set of blocking signals, [[Pending]] returns the set of pending signals, [[Post]] marks a
// signal as pending (but possibly blocked), and [[Raise]] executes all eligible signals.
//
// <Definition of class [[GUSISigContext]]>=
class GUSISigContext {
public:
virtual sigset_t GetBlocked() const;
virtual void SetBlocked(sigset_t sigs);
virtual sigset_t Pending() const;
virtual sigset_t Pending(GUSISigProcess * proc) const;
virtual void ClearPending(sigset_t clear);
virtual void Post(int sig);
virtual sigset_t Ready(GUSISigProcess * proc);
virtual bool Raise(GUSISigProcess * proc, bool allSigs = false);
virtual ~GUSISigContext();
protected:
// [[GUSISigContext]] mainly deals with a set of blocked signals, which it inherits from its parent.
//
// <Privatissima of [[GUSISigContext]]>=
sigset_t fPending;
sigset_t fBlocked;
// Many signals cannot be blocked. [[CantBlock]] defines those.
//
// <Privatissima of [[GUSISigContext]]>=
virtual sigset_t CantBlock();
friend class GUSISigFactory;
GUSISigContext(const GUSISigContext * parent);
};
// The [[GUSISigFactory]] singleton creates the above two classes, allowing a future extension to
// handle more signals.
//
// <Definition of class [[GUSISigFactory]]>=
class GUSISigFactory {
public:
virtual GUSISigProcess * CreateSigProcess();
virtual GUSISigContext * CreateSigContext(const GUSISigContext * parent);
virtual ~GUSISigFactory();
static GUSISigFactory * Instance();
static void SetInstance(GUSISigFactory * instance);
protected:
GUSISigFactory() {}
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#endif
#endif /* _GUSISIGNAL_ */