deployer: don't start TaskBrowser when we're a daemon process and fixup log statements
[orocos-toolchain:ocl.git] / bin / deployer.cpp
1 /***************************************************************************
2   tag: Peter Soetens  Thu Jul 3 15:30:14 CEST 2008  deployer.cpp
3
4                         deployer.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 #include <rtt/rtt-config.h>
28 #ifdef OS_RT_MALLOC
29 // need access to all TLSF functions embedded in RTT
30 #define ORO_MEMORY_POOL
31 #include <rtt/os/tlsf/tlsf.h>
32 #endif
33 #include <rtt/os/main.h>
34 #include <rtt/RTT.hpp>
35 #include <rtt/Logger.hpp>
36
37 #ifndef RTT_SCRIPT_PROGRAM
38 #define USE_TASKBROWSER
39 #endif
40
41 #ifdef USE_TASKBROWSER
42 #include <taskbrowser/TaskBrowser.hpp>
43 #endif
44 #include <deployment/DeploymentComponent.hpp>
45 #include <iostream>
46 #include <string>
47 #include "deployer-funcs.hpp"
48
49 #ifdef  ORO_BUILD_LOGGING
50 #   ifndef OS_RT_MALLOC
51 #   warning "Logging needs rtalloc!"
52 #   endif
53 #include <log4cpp/HierarchyMaintainer.hh>
54 #include "logging/Category.hpp"
55 #endif
56
57 using namespace RTT;
58 namespace po = boost::program_options;
59 using namespace std;
60
61 int main(int argc, char** argv)
62 {
63         std::string                 siteFile;      // "" means use default in DeploymentComponent.cpp
64     std::vector<std::string>    scriptFiles;
65         std::string                 name("Deployer");
66     bool                        requireNameService = false;         // not used
67     po::variables_map           vm;
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     // were we given non-deployer options? ie find "--"
84     int     optIndex    = 0;
85     bool    found       = false;
86
87     while(!found && optIndex<argc)
88     {
89         found = (0 == strcmp("--", argv[optIndex]));
90         if(!found) optIndex++;
91     }
92
93     if (found) {
94         argv[optIndex] = argv[0];
95     }
96
97     // if extra options not found then process all command line options,
98     // otherwise process all options up to but not including "--"
99     int rc = OCL::deployerParseCmdLine(!found ? argc : optIndex, argv,
100                                        siteFile, scriptFiles, name, requireNameService,
101                                        vm, &otherOptions);
102
103     if (0 != rc)
104         {
105                 return rc;
106         }
107
108 #if     defined(ORO_BUILD_LOGGING) && defined(OROSEM_LOG4CPP_LOGGING)
109     if (!OCL::deployerConfigureRttLog4cppCategory(rttLog4cppConfigFile))
110     {
111         return -1;
112     }
113 #endif
114
115 #ifdef  ORO_BUILD_RTALLOC
116     size_t                  memSize     = rtallocMemorySize.size;
117     void*                   rtMem       = 0;
118     size_t                  freeMem     = 0;
119     if (0 < memSize)
120     {
121         // don't calloc() as is first thing TLSF does.
122         rtMem = malloc(memSize);
123         assert(0 != rtMem);
124         freeMem = init_memory_pool(memSize, rtMem);
125         if ((size_t)-1 == freeMem)
126         {
127             cerr << "Invalid memory pool size of " << memSize 
128                           << " bytes (TLSF has a several kilobyte overhead)." << endl;
129             free(rtMem);
130             return -1;
131         }
132         cout << "Real-time memory: " << freeMem << " bytes free of "
133                   << memSize << " allocated." << endl;
134     }
135 #endif  // ORO_BUILD_RTALLOC
136
137 #ifdef  ORO_BUILD_LOGGING
138     log4cpp::HierarchyMaintainer::set_category_factory(
139         OCL::logging::Category::createOCLCategory);
140 #endif
141
142
143     /******************** WARNING ***********************
144      *   NO log(...) statements before __os_init() !!!!! 
145      ***************************************************/
146
147     // start Orocos _AFTER_ setting up log4cpp
148         if (0 == __os_init(argc - optIndex, &argv[optIndex]))
149     {
150 #ifdef  ORO_BUILD_LOGGING
151         log(Info) << "OCL factory set for real-time logging" << endlog();
152 #endif
153         // scope to force dc destruction prior to memory free
154         {
155             OCL::DeploymentComponent dc( name, siteFile );
156
157             for (std::vector<std::string>::const_iterator iter=scriptFiles.begin();
158                  iter!=scriptFiles.end();
159                  ++iter)
160             {
161                 if ( !(*iter).empty() )
162                 {
163                     if ( (*iter).rfind(".xml",std::string::npos) == (*iter).length() - 4 || (*iter).rfind(".cpf",std::string::npos) == (*iter).length() - 4) {
164                         dc.kickStart( (*iter) );
165                         continue;
166                     } if ( (*iter).rfind(".ops",std::string::npos) == (*iter).length() - 4 || (*iter).rfind(".osd",std::string::npos) == (*iter).length() - 4) {
167                         dc.runScript( (*iter) );
168                         continue;
169                     }
170                     log(Error) << "Unknown extension of file: '"<< (*iter) <<"'. Must be xml, cpf for XML files or, ops or osd for script files."<<endlog();
171                 }
172             }
173 #ifdef USE_TASKBROWSER
174             // We don't start an interactive console when we're a daemon
175             if ( !vm.count("daemon") ) {
176                 OCL::TaskBrowser tb( &dc );
177
178                 tb.loop();
179             }
180 #endif
181         }
182 #ifdef  ORO_BUILD_RTALLOC
183         if (0 != rtMem)
184             {
185                 // print statistics after deployment finished, but before os_exit() (needs Logger):
186                 log(Debug) << "TLSF bytes allocated=" << memSize
187                            << " overhead=" << (memSize - freeMem)
188                            << " max-used=" << get_max_size(rtMem)
189                            << " currently-used=" << get_used_size(rtMem)
190                            << " still-allocated=" << (get_used_size(rtMem) - (memSize - freeMem))
191                            << endlog();
192             }
193 #endif
194
195         __os_exit();
196         rc = 0;
197         }
198         else
199         {
200                 std::cerr << "Unable to start Orocos" << std::endl;
201         rc = -1;
202         }
203
204 #ifdef  ORO_BUILD_LOGGING
205     log4cpp::HierarchyMaintainer::getDefaultMaintainer().shutdown();
206     log4cpp::HierarchyMaintainer::getDefaultMaintainer().deleteAllCategories();
207 #endif
208
209 #ifdef  ORO_BUILD_RTALLOC
210     if (0 != rtMem)
211     {
212         std::cout << "TLSF bytes allocated=" << memSize
213                   << " overhead=" << (memSize - freeMem)
214                   << " max-used=" << get_max_size(rtMem)
215                   << " currently-used=" << get_used_size(rtMem)
216                   << " still-allocated=" << (get_used_size(rtMem) - (memSize - freeMem))
217                   << "\n";
218
219         destroy_memory_pool(rtMem);
220         free(rtMem);
221     }
222 #endif
223
224     return rc;
225 }