[f7f995] | 1 | /*
|
---|
| 2 | * Project: MoleCuilder
|
---|
| 3 | * Description: creates and alters molecular systems
|
---|
| 4 | * Copyright (C) 2011-2012 University of Bonn. All rights reserved.
|
---|
| 5 | * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
|
---|
| 6 | */
|
---|
| 7 |
|
---|
| 8 | /*
|
---|
| 9 | * \file Server.cpp
|
---|
| 10 | *
|
---|
| 11 | * This file strongly follows the Serialization example from the boost::asio
|
---|
| 12 | * library (see server.cpp)
|
---|
| 13 | *
|
---|
| 14 | * Created on: Oct 21, 2011
|
---|
| 15 | * Author: heber
|
---|
| 16 | */
|
---|
| 17 |
|
---|
| 18 | // include config.h
|
---|
| 19 | #ifdef HAVE_CONFIG_H
|
---|
| 20 | #include <config.h>
|
---|
| 21 | #endif
|
---|
| 22 |
|
---|
| 23 | // boost asio needs specific operator new
|
---|
| 24 | #include <boost/asio.hpp>
|
---|
| 25 |
|
---|
| 26 | #include "CodePatterns/MemDebug.hpp"
|
---|
| 27 |
|
---|
| 28 | #include <boost/lexical_cast.hpp>
|
---|
[684bc1] | 29 | #include <boost/program_options.hpp>
|
---|
[f7f995] | 30 | #include <iostream>
|
---|
[267b8d] | 31 | #include <signal.h>
|
---|
[f7f995] | 32 |
|
---|
[cc5db5] | 33 | #include "Fragmentation/Automation/atexit.hpp"
|
---|
[f7f995] | 34 | #include "CodePatterns/Info.hpp"
|
---|
[630a6e] | 35 | #include "CodePatterns/Log.hpp"
|
---|
[cc5db5] | 36 | #include "Fragmentation/Automation/FragmentScheduler.hpp"
|
---|
[f7f995] | 37 |
|
---|
| 38 |
|
---|
[267b8d] | 39 | //!> global shutdown function
|
---|
| 40 | boost::function<void (int)> shutdownfunction;
|
---|
| 41 | //!> global signal vector for later releasing
|
---|
| 42 | std::vector<size_t> signals;
|
---|
| 43 | //!> counter for the number of received signals
|
---|
| 44 | size_t NoSignalsReceived = 0;
|
---|
| 45 | //!> maximum number of received signals after which the handlers are released
|
---|
| 46 | const size_t MAX_NOSIGNALSRECEIVED = 3;
|
---|
| 47 |
|
---|
| 48 | void signalhandler(int sig)
|
---|
| 49 | {
|
---|
| 50 | // increment received signal counter
|
---|
| 51 | ++NoSignalsReceived;
|
---|
| 52 |
|
---|
| 53 | // shutdown if we have handler
|
---|
| 54 | if (shutdownfunction)
|
---|
| 55 | shutdownfunction(sig);
|
---|
| 56 |
|
---|
| 57 | if (NoSignalsReceived >= MAX_NOSIGNALSRECEIVED) {
|
---|
| 58 | // release signal hook again
|
---|
| 59 | for (std::vector<size_t>::const_iterator iter = signals.begin();
|
---|
| 60 | iter != signals.end(); ++iter)
|
---|
| 61 | signal(*iter, NULL);
|
---|
| 62 | }
|
---|
| 63 | }
|
---|
| 64 |
|
---|
[f7f995] | 65 | int main(int argc, char* argv[])
|
---|
| 66 | {
|
---|
| 67 | // from this moment on, we need to be sure to deinitialize in the correct order
|
---|
| 68 | // this is handled by the cleanup function
|
---|
| 69 | atexit(cleanUp);
|
---|
| 70 |
|
---|
[684bc1] | 71 | // Declare the supported options.
|
---|
| 72 | boost::program_options::options_description desc("Allowed options");
|
---|
| 73 | desc.add_options()
|
---|
| 74 | ("help,h", "produce help message")
|
---|
| 75 | ("verbosity,v", boost::program_options::value<size_t>(), "set verbosity level")
|
---|
[267b8d] | 76 | ("signal", boost::program_options::value< std::vector<size_t> >(), "set signal to catch (can be given multiple times)")
|
---|
[684bc1] | 77 | ("workerport", boost::program_options::value< unsigned short >(), "listen on this port for connecting workers")
|
---|
| 78 | ("controllerport", boost::program_options::value< unsigned short >(), "listen on this port for connecting controller")
|
---|
| 79 | ;
|
---|
| 80 |
|
---|
| 81 | boost::program_options::variables_map vm;
|
---|
| 82 | boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
|
---|
| 83 | boost::program_options::notify(vm);
|
---|
| 84 |
|
---|
| 85 | if (vm.count("help")) {
|
---|
| 86 | std::cout << desc << "\n";
|
---|
| 87 | return 1;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | if (vm.count("verbosity")) {
|
---|
| 91 | LOG(0, "STATUS: Verbosity level was set to " << vm["verbosity"].as<size_t>() << ".");
|
---|
| 92 | setVerbosity(vm["verbosity"].as<size_t>());
|
---|
| 93 | } else {
|
---|
| 94 | LOG(0, "STATUS: Verbosity level was not set, defaulting to 3.");
|
---|
| 95 | setVerbosity(3);
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | unsigned short workerport;
|
---|
| 99 | if (vm.count("workerport")) {
|
---|
| 100 | try {
|
---|
| 101 | workerport = vm["workerport"].as< unsigned short >();
|
---|
| 102 | } catch (boost::bad_lexical_cast) {
|
---|
| 103 | ELOG(1, "Could not read " << workerport << " as digits.");
|
---|
| 104 | return 255;
|
---|
| 105 | }
|
---|
| 106 | LOG(1, "INFO: Using " << workerport << " as listen port for worker.");
|
---|
| 107 | } else {
|
---|
| 108 | ELOG(1, "Requiring listen port for worker.");
|
---|
| 109 | return 255;
|
---|
| 110 | }
|
---|
| 111 |
|
---|
| 112 | unsigned short controllerport;
|
---|
| 113 | if (vm.count("controllerport")) {
|
---|
| 114 | try {
|
---|
| 115 | controllerport = vm["controllerport"].as< unsigned short >();
|
---|
| 116 | } catch (boost::bad_lexical_cast) {
|
---|
| 117 | ELOG(1, "Could not read " << controllerport << " as digits.");
|
---|
| 118 | return 255;
|
---|
| 119 | }
|
---|
| 120 | LOG(1, "INFO: Using " << controllerport << " as listen port for controller.");
|
---|
| 121 | } else {
|
---|
| 122 | ELOG(1, "Requiring listen port for controller.");
|
---|
| 123 | return 255;
|
---|
| 124 | }
|
---|
[630a6e] | 125 |
|
---|
[db03d9] | 126 | size_t Exitflag = 0;
|
---|
[f7f995] | 127 | try
|
---|
| 128 | {
|
---|
| 129 | boost::asio::io_service io_service;
|
---|
[db03d9] | 130 | FragmentScheduler Server(io_service, workerport, controllerport);
|
---|
[267b8d] | 131 |
|
---|
| 132 | // catch ctrl-c and shutdown worker properly
|
---|
| 133 | shutdownfunction = boost::bind(&FragmentScheduler::shutdown, boost::ref(Server), _1);
|
---|
| 134 | if (vm.count("signal")) {
|
---|
| 135 | signals = vm["signal"].as< std::vector<size_t> >();
|
---|
| 136 | for (std::vector<size_t>::const_iterator iter = signals.begin();
|
---|
| 137 | iter != signals.end(); ++iter) {
|
---|
| 138 | LOG(0, "STATUS: Catching signal " << *iter << " via signal handler.");
|
---|
| 139 | signal(*iter, &signalhandler);
|
---|
| 140 | }
|
---|
| 141 | } else {
|
---|
| 142 | LOG(0, "STATUS: No signals are caught.");
|
---|
| 143 | }
|
---|
| 144 |
|
---|
[f7f995] | 145 | {
|
---|
| 146 | Info info("io_service");
|
---|
| 147 | io_service.run();
|
---|
| 148 | }
|
---|
[db03d9] | 149 | Exitflag = Server.getExitflag();
|
---|
[f7f995] | 150 | }
|
---|
| 151 | catch (std::exception& e)
|
---|
| 152 | {
|
---|
| 153 | std::cerr << e.what() << std::endl;
|
---|
| 154 | }
|
---|
| 155 |
|
---|
[db03d9] | 156 | return Exitflag;
|
---|
[f7f995] | 157 | }
|
---|