deployer: don't start TaskBrowser when we're a daemon process and fixup log statements
[orocos-toolchain:ocl.git] / bin / deployer-corba.cpp
1 /***************************************************************************
2   tag: Peter Soetens  Thu Jul 3 15:30:24 CEST 2008  deployer-corba.cpp
3
4                         deployer-corba.cpp -  description
5                            -------------------
6     begin                : Thu July 03 2008
7     copyright            : (C) 2008 Peter Soetens
8     email                : peter.soetens@fmtc.be
9
10  ***************************************************************************
11  *   This program is free software; you can redistribute it and/or         *
12  *   modify it under the terms of the GNU Lesser General Public            *
13  *   License as published by the Free Software Foundation; either          *
14  *   version 2.1 of the License, or (at your option) any later version.    *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
19  *   Lesser General Public License for more details.                       *
20  *                                                                         *
21  *   You should have received a copy of the GNU Lesser General Public      *
22  *   License along with this program; if not, write to the Free Software   *
23  *   Foundation, Inc., 59 Temple Place,                                    *
24  *   Suite 330, Boston, MA  02111-1307  USA                                *
25  ***************************************************************************/
26
27
28 #include <rtt/rtt-config.h>
29 #ifdef OS_RT_MALLOC
30 // need access to all TLSF functions embedded in RTT
31 #define ORO_MEMORY_POOL
32 #include <rtt/os/tlsf/tlsf.h>
33 #endif
34 #include <rtt/os/main.h>
35 #include <rtt/RTT.hpp>
36
37 #include <taskbrowser/TaskBrowser.hpp>
38 #include <deployment/CorbaDeploymentComponent.hpp>
39 #include <rtt/transports/corba/TaskContextServer.hpp>
40 #include <iostream>
41 #include "deployer-funcs.hpp"
42
43 #include <rtt/transports/corba/corba.h>
44
45 #ifdef  ORO_BUILD_LOGGING
46 #   ifndef OS_RT_MALLOC
47 #   warning "Logging needs rtalloc!"
48 #   endif
49 #include <log4cpp/HierarchyMaintainer.hh>
50 #include "logging/Category.hpp"
51 #endif
52
53 using namespace std;
54 using namespace RTT;
55 using namespace RTT::corba;
56 namespace po = boost::program_options;
57
58 int main(int argc, char** argv)
59 {
60         std::string                 siteFile;      // "" means use default in DeploymentComponent.cpp
61     std::vector<std::string>    scriptFiles;
62         std::string                 name("Deployer");
63     bool                        requireNameService = false;
64         po::variables_map           vm;
65         po::options_description     taoOptions("Additional options can also be passed to TAO");
66         // we don't actually list any options for TAO ...
67
68         po::options_description     otherOptions;
69
70 #ifdef  ORO_BUILD_RTALLOC
71     OCL::memorySize         rtallocMemorySize   = ORO_DEFAULT_RTALLOC_SIZE;
72         po::options_description rtallocOptions      = OCL::deployerRtallocOptions(rtallocMemorySize);
73         otherOptions.add(rtallocOptions);
74 #endif
75
76 #if     defined(ORO_BUILD_LOGGING) && defined(OROSEM_LOG4CPP_LOGGING)
77     // to support RTT's logging to log4cpp
78     std::string                 rttLog4cppConfigFile;
79     po::options_description     rttLog4cppOptions = OCL::deployerRttLog4cppOptions(rttLog4cppConfigFile);
80     otherOptions.add(rttLog4cppOptions);
81 #endif
82
83     // as last set of options
84     otherOptions.add(taoOptions);
85
86     // were we given TAO options? ie find "--"
87     int     taoIndex    = 0;
88     bool    found       = false;
89
90     while(!found && taoIndex<argc)
91     {
92         found = (0 == strcmp("--", argv[taoIndex]));
93         if(!found) taoIndex++;
94     }
95
96     if (found) {
97         argv[taoIndex] = argv[0];
98     }
99
100     // if TAO options not found then process all command line options,
101     // otherwise process all options up to but not including "--"
102         int rc = OCL::deployerParseCmdLine(!found ? argc : taoIndex, argv,
103                                        siteFile, scriptFiles, name, requireNameService,
104                                        vm, &otherOptions);
105         if (0 != rc)
106         {
107                 return rc;
108         }
109
110
111 #if     defined(ORO_BUILD_LOGGING) && defined(OROSEM_LOG4CPP_LOGGING)
112     if (!OCL::deployerConfigureRttLog4cppCategory(rttLog4cppConfigFile))
113     {
114         return -1;
115     }
116 #endif
117
118 #ifdef  ORO_BUILD_RTALLOC
119     size_t                  memSize     = rtallocMemorySize.size;
120     void*                   rtMem       = 0;
121     if (0 < memSize)
122     {
123         // don't calloc() as is first thing TLSF does.
124         rtMem = malloc(memSize);
125         assert(rtMem);
126         size_t freeMem = init_memory_pool(memSize, rtMem);
127         if ((size_t)-1 == freeMem)
128         {
129             cerr << "Invalid memory pool size of " << memSize
130                           << " bytes (TLSF has a several kilobyte overhead)." << endl;
131             free(rtMem);
132             return -1;
133         }
134         cout << "Real-time memory: " << freeMem << " bytes free of "
135                   << memSize << " allocated." << endl;
136     }
137 #endif  // ORO_BUILD_RTALLOC
138
139 #ifdef  ORO_BUILD_LOGGING
140     // use our log4cpp-derived categories to do real-time logging
141     log4cpp::HierarchyMaintainer::set_category_factory(
142         OCL::logging::Category::createOCLCategory);
143 #endif
144
145     // start Orocos _AFTER_ setting up log4cpp
146         if (0 == __os_init(argc - taoIndex, &argv[taoIndex]))
147     {
148 #ifdef  ORO_BUILD_LOGGING
149         log(Info) << "OCL factory set for real-time logging" << endlog();
150 #endif
151         rc = -1;     // prove otherwise
152         try {
153             // if TAO options not found then have TAO process just the program name,
154             // otherwise TAO processes the program name plus all options (potentially
155             // none) after "--"
156             TaskContextServer::InitOrb( argc - taoIndex, &argv[taoIndex] );
157
158             OCL::CorbaDeploymentComponent dc( name, siteFile );
159
160             if (0 == TaskContextServer::Create( &dc, true, requireNameService ))
161                 {
162                     return -1;
163                 }
164
165             // The orb thread accepts incomming CORBA calls.
166             TaskContextServer::ThreadOrb();
167
168             // Only start the scripts after the Orb was created.
169             for (std::vector<std::string>::const_iterator iter=scriptFiles.begin();
170                  iter!=scriptFiles.end();
171                  ++iter)
172             {
173                 if ( !(*iter).empty() )
174                 {
175                     if ( (*iter).rfind(".xml",string::npos) == (*iter).length() - 4 || (*iter).rfind(".cpf",string::npos) == (*iter).length() - 4) {
176                         dc.kickStart( (*iter) );
177                         continue;
178                     } if ( (*iter).rfind(".ops",string::npos) == (*iter).length() - 4 || (*iter).rfind(".osd",string::npos) == (*iter).length() - 4) {
179                         dc.runScript( (*iter) );
180                         continue;
181                     }
182                     log(Error) << "Unknown extension of file: '"<< (*iter) <<"'. Must be xml, cpf for XML files or, ops or osd for script files."<<endlog();
183                 }
184             }
185
186             if ( !vm.count("daemon") ) {
187                  OCL::TaskBrowser tb( &dc );
188                  tb.loop();
189             }
190
191             TaskContextServer::ShutdownOrb();
192
193             TaskContextServer::DestroyOrb();
194
195             rc = 0;
196
197         } catch( CORBA::Exception &e ) {
198             log(Error) << argv[0] <<" ORO_main : CORBA exception raised!" << Logger::nl;
199             log() << CORBA_EXCEPTION_INFO(e) << endlog();
200         } catch (...) {
201             // catch this so that we can destroy the TLSF memory correctly
202             log(Error) << "Uncaught exception." << endlog();
203         }
204
205                 // shutdown Orocos
206                 __os_exit();
207         }
208         else
209         {
210                 std::cerr << "Unable to start Orocos" << std::endl;
211         rc = -1;
212         }
213
214 #ifdef  ORO_BUILD_RTALLOC
215     if (!rtMem)
216     {
217         destroy_memory_pool(rtMem);
218         free(rtMem);
219     }
220 #endif  // ORO_BUILD_RTALLOC
221
222     return rc;
223 }