Orocos Real-Time Toolkit  2.6.0
startstop.cpp
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon May 10 19:10:29 CEST 2004  startstop.cxx
00003 
00004                         startstop.cxx -  description
00005                            -------------------
00006     begin                : Mon May 10 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00045 #include "../rtt-config.h"
00046 #include <os/startstop.h>
00047 #include "os/MainThread.hpp"
00048 #include "os/StartStopManager.hpp"
00049 #include "../internal/GlobalEngine.hpp"
00050 #include "../types/GlobalsRepository.hpp"
00051 #include "../types/TypekitRepository.hpp"
00052 
00053 #ifdef OROPKG_OS_THREAD_SCOPE
00054 # include <boost/scoped_ptr.hpp>
00055 # include "../extras/dev/DigitalOutInterface.hpp"
00056   using namespace RTT;
00057 #endif
00058 
00059 #ifdef OS_HAVE_IOSTREAM
00060 #include <iostream>
00061 using namespace std;
00062 #else
00063 #include <cstdio>
00064 #endif
00065 
00066 #include "../Logger.hpp"
00067 #include "TimeService.hpp"
00068 
00069 using namespace RTT;
00070 using namespace RTT::os;
00071 static os::StartStopManager* initM;
00072 
00073 static int os_argc_arg;
00074 static char** os_argv_arg;
00075 
00076 int __os_init(int argc, char** argv )
00077 {
00078 #ifdef OS_HAVE_MANUAL_CRT
00079     DO_GLOBAL_CTORS();
00080 #endif
00081 
00082     os_argc_arg = argc;
00083     os_argv_arg = argv;
00084 
00085     os::MainThread::Instance();
00086     Logger::log() << Logger::Debug << "MainThread started." << Logger::endl;
00087 
00088     Logger::log() << Logger::Debug << "Starting StartStopManager." << Logger::endl;
00089     initM = os::StartStopManager::Instance();
00090     int ret = initM->start() ? 0 : 1;
00091 
00092 #ifdef OROPKG_OS_THREAD_SCOPE
00093         unsigned int bit = 0;
00094 
00095         boost::scoped_ptr<DigitalOutInterface> pp;
00096         DigitalOutInterface* d = 0;
00097         // this is the device users can use across all threads to control the
00098         // scope's output.
00099         if ( DigitalOutInterface::nameserver.getObject("ThreadScope") )
00100             d = DigitalOutInterface::nameserver.getObject("ThreadScope");
00101         else
00102             Logger::log() << Logger::Error<< "Failed to find 'ThreadScope' object in DigitalOutInterface::nameserver." << Logger::endl;
00103         if ( d ) {
00104             Logger::log() << Logger::Info << "ThreadScope : main thread toggles bit "<< bit << Logger::endl;
00105             d->switchOn( bit );
00106         }
00107 #endif
00108         return ret;
00109 }
00110 
00111 int __os_main_argc(void) {
00112     return os_argc_arg;
00113 }
00114 char** __os_main_argv(void) {
00115     return os_argv_arg;
00116 }
00117 
00118 void __os_printFailure(const char* prog)
00119 {
00120 #ifdef OS_HAVE_IOSTREAM
00121                         cerr <<endl<< " Orocos has detected an uncaught C++ exception"<<endl;
00122                         cerr << " in the ORO_main() function."<<endl;
00123                         cerr << " You might have called a function which throws"<<endl;
00124                         cerr << " without a try {} catch {} block."<< endl << endl;
00125                         cerr << "To Debug this situation, issue the following command:"<<endl<<endl;
00126                         cerr << "   valgrind -v --num-callers=16 "<< prog <<" [options...] --nocatch" << endl;
00127                         cerr << "Which will show where the exception occured."<<endl;
00128                         cerr << " ( Change num-callers for more/less detail."<<endl;
00129                         cerr << "   Also, compiling orocos and your program with"<<endl;
00130                         cerr << "   -g adds more usefull information. )"<<endl<<endl;
00131 #else
00132                         printf("Orocos intercepted an uncaught C++ exception\n");
00133 #endif
00134 
00135 }
00136 
00137 void __os_printException(const char* prog, std::exception& arg)
00138 {
00139 #ifdef OS_HAVE_IOSTREAM
00140                         cerr << endl<<" Caught std::exception." << endl << "  what(): " << arg.what() <<endl;
00141 #endif
00142                         __os_printFailure(prog);
00143 }
00144 
00145 const char* oro_catchflag = "--nocatch";
00146 const char* oro_catchflag2 = "--no-catch";
00147 
00148 int __os_checkException(int& argc, char** argv)
00149 {
00150     bool dotry = true;
00151     // look for --nocatch/--no-catch flag :
00152     for( int i=1; i < argc; ++i)
00153         if ( strncmp(oro_catchflag, argv[i], strlen(oro_catchflag) ) == 0
00154                 || strncmp(oro_catchflag2, argv[i], strlen(oro_catchflag2) ) == 0 ) {
00155             // if --no-catch was given last, remove it from the argc.
00156             if ( i == argc-1)
00157                 --argc;
00158             dotry = false;
00159         }
00160 
00161     return dotry;
00162 }
00163 
00164 void __os_exit(void)
00165 {
00166 #ifdef OROPKG_OS_THREAD_SCOPE
00167         if (d)
00168             d->switchOff(bit);
00169 #endif
00170 
00171     internal::GlobalEngine::Release();
00172 
00173     types::GlobalsRepository::Release();
00174 
00175     types::TypekitRepository::Release();
00176 
00177     Logger::log() << Logger::Debug << "Stopping StartStopManager." << Logger::endl;
00178     initM->stop();
00179     os::StartStopManager::Release();
00180 
00181     // This should be the (one but) last message to be logged :
00182     Logger::log() << Logger::Debug << "Stopping MainThread." << Logger::endl;
00183 
00184     // Stop logging
00185     Logger::Release();
00186 
00187     // Stop TimeService if present.
00188     TimeService::Release();
00189 
00190     // Stop Main Thread
00191     os::MainThread::Release();
00192 
00193 #ifdef OS_HAVE_MANUAL_CRT
00194     DO_GLOBAL_DTORS();
00195 #endif
00196 }