/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2011-2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * \file Server.cpp * * This file strongly follows the Serialization example from the boost::asio * library (see server.cpp) * * Created on: Oct 21, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif // boost asio needs specific operator new #include #include "CodePatterns/MemDebug.hpp" #include #include #include #include #include "Fragmentation/Automation/atexit.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "Fragmentation/Automation/FragmentScheduler.hpp" //!> global shutdown function boost::function shutdownfunction; //!> global signal vector for later releasing std::vector signals; //!> counter for the number of received signals size_t NoSignalsReceived = 0; //!> maximum number of received signals after which the handlers are released const size_t MAX_NOSIGNALSRECEIVED = 3; void signalhandler(int sig) { // increment received signal counter ++NoSignalsReceived; // shutdown if we have handler if (shutdownfunction) shutdownfunction(sig); if (NoSignalsReceived >= MAX_NOSIGNALSRECEIVED) { // release signal hook again for (std::vector::const_iterator iter = signals.begin(); iter != signals.end(); ++iter) signal(*iter, NULL); } } int main(int argc, char* argv[]) { // from this moment on, we need to be sure to deinitialize in the correct order // this is handled by the cleanup function atexit(cleanUp); // Declare the supported options. boost::program_options::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") ("verbosity,v", boost::program_options::value(), "set verbosity level") ("signal", boost::program_options::value< std::vector >(), "set signal to catch (can be given multiple times)") ("workerport", boost::program_options::value< unsigned short >(), "listen on this port for connecting workers") ("controllerport", boost::program_options::value< unsigned short >(), "listen on this port for connecting controller") ; boost::program_options::variables_map vm; boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); boost::program_options::notify(vm); if (vm.count("help")) { std::cout << desc << "\n"; return 1; } if (vm.count("verbosity")) { LOG(0, "STATUS: Verbosity level was set to " << vm["verbosity"].as() << "."); setVerbosity(vm["verbosity"].as()); } else { LOG(0, "STATUS: Verbosity level was not set, defaulting to 3."); setVerbosity(3); } unsigned short workerport; if (vm.count("workerport")) { try { workerport = vm["workerport"].as< unsigned short >(); } catch (boost::bad_lexical_cast) { ELOG(1, "Could not read " << workerport << " as digits."); return 255; } LOG(1, "INFO: Using " << workerport << " as listen port for worker."); } else { ELOG(1, "Requiring listen port for worker."); return 255; } unsigned short controllerport; if (vm.count("controllerport")) { try { controllerport = vm["controllerport"].as< unsigned short >(); } catch (boost::bad_lexical_cast) { ELOG(1, "Could not read " << controllerport << " as digits."); return 255; } LOG(1, "INFO: Using " << controllerport << " as listen port for controller."); } else { ELOG(1, "Requiring listen port for controller."); return 255; } size_t Exitflag = 0; try { boost::asio::io_service io_service; FragmentScheduler Server(io_service, workerport, controllerport); // catch ctrl-c and shutdown worker properly shutdownfunction = boost::bind(&FragmentScheduler::shutdown, boost::ref(Server), _1); if (vm.count("signal")) { signals = vm["signal"].as< std::vector >(); for (std::vector::const_iterator iter = signals.begin(); iter != signals.end(); ++iter) { LOG(0, "STATUS: Catching signal " << *iter << " via signal handler."); signal(*iter, &signalhandler); } } else { LOG(0, "STATUS: No signals are caught."); } { Info info("io_service"); io_service.run(); } Exitflag = Server.getExitflag(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return Exitflag; }