Boost logo

Boost Users :

Subject: Re: [Boost-users] problem with asio signal_set and consecutive signals
From: niXman (i.nixman_at_[hidden])
Date: 2014-08-27 17:04:40


Lutz Schneider 2014-08-28 00:11:
> Hi,
>
> I have a program and would like to stop it by sending SIGINT for
> writing
> some data to a file instead of exiting immediately. However, if the
> user of
> the program sends SIGINT again then the program should quit immediately
> and
> forget about writing data to a file. For portability reason I would
> like to
> use boost::asio for this purpose.
>
> My initial (simplified) approach (see below) did not work. Is this not
> possible or am I missing something?
>
> handler seems to be called only once (printing out the message) and the
> program always stops when the loop has reached the max iteration
> number.
>
> void handler(
> const boost::system::error_code& error,
> int signal_number)
> {
> if (!error)
> {
> static bool first = true;
> if(first){
> std::cout << " A signal(SIGINT) occurred." << std::endl;
> // do something like writing data to a file
> first = false;
> }else{
> std::cout << " A signal(SIGINT) occurred, exiting...." <<
> std::endl;
> exit(0);
> }
> }
> }
>
> int main(){
> // Construct a signal set registered for process termination.
> boost::asio::io_service io;
> boost::asio::signal_set signals(io, SIGINT);
> // Start an asynchronous wait for one of the signals to occur.
> signals.async_wait(handler);
> io.run();
> size_t i;
> for(i=0;i<std::numeric_limits<size_t>::max();++i){
> // time stepping loop, do some computations
> }
> std::cout << i << std::endl;
> return 0;
> }

Hi,

You should set async waiting for next signal immediately in handler,
like this:
#include <iostream>

#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/asio.hpp>

void handler(
         boost::asio::signal_set &sset,
         const boost::system::error_code& error,
         int signal_number)
{
         if (!error)
         {
                 sset.async_wait(
                         boost::bind(
                                  handler
                                 ,boost::ref(sset)
                                 ,boost::asio::placeholders::error
                                 
,boost::asio::placeholders::signal_number
                         )
                 );
                 static bool first = true;
                 if(first){
                         std::cout << " A signal(SIGINT) occurred." <<
std::endl;
                         // do something like writing data to a file
                         first = false;
                 }else{
                         std::cout << " A signal(SIGINT) occurred,
exiting...." << std::endl;
                         exit(0);
                 }
         }
}

int main(){
         // Construct a signal set registered for process termination.
         boost::asio::io_service io;
         boost::asio::signal_set signals(io, SIGINT);
         // Start an asynchronous wait for one of the signals to occur.
         signals.async_wait(
                 boost::bind(
                          handler
                         ,boost::ref(signals)
                         ,boost::asio::placeholders::error
                         ,boost::asio::placeholders::signal_number
                 )
         );

         io.run();
         size_t i;
         for(i=0;i<std::numeric_limits<size_t>::max();++i){
                 // time stepping loop, do some computations
         }
         std::cout << i << std::endl;
         return 0;
}

(http://pastebin.com/RuxQ5ARw)

-- 
Regards, niXman
___________________________________________________
Dual-target(32 & 64-bit) MinGW-W64 compilers for 32 and 64-bit Windows:
http://sourceforge.net/projects/mingw-w64/
___________________________________________________
Another online IDE: http://liveworkspace.org/

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net