1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    sumo_main.cpp
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Axel Wegener
14 /// @author  Thimor Bohn
15 /// @author  Michael Behrisch
16 /// @date    Tue, 20 Nov 2001
17 /// @version $Id$
18 ///
19 // Main for SUMO
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #ifdef HAVE_VERSION_H
29 #include <version.h>
30 #endif
31 
32 #include <ctime>
33 #include <csignal>
34 #include <string>
35 #include <iostream>
36 #include <netload/NLBuilder.h>
37 #include <utils/options/OptionsCont.h>
38 #include <utils/options/OptionsIO.h>
39 #include <utils/iodevices/OutputDevice.h>
40 #include <utils/common/MsgHandler.h>
41 #include <utils/common/SystemFrame.h>
42 #include <utils/common/UtilExceptions.h>
43 #include <utils/common/ToString.h>
44 #include <utils/common/StdDefs.h>
45 #include <utils/xml/XMLSubSys.h>
46 #include <traci-server/TraCIServer.h>
47 
48 
49 // ===========================================================================
50 // functions
51 // ===========================================================================
52 void
signalHandler(int signum)53 signalHandler(int signum) {
54     if (MSNet::hasInstance()) {
55         switch (signum) {
56             case SIGINT:
57             case SIGTERM:
58                 if (MSNet::getInstance()->isInterrupted()) {
59                     std::cout << "Another interrupt signal received, hard exit." << std::endl;
60                     exit(signum);
61                 }
62                 std::cout << "Interrupt signal received, trying to exit gracefully." << std::endl;
63                 MSNet::getInstance()->interrupt();
64                 break;
65 #ifndef _MSC_VER
66             case SIGUSR1:
67                 std::cout << "Step #" << SIMSTEP << std::endl;
68                 std::cout << MSNet::getInstance()->generateStatistics(string2time(OptionsCont::getOptions().getString("begin"))) << std::endl;
69                 break;
70             case SIGUSR2:
71                 //TODO reload sim
72                 break;
73 #endif
74             default:
75                 break;
76         }
77     }
78 }
79 
80 
81 /* -------------------------------------------------------------------------
82  * main
83  * ----------------------------------------------------------------------- */
84 int
main(int argc,char ** argv)85 main(int argc, char** argv) {
86     signal(SIGINT, signalHandler);
87     signal(SIGTERM, signalHandler);
88 #ifndef _MSC_VER
89     signal(SIGUSR1, signalHandler);
90     signal(SIGUSR2, signalHandler);
91 #endif
92 
93     OptionsCont& oc = OptionsCont::getOptions();
94     // give some application descriptions
95     oc.setApplicationDescription("A microscopic, multi-modal traffic simulation.");
96     oc.setApplicationName("sumo", "Eclipse SUMO Version " VERSION_STRING);
97     gSimulation = true;
98     int ret = 0;
99     MSNet* net = nullptr;
100     try {
101         // initialise subsystems
102         XMLSubSys::init();
103         OptionsIO::setArgs(argc, argv);
104         // load the net
105         MSNet::SimulationState state = MSNet::SIMSTATE_LOADING;
106         while (state == MSNet::SIMSTATE_LOADING) {
107             net = NLBuilder::init();
108             if (net != nullptr) {
109                 state = net->simulate(string2time(oc.getString("begin")), string2time(oc.getString("end")));
110                 delete net;
111             } else {
112                 break;
113             }
114         }
115     } catch (const ProcessError& e) {
116         if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
117             WRITE_ERROR(e.what());
118         }
119         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
120         // we need to delete the network explicitly to trigger the cleanup in the correct order
121         delete net;
122         ret = 1;
123 #ifndef _DEBUG
124     } catch (const std::exception& e) {
125         if (std::string(e.what()) != std::string("")) {
126             WRITE_ERROR(e.what());
127         }
128         MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
129         ret = 1;
130     } catch (...) {
131         MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
132         ret = 1;
133 #endif
134     }
135     TraCIServer::close();
136     SystemFrame::close();
137     return ret;
138 }
139 
140 
141 /****************************************************************************/
142