// -*- c++ -*-
//------------------------------------------------------------------------------
//                            SigHandlers.h
//------------------------------------------------------------------------------
//  Copyright (C) 1997-2002  Vladislav Grinchenko <vladg@erols.com>
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------

#ifndef _SigHandlers_h
#define _SigHandlers_h

// System includes
//
#include <signal.h>
#include <errno.h>
#include <sys/time.h>		// select
#include <sys/types.h>		// select

#include "assa/SigHandler.h"
#include "assa/SigHandlersList.h"
#include "assa/Handlers.h"

namespace ASSA {

/** @file SigHandlers.h 

    SigHandlers is a signal handlers manager.

	SigHandlers class extends SigHandler class by allowing
	user to register multiple EventHandlers per signal. It also preserves
	signal handlers installed by the third-party software.

	Initially the state of SigHandlers object is passive. No special
	dispatching is done. User can use other means (such as @see SigAction) to
	register C-function as signal handler.

	When register() method is called for the first EventHandler,
	the state of SigHandlers object changes to active, and SigHandlers
	dispatcher takes over the control on how signals are dispatched. Each
	EventHandler is added to the list of handlers. When signal is delivered,
	all handlers on that list will be notified.
	
	If third party library (or application code) has installed its own
	signal handler (C-function) prior to the first EventHandler registration,
	it will be placed among all other registered EventHandlers and notified too
	when signal is delivered to the process by OS.
*/

class SigHandlers : public SigHandler
{
public:
	/** A wrapper around static SigHandlers::dispatch(). It is needed for 
	    the purpose of differentiation it with other signal handlers that 
	    might be installed by user's code.
	    @param signum_ Dispatch event handlers for this signal.
	*/
	static void sighandlers_dispatcher (int signum_);

	/** Register EventHandler with dispatching system.

	    @param signum_   (In   ) Signal number.
	    @param new_hand_ (In   ) Pointer to new event handler to install.
	    @param new_disp_ (In=0 ) New disposition to use to handle signal.
	    @param old_hand_ (Out=0) Placeholder for old event handler.
	    @param old_disp_ (Out=0) Placeholder for old disposition.

	    @return 0 on success; -1 on error.
	 */
	virtual int install (int            signum_,
						 EventHandler*  new_hand_,
						 SigAction*     new_disp_ = 0,
						 EventHandler** old_hand_ = 0,
						 SigAction*     old_disp_ = 0);
			     
	/** Remove EventHandler from the list of registered handler
	    for signum_. If eh_ is NULL, then all
	    EventHandler(s) will be removed from the list, and object
	    will go back to passive mode in which no signal
	    handling is done via SigHandlers class dispatcher. If
	    new_disp_ is omitted, SIG_DFL will be used
	    instead.

	    @param signum_   (In   ) Signal number.
	    @param eh_       (In   ) Event handler to remove.
	    @param new_disp_ (In=0 ) New disposition to use to handle signal.
	    @param old_disp_ (Out=0) Placeholder for old disposition.

	    @return 0 on success; -1 on error.
	*/

	virtual int remove (int           signum_, 
						EventHandler* eh_,
						SigAction*    new_disp_ = 0, 
						SigAction*    old_disp_ = 0);
private:
	/** The heart of SigHandlers class - this callback function
	    is really registered with OS to catch all of the signals
	    for which event handler has been installed. Appropriate
	    EventHandler(s) are then notified.
	*/
	static void dispatch (int signum_);
};

} // end namespace ASSA

#endif /* _SigHandlers_h */
