GCC Code Coverage Report


Directory: ./
File: src/server.cc
Date: 2025-03-26 15:03:21
Exec Total Coverage
Lines: 34 130 26.2%
Branches: 35 416 8.4%

Line Branch Exec Source
1 // Copyright (C) 2019 by Joseph Mirabel
2 //
3 // This file is part of hpp-template-corba
4 //
5 // This software is provided "as is" without warranty of any kind,
6 // either expressed or implied, including but not limited to the
7 // implied warranties of fitness for a particular purpose.
8 //
9 // See the COPYING file for more information.
10
11 #include <pthread.h>
12 #include <stdio.h>
13
14 #include <hpp/corba/template/server.hh>
15 #include <iostream>
16
17 namespace hpp {
18 namespace corba {
19 using CORBA::COMM_FAILURE;
20 using CORBA::Exception;
21 using CORBA::Object_ptr;
22 using CORBA::Object_var;
23 using CORBA::ORB_init;
24 using CORBA::PolicyList;
25 using CORBA::SystemException;
26 using omniORB::fatalException;
27
28 typedef CORBA::ORB::InvalidName InvalidName;
29
30 namespace {
31 /// \brief Forward logging messages to hpp logging mechanism.
32 /// If debug is disabled, CORBA logging will be disabled too.
33 ///
34 /// Tracing has to be enabled in your ``omniORB.cfg'' to use this
35 /// feature.
36 /// See ``omniORB configuration and API'' > ``Tracing options''
37 /// section of omniORB manual for more information.
38 void logFunction(const char* msg);
39
40 void logFunction(const char* msg) {
41 (void)msg;
42 hppCorbaDout(info, "omniORB: " << msg);
43 }
44 } // end of anonymous namespace.
45
46 1 ServerBase::ServerBase(int argc, const char* argv[], const char* orb_identifier,
47
5/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 const char* options[][2]) {
48 // Register log function.
49
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 omniORB::setLogFunction(&logFunction);
50
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 initORB(argc, argv, orb_identifier, options);
51 1 }
52
53 2 ServerBase::~ServerBase() {}
54
55 1 void ServerBase::setServant(CORBA::Object_ptr obj) { servant_ = obj; }
56
57 /*
58 CORBA SERVER INITIALIZATION
59 */
60 1 bool ServerBase::initORB(int argc, const char* argv[],
61 const char* orb_identifier, const char* options[][2]) {
62 try {
63
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 orb_ = ORB_init(argc, const_cast<char**>(argv), orb_identifier, options);
64
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 if (is_nil(orb_)) {
65 hppCorbaDout(error, "failed to initialize ORB");
66 return false;
67 }
68 }
69 HPP_CORBA_CATCH("failed to initialize ORB", false);
70 1 return true;
71 }
72
73 1 bool ServerBase::initRootPOA(bool inMultiThread) {
74
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Object_var obj;
75
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PortableServer::ThreadPolicy_var threadPolicy;
76
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PortableServer::POA_var rootPoa;
77
78 try {
79
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 obj = orb_->resolve_initial_references("RootPOA");
80 }
81 HPP_CORBA_CATCH("failed to resolve initial references", false);
82
83 /*
84 Create and duplicate thread policy
85 */
86
87 try {
88 //
89 // Make the CORBA object single-threaded to avoid GUI krash
90 //
91 // Create a sigle threaded policy object
92
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 rootPoa = PortableServer::POA::_narrow(obj);
93
94
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (inMultiThread) {
95 threadPolicy =
96
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 rootPoa->create_thread_policy(PortableServer::ORB_CTRL_MODEL);
97 } else {
98 threadPolicy =
99 rootPoa->create_thread_policy(PortableServer::MAIN_THREAD_MODEL);
100 }
101 }
102 HPP_CORBA_CATCH("failed to create thread policy", false);
103
104 1 PolicyList policyList;
105
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 policyList.length(1);
106
107 try {
108
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 policyList[0] = PortableServer::ThreadPolicy::_duplicate(threadPolicy);
109 }
110 HPP_CORBA_CATCH("failed to duplicate thread policy", false);
111
112 // Find or create the POA
113 try {
114 try {
115
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
1 main_poa_ = rootPoa->find_POA("child", false);
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } catch (const CORBA::UserException& exc) {
117 main_poa_ =
118
3/6
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
1 rootPoa->create_POA("child", rootPoa->the_POAManager(), policyList);
119
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 }
120 }
121 HPP_CORBA_CATCH("failed to find or create POA", false);
122
123 // Destroy policy object
124 try {
125
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 threadPolicy->destroy();
126 }
127 HPP_CORBA_CATCH("failed to destroy thread policy", false);
128
129 1 return true;
130 1 }
131
132 bool ServerBase::initOmniINSPOA() {
133 Object_var obj;
134 try {
135 obj = orb_->resolve_initial_references("omniINSPOA");
136 } catch (CORBA::SystemException& e) {
137 std::cerr << "OmniORB::resolve_initial_references throws "
138 "CORBA::SystemException "
139 << e.NP_minorString() << '\n';
140 perror("A possible reason");
141 return false;
142 } catch (CORBA::Exception& e) {
143 std::cerr << "OmniORB::resolve_initial_references throws "
144 "CORBA::Exception"
145 << std::endl;
146 return false;
147 }
148
149 try {
150 ins_poa_ = PortableServer::POA::_narrow(obj);
151 }
152 HPP_CORBA_CATCH("failed to narrow the POA", false);
153
154 return true;
155 }
156
157 int ServerBase::startCorbaServer(const std::string& contextId,
158 const std::string& contextKind,
159 const std::string& objectId,
160 const std::string& objectKind) {
161 try {
162 // Obtain a reference to objects, and register them in
163 // the naming service.
164
165 if (!createHppContext(contextId, contextKind)) {
166 return -1;
167 }
168 CosNaming::Name objectName;
169 objectName.length(1);
170 objectName[0].id = (const char*)objectId.c_str();
171 objectName[0].kind = (const char*)objectKind.c_str();
172
173 if (!bindObjectToName(servant_, objectName)) {
174 return -1;
175 }
176 }
177 HPP_CORBA_CATCH("failed to start CORBA server", false)
178 return 0;
179
180 return startCorbaServer();
181 }
182
183 int ServerBase::startCorbaServer(const std::string& contextId,
184 const std::string& contextKind) {
185 CosNaming::NamingContext_var rootContext;
186 Object_var localObj;
187
188 try {
189 // Obtain a reference to the root context of the Name service:
190 localObj = orb_->resolve_initial_references("NameService");
191 }
192 HPP_CORBA_CATCH("failed to get the name service", -1);
193
194 try {
195 // Narrow the reference returned.
196 rootContext = CosNaming::NamingContext::_narrow(localObj);
197 if (is_nil(rootContext)) {
198 hppCorbaDout(error, "Failed to narrow the root naming context.");
199 return -1;
200 }
201 } catch (InvalidName& ex) {
202 // This should not happen!
203 hppCorbaDout(error, "Service required is invalid [does not exist].");
204 return -1;
205 }
206 HPP_CORBA_CATCH("failed to narrow the root naming context.", -1);
207
208 try {
209 // Obtain a reference to objects, and register them in
210 // the naming service.
211 CosNaming::Name objectName;
212 objectName.length(1);
213 objectName[0].id = (const char*)contextId.c_str();
214 objectName[0].kind = (const char*)contextKind.c_str();
215
216 if (!bindObjectToName(rootContext, servant_, objectName)) return -1;
217 }
218 HPP_CORBA_CATCH("failed to start CORBA server", -1)
219
220 return startCorbaServer();
221 }
222
223 1 int ServerBase::startCorbaServer() {
224 try {
225
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 PortableServer::POAManager_var pman = poa()->the_POAManager();
226
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 pman->activate();
227 1 }
228 HPP_CORBA_CATCH("failed to start CORBA server", false);
229 1 return 0;
230 }
231
232 int ServerBase::processRequest(bool loop) {
233 if (loop) {
234 hppCorbaDout(info, "start processing CORBA requests for ever.");
235 orb_->run();
236 } else {
237 if (orb_->work_pending()) orb_->perform_work();
238 }
239 return 0;
240 }
241
242 bool ServerBase::createHppContext(const std::string& id,
243 const std::string kind) {
244 CosNaming::NamingContext_var rootContext;
245 Object_var localObj;
246 CosNaming::Name contextName;
247
248 try {
249 // Obtain a reference to the root context of the Name service:
250 localObj = orb_->resolve_initial_references("NameService");
251 }
252 HPP_CORBA_CATCH("failed to get the name service", false)
253
254 try {
255 // Narrow the reference returned.
256 rootContext = CosNaming::NamingContext::_narrow(localObj);
257 if (is_nil(rootContext)) {
258 hppCorbaDout(error, "Failed to narrow the root naming context.");
259 return false;
260 }
261 } catch (InvalidName& ex) {
262 // This should not happen!
263 hppCorbaDout(error, "Service required is invalid [does not exist].");
264 return false;
265 }
266 HPP_CORBA_CATCH("failed to narrow the root naming context.", false)
267
268 try {
269 // Bind a context called "hpp" to the root context:
270
271 contextName.length(1);
272 contextName[0].id = (const char*)id.c_str(); // string copied
273 contextName[0].kind = (const char*)kind.c_str(); // string copied
274 // Note on kind: The kind field is used to indicate the type
275 // of the object. This is to avoid conventions such as that used
276 // by files (name.type -- e.g. hpp.ps = postscript etc.)
277
278 try {
279 // Bind the context to root.
280 hppContext_ = rootContext->bind_new_context(contextName);
281 } catch (CosNaming::NamingContext::AlreadyBound& ex) {
282 // If the context already exists, this exception will be raised.
283 // In this case, just resolve the name and assign hppContext
284 // to the object returned:
285 Object_var localObj;
286 localObj = rootContext->resolve(contextName);
287 hppContext_ = CosNaming::NamingContext::_narrow(localObj);
288 if (is_nil(hppContext_)) {
289 hppCorbaDout(error, "Failed to narrow naming context.");
290 return false;
291 }
292 }
293 } catch (COMM_FAILURE& ex) {
294 hppCorbaDout(
295 error, "Caught system exception COMM_FAILURE -- unable to contact the "
296 << "naming service.");
297 return false;
298 } catch (SystemException&) {
299 hppCorbaDout(error, "Caught a SystemException while creating the context.");
300 return false;
301 }
302
303 return true;
304 }
305
306 bool ServerBase::bindObjectToName(Object_ptr objref,
307 CosNaming::Name objectName) {
308 return bindObjectToName(hppContext_, objref, objectName);
309 }
310
311 bool ServerBase::bindObjectToName(CosNaming::NamingContext_ptr context,
312 CORBA::Object_ptr objref,
313 CosNaming::Name objectName) {
314 try {
315 context->bind(objectName, objref);
316 } catch (CosNaming::NamingContext::AlreadyBound& ex) {
317 context->rebind(objectName, objref);
318 }
319 // Note: Using rebind() will overwrite any Object previously bound
320 // to /hpp/RobotConfig with localObj.
321 // Alternatively, bind() can be used, which will raise a
322 // CosNaming::NamingContext::AlreadyBound exception if the name
323 // supplied is already bound to an object.
324
325 // Amendment: When using OrbixNames, it is necessary to first try bind
326 // and then rebind, as rebind on it's own will throw a NotFoundexception if
327 // the Name has not already been bound. [This is incorrect behaviour -
328 // it should just bind].
329 catch (COMM_FAILURE& ex) {
330 hppCorbaDout(
331 error, "Caught system exception COMM_FAILURE -- unable to contact the "
332 << "naming service.");
333 return false;
334 } catch (SystemException&) {
335 hppCorbaDout(
336 error,
337 "Caught a SystemException while binding object to name service.");
338 return false;
339 }
340
341 return true;
342 }
343
344 } // end of namespace corba.
345 } // end of namespace hpp.
346