A sigaction of C + + wrap

Source: Internet
Author: User

In the previous article (http://www.cnblogs.com/coding-my-life/p/4220128.html), it was mentioned that Libev provides C + + wrap for processing signals. But I'm obviously not going to be able to catch the disadvantage of the message after I need to enter the event loop of the Libev. So I decided to write a C + + wrap According to Libev's idea.

Analyzed the source code of Libev, the main points are as follows:

    • The Sigaction function can only set a function pointer of C as a callback function and cannot callback a member function. Therefore, you need to callback the member function through the C function.
    • Callback a member function that must have an object (or its pointer) and a member function pointer. Therefore, a structure is designed to store object pointers and member function pointers.
    • To store data, it mainly involves the allocation, release, and management of memory. Therefore, a global object is designed to manage these data structures.

Based on the above points, you can design the following code:

#include <cstddef>/*For NULL*/#include<signal.h>#include<cassert>StaticInlinevoidSighandler (intSignum);/** * @brief the sig_action struct * Store callback object pointers and callback functions*/structsig_action{void*Object; void(*CB) (void*Object,intsignum);};/** * @brief the Csignal class * C + + classes for sigaction encapsulation*/classcsignal{ Public:    Explicitcsignal (); ~csignal (); intResetintSignum); intIgnoreintSignum); voidFeed_signal (intSignum); Template<classKvoid(K::* PF) (int) >int SetKObject,intSignumintsa_flag);Private:        /*NSIG the value of this symbolic constant are the total number of signals defined. Since the signal numbers is allocated consecutively, NSIG is also one greater than the largest defined signal numb       Er. Define in Sys/signal.h*/    structsig_action*M_actions[nsig]; Template<classKvoid(K::* method) (int) >Static voidMethod_thunk (void*Object,intSignum) {(static_cast<k *> (Object)->*method)    (Signum); }};/** * @brief csignal::csignal * Initialize signal callback structure*/csignal::csignal () { for(inti =0; i < Nsig;i + +) {M_actions[i]=NULL; }}/** * @brief csignal::~csignal * Destroy signal callback structure*/csignal::~csignal () { for(inti =0; i < Nsig;i + + )    {        if(M_actions[i]) {delete m_actions[i]; M_actions[i]=NULL; }    }}/** * @brief Csignal::set * Set Signal object callback*/Template<classKvoid(K::* PF) (int) >intCsignal::SetKObject,intSignumintSa_flag) {Assert (0< Signum && NSIG > Signum);/*valid signals range from 1 to NSIG-1*/            structsigaction sa; Sa.sa_handler=Sighandler; Sigemptyset (&sa.sa_mask);/*Won't block any other signal*/Sa.sa_flags= Sa_flag;/*usually Sa_restart or Sa_resethand,man sigaction for more*/        if(NULL = = M_actions[signum])/*First init*/M_actions[signum]=New structsig_action; M_actions[signum]-Object= (void*)Object; M_actions[signum]-&GT;CB = method_thunk<k,pf>; returnSigaction (Signum,&sa,0 );}/** * @brief csignal::feed_signal * @param signum * Trigger callback*/voidCsignal::feed_signal (intSignum) {    structSig_action *sac =M_actions[signum]; ASSERT (NULL!=SAC); SAC-&GT;CB (sac->Object, Signum);}/** * @brief csignal::ignore * @param signum * @return return value Same as sigaction * Ignore signal*/intCsignal::ignore (intSignum) {    structsigaction sa; Sa.sa_handler=sig_ign; Sigemptyset (&sa.sa_mask); returnSigaction (Signum,&sa,0 );}/** * @brief csignal::reset * @param signum * @return return value Same as Sigaction * Reset signal as default*/intCsignal::reset (intSignum) {    structsigaction sa; Sa.sa_handler=SIG_DFL; Sigemptyset (&sa.sa_mask); returnSigaction (Signum,&sa,0 );}/*Global funtion and Object*/Static classcsignal Signal_watcher;StaticInlineclassCsignal *Default_signal_watcher () {return((classcsignal*) &signal_watcher);}#defineCsig_default Default_signal_watcher ()/** * @brief Sighandler * @param signum * Signal callback function main entrance*/StaticInlinevoidSighandler (intSignum) {Csig_default-feed_signal (Signum);}

In order to test the code above, some auxiliary test classes are also written:

#ifndef Cbackend_h #define Cbackend_h/**/class  cbackend{public:    cbackend (    ); void int signum);     void loop ();}; #endif // Cbackend_h
#include"CBackend.h"#include<signal.h>/*For strsignal*/#include<unistd.h>/*For sleep in Ubuntu 14.04*/#include<iostream>/*For Std::cout*/#include<cstring>/*For strsignal*/cbackend::cbackend () {}/** * @brief Cbackend::sighandler * @param signum * processing signal*/voidCbackend::sighandler (intSignum) {Std::cout<<"Catch Signal"<< Signum <<" -- "<< strsignal (Signum) <<Std::endl;}/** * @brief cbackend::loop * Background work cycle*/voidCbackend::loop () { while(true) {Std::cout<<"I ' m working ..."<<Std::endl; Sleep (1 ); }}
" signal++.h "  "CBackend.h"/**/int  main () {    Cbackend backend;    Csig_defaultSet<CBackend,&CBackend::sighandler> (&Backend,sigint,sa_ RESTART);    Backend.loop ();}

Compile and test:

g++-o Example Example.cpp CBackend.cpp
./example

Press CTRL + C to see a message like catch signal 2--interrupt.

This basically completes the original intention of the signal callback C + + member function. However, the code above also has some problems: the use of global variables. But there is no better plan at the moment. On the other hand, because of the use of templates, do not hijack the separate compilation, simply write all the functions in the. h file.

A sigaction of C + + wrap

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.