⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sig_handler.h

📁 C++ SOCKET 类
💻 H
字号:
//// This file is part of the C++ threads library//// Copyright (C) 2001, The C++ threads library team.//// This file creates a mechanism to deliver signals// to a C++ thread.//#ifndef CPP_THREADS_SIGNAL_SYSTEM_H#define CPP_THREADS_SIGNAL_SYSTEM_H#include "systemlib.h"#include <threads/signal_num.h>namespace cpp_threads {  /**   * This is an internal structure used by the signalling class   * to hold data about each registered.   */  template<class T,class P=void*,class Ret=void>    struct signalling_holder {      int               s_pid;      struct sigaction  s_sa;      struct sigaction* s_old_handler;      T*                s_thisptr;      Ret              (T::*s_handler)(P);      P                 s_param;#if (Ret!=void)      Ret               s_retVal;#endif    };  /**   *   Signal system in C++ Threads.   *   *   The signal system, converts C style signal mechanism into   * a more usable C++ style.  What is more useful in this class   * above the normal C signalling system, is that the template   * structure and the use of the above structure, allows the   * user to specify an arbitrary parameter the signal routine   * will take.  It also allows the user to specify the return   * type for the signal handler.   *   *   Methods are also provided to send signals using this scheme   * and to obtain the last return value from the signal handler.   *   * @short Signal system for C++ threads.   * @author Orn E. Hanse <oe.hansen@nissamedia.net>   */  template<class T,class P=void*,class Ret=void>  class signalling {    protected:      typedef Ret(T::*slot_t)(P);    protected:      static signalling_holder<T,P,Ret> _holder[_NSIG];      static void signal_catcher(int);    public:      signalling();      ~signalling();    /**     * This will establish all set signal handlers, with extreme     * prejudice.  It is mainly thought out, to re-establsh the     * signal handling system, in case of a C routine altering     * them.     */    void resetAll();    /**     * Connect a signal to a specific class and method. This     * will activate signal delivery to a specific class.  The     * class can be any class, but must have been given when     * the instance of this class was created, along with the     * return value and parameter of the method.     *     * Note, that a signal can only be connected to once,     *       once connected, it must be disconnected before     *       being used again.  The process that actually is     *       doing the connect, must also be the true     *       receiver of the signal.  As that's process     *       signal table is changed.     *     * @param s The signal number to connect to.     * @param c A pointer to the class itself.     * @param m A reference to the method within that class.     * @return True if the signal was connected.     */    bool connect(__sign_num,T*,slot_t);    /**     * This method varies from the above only in the number of parameters     * it accepts.  It is a link for those who wish to set the flags, and     * mask values, as is accepted by sigaction.     *     * @param s The signal number to connect to.     * @param m The mask to use.     * @param f The flags to set.     * @param c A pointer to the class instance.     * @param p A pointer to the method within the class.     * @return True if the signal was connected.     */    bool connect(__sign_num,sigset_t,int,T*,slot_t);    /**     * This method will disconnect a connected signal, and return     * it to the state it was in, prior to being connected.     *     * @param s The signal number to disconnect.     * @return True if a signal was disconnected.     */    bool disconnect(__sign_num);    /**     * This method will emit a signal (by way of kill) and pass a     * parameter to the routine.  It will also return to the caller     * the return value from the signal handler.     *     * @param s Signal number to send to process.     * @param p The parameter to pass to signal handler.     */    void emit(__sign_num,P);    /**     * This method will obtain the return value, that was given by     * the handler.     *     * @return The return value from the handler.     */    Ret retValue();    /**     * This method will query if the signal handler is actually     * active.     *     * @return True if the signal handler is processing a request.     */    bool signal_active();  };  template<class T,class P,class Ret>    signalling_holder<T,P,Ret> signalling<T,P,Ret>::_holder[_NSIG];  template<class T,class P,class Ret>    signalling<T,P,Ret>::signalling()    {      int i;            for(i=0;i<_NSIG;i++)	_holder[i].s_old_handler = 0;    }  template<class T,class P,class Ret>    signalling<T,P,Ret>::~signalling()    {      int i;      for(i=0;i<_NSIG;i++)	disconnect(__sign_num(i));    }  template<class T,class P,class Ret>    void signalling<T,P,Ret>::signal_catcher(int signal_num_p)    {      register signalling_holder<T,P,Ret>& refptr = _holder[signal_num_p];      if( (refptr.s_thisptr) && (refptr.s_handler) )#if( Ret!=void )	refptr.s_retVal=(refptr.s_thisptr->*refptr.s_handler)(refptr.s_param);#else	(refptr.s_thisptr->*refptr.s_handler)(refptr.s_param);#endif    }  template<class T,class P,class Ret>    void signalling<T,P,Ret>::resetAll()    {      for(int i=1;i<_NSIG;i++)	if( _holder[i].s_old_handler )	  sys::sigaction(i,&_holder[i].s_sa,0);    }  template<class T,class P,class Ret>    bool signalling<T,P,Ret>::connect(__sign_num signal_num_p,T* this_p,slot_t handler_p)    {      sigset_t mask;        sigemptyset(&mask);      return connect(signal_num_p,mask,0,this_p,handler_p);    }  template<class T,class P,class Ret>    bool signalling<T,P,Ret>::connect(__sign_num signal_num_p,sigset_t mask_p,int flags_p,T* this_p,slot_t handler_p)    {      int rv;      signalling_holder<T,P,Ret>& refptr = _holder[signal_num_p];      refptr.s_handler = handler_p;      refptr.s_thisptr = this_p;      refptr.s_param   = P();      if( refptr.s_old_handler == 0 ) {	refptr.s_old_handler = new struct sigaction;	refptr.s_sa.sa_handler = signal_catcher;	refptr.s_sa.sa_flags   = flags_p;	refptr.s_sa.sa_mask    = mask_p;	refptr.s_pid  = getpid();	rv=sys::sigaction(signal_num_p,&refptr.s_sa,refptr.s_old_handler);	return (rv == 0);      }      return true;    }  template<class T,class P,class Ret>    bool signalling<T,P,Ret>::disconnect(__sign_num signal_num_p)    {      signalling_holder<T,P,Ret>& refptr = _holder[signal_num_p];      int n=0;      if( refptr.s_old_handler ) {	n = sys::sigaction(signal_num_p,refptr.s_old_handler,0);	refptr.s_old_handler = 0;      }      return (n == 0);    }  template<class T,class P,class Ret>    void signalling<T,P,Ret>::emit(__sign_num signal_num_p,P param_p)    {      signalling_holder<T,P,Ret>& refptr = _holder[signal_num_p];      refptr.s_param = param_p;      kill( refptr.s_pid,signal_num_p );    }  template<class T,class P,class Ret>    Ret retValue(__sign_num signal_num_p)    {#if( Ret!=void )      return _holder[signal_num_p].s_retVal;#endif    }}; // namespace#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -