Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Customization

Customize Aspects
Customize Signals/Handlers

The 'aspects' concept allow user to customize, and extend library functionality in easy way. The diagram below shows the way to extend or create new aspect.

aspect

The 'A' shows the more complex aspects, that needs to meet a well defined interface, which is used internally by the application mode.

On 'B' we have simplest aspect that can be any C++ class.

Thus, the user can customize the default behavior of any handler. To do this, the user needs inheriting of contract handler class (abstract) that he wants to modify the behavior.

For sample: The default behavior of wait_for_termination_request is unblock and exit of application. To change this behavior user can do as follows:

class myapp
{
public:

   myapp(application::context& context)
      : context_(context)
   {
   }

   // param
   int operator()()
   {
      std::cout << "Test" << std::endl;
	
	  1context_.find<application::wait_for_termination_request>()->wait();

      return 0;
   }

private:

   application::context& context_;
};

// my made by hand behaviour
class wait_for_termination_request_my_behaviour
   2: public application::wait_for_termination_request
{
public:

   3void wait(){
      char type;
      do
      {
         std::cout << "Exit? [y/n]" << std::endl;
         std::cin >> type;
      }
      while( !std::cin.fail() && type!='y' );
   }

   void proceed(){
      // do nothing
   }
};

// main

int main(int argc, char *argv[])
{
   application::context app_context;
   myapp app(app_context);

   app_context.insert<application::args>(
      boost::make_shared<application::args>(argc, argv));

   // if user do this, the default behavoiur will be ignored, 
   // and the user behaviour will be executed by application::server
   4app_context.insert< application::wait_for_termination_request>(
      shared_ptr<application::wait_for_termination_request>(
         new wait_for_termination_request_my_behaviour));

   return application::launch<application::common>(app, app_context);
}

1

Use your custon handler

2

Inheriting of 'wait_for_termination_request' handler contract abstract class

3

Define your desired operation for 'wait' method

4

Add your custon handler to context aspect pool of application

Like a handler, the user is free to customize the SIGNALS of application.

[Note] Note

The SIGNALS can not be customized when Windows Service (server application mode on windows) is used.

Windows Service uses a completely different set of signals called 'events', so in this case you should customize 'pause', 'resume' and 'stop' handlers

This feature allows user configure/add handlers for others SIGNALS.

In this sample we will create a handler to SIGUSR2 POSIX signal. Note that this signal is not available on Windows.

To do this user need inheriting of signal_manager class and add new signal bind, like:

class myapp
{
public:

   myapp(context& context)
      : context_(context)
   {
   }

   ~myapp()
   {
      std::cout << "~myapp()" << std::endl;
   }

   void work_thread()
   {
      while(1)
      {
         boost::this_thread::sleep(boost::posix_time::seconds(2));
         std::cout << "running" << std::endl;
      }
   }

   // param
   int operator()()
   {
      std::cout << "operator()" << std::endl;
	
      // launch a work thread
      boost::thread thread(boost::bind(&myapp::work_thread, this));
	
      context_.find<wait_for_termination_request>()->wait();

      return 0;
   }

private:

   context& context_;

};

1class my_signal_manager : public signal_manager
{
public:

   2my_signal_manager(context &context)
      : signal_manager(context)
   {
      handler<>::callback cb
         = boost::bind<bool>(&my_signal_manager::stop, this);

      // define my own signal / handler
#if defined( BOOST_WINDOWS_API )
      bind(SIGINT,  cb); // CTRL-C (2)
#elif defined( BOOST_POSIX_API )
      3bind(SIGUSR2, cb);
#endif

   }

   4bool stop()
   {
      BOOST_APPLICATION_FEATURE_SELECT

#if defined( BOOST_WINDOWS_API )
      std::cout << "exiting..." << std::endl;
#elif defined( BOOST_POSIX_API )
      std::ofstream my_log_file;
      my_log_file.open((context_.find<
         path>()->executable_path().string() + "/log_stop.txt").c_str());
      my_log_file << ":0)-" << std::endl;
      my_log_file.close();
#endif

      shared_ptr<wait_for_termination_request> th
         = context_.find<wait_for_termination_request>();

      th->proceed();

      return false;
   }

};

// main

int main(int argc, char *argv[])
{
   context app_context;
   myapp app(app_context);

   app_context.insert<path>(
      boost::make_shared<path_default_behaviour>(argc, argv));

   // we will customize our signals behaviour
   5my_signal_manager sm(app_context);

#if defined( BOOST_WINDOWS_API )
   6return launch<common>(app, sm, app_context);
#elif defined( BOOST_POSIX_API )
   return launch<server>(app, sm, app_context);
#endif

}

1

Inheriting of signal_manager

2

Customize SIGNALS bind

3

Define signal bind

4

Define signal callback

5

Instantiate your custon signal manager.

6

Pass 'custon signal manager (sm)' to launch function.


PrevUpHomeNext