Benefits - get rid of yet another pervasive Boost dependency - define additional more fine grained policies (move only, clonable)
138 lines
4.7 KiB
C++
138 lines
4.7 KiB
C++
/*
|
|
SUBSYS.hpp - interface for describing an application part to be handled by main()
|
|
|
|
Copyright (C) Lumiera.org
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
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 for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
/** @file subsys.hpp
|
|
** Describing dependencies and lifecycle of the application's primary parts.
|
|
** Within Lumiera's main(), a small number of well-known application subsystems
|
|
** need to be started and maintained, observing some interrelations.
|
|
** While the activation of the key components is controlled by options, maybe
|
|
** some prerequisite subsystems need to be pulled up, and in case of an regular
|
|
** or irregular exit of a given subsystem, the whole dependency graph needs
|
|
** to be brought down in a clean manner. The purpose of lumiera::Subsys is
|
|
** to maintain these in a self-explanatory script-like fashion within main(),
|
|
** without forcing the individual subsystems into a fixed implementation scheme.
|
|
** The only requirement is that for each subsystem there is sort-of an entry
|
|
** point or facade object, providing a Subsys descriptor instance to be
|
|
** used within main.
|
|
**
|
|
** @see lumiera::AppState
|
|
** @see lumiera::Option
|
|
** @see main.cpp
|
|
*/
|
|
|
|
|
|
#ifndef LUMIERA_SUBSYS_H
|
|
#define LUMIERA_SUBSYS_H
|
|
|
|
#include "lib/error.hpp"
|
|
#include "lib/nocopy.hpp"
|
|
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace lumiera {
|
|
|
|
using std::string;
|
|
using std::function;
|
|
|
|
class Option;
|
|
|
|
|
|
|
|
/**
|
|
* Dependencies and lifecycle of a partially independent Subsystem of the Application.
|
|
* Using such descriptors, AppState as activated from main() is able to pull up,
|
|
* maintain and shut down the primary parts of the Application.
|
|
* @note synchronisation is up to the implementor.
|
|
*/
|
|
class Subsys
|
|
: util::NonCopyable
|
|
{
|
|
public:
|
|
typedef function<void(string*)> SigTerm;
|
|
|
|
virtual ~Subsys();
|
|
|
|
/** a human readable name */
|
|
virtual operator string() const =0;
|
|
|
|
|
|
/** define a dependency to another Subsys
|
|
* required for running this subsystem */
|
|
Subsys& depends (Subsys& prereq);
|
|
|
|
/** @return true if Up
|
|
* @warning must not block nor throw. */
|
|
bool isRunning() noexcept;
|
|
|
|
|
|
/** query application option state to determine
|
|
* if this subsystem should be activated.
|
|
* @note even if not started explicitly, it could still
|
|
* be started as prerequisite of another one */
|
|
virtual bool shouldStart (lumiera::Option&) =0;
|
|
|
|
|
|
/** attempt to bring up this subsystem up. On return, the
|
|
* subsystem must be operational, according to checkRunningState().
|
|
* Failure to start up usually terminates the whole application.
|
|
* When this subsystem ceases to work, it must ensure to activate
|
|
* the given callback signal.
|
|
* @param options may be influencing the operation mode
|
|
* @param SigTerm to be signalled by the subsystem.
|
|
* @warning termination must be signalled reliably.
|
|
* @return `true` if actually started. */
|
|
virtual bool start (lumiera::Option& options, SigTerm) =0;
|
|
|
|
|
|
/** initiate termination of this subsystem.
|
|
* This trigger may be called repeatedly any time...
|
|
* When the subsystem actually has terminated,
|
|
* the SigTerm passed to #start must be invoked.
|
|
* @note called within a locked context (barrier)
|
|
* @warning must not block nor throw. */
|
|
virtual void triggerShutdown() noexcept =0;
|
|
|
|
|
|
const std::vector<Subsys*>
|
|
getPrerequisites() { return prereq_; }
|
|
|
|
|
|
private:
|
|
/** whether this subsystem is actually operational.
|
|
* When returning \c false here, the application may
|
|
* terminate at any point without further notice
|
|
* Note further, that a subsystem must not be in
|
|
* running state when signalling termination. */
|
|
virtual bool checkRunningState() noexcept =0;
|
|
|
|
std::vector<Subsys*> prereq_;
|
|
};
|
|
|
|
|
|
|
|
} // namespace lumiera
|
|
|
|
#endif
|