| Directory: | ./ |
|---|---|
| File: | src/server.cc |
| Date: | 2025-05-11 11:10:19 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 102 | 240 | 42.5% |
| Branches: | 79 | 417 | 18.9% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (C) 2009, 2010 by Florent Lamiraux, Thomas Moulard, JRL. | ||
| 2 | // | ||
| 3 | |||
| 4 | // Redistribution and use in source and binary forms, with or without | ||
| 5 | // modification, are permitted provided that the following conditions are | ||
| 6 | // met: | ||
| 7 | // | ||
| 8 | // 1. Redistributions of source code must retain the above copyright | ||
| 9 | // notice, this list of conditions and the following disclaimer. | ||
| 10 | // | ||
| 11 | // 2. Redistributions in binary form must reproduce the above copyright | ||
| 12 | // notice, this list of conditions and the following disclaimer in the | ||
| 13 | // documentation and/or other materials provided with the distribution. | ||
| 14 | // | ||
| 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 16 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 17 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 18 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 19 | // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 20 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 21 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 23 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 24 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 25 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| 26 | // DAMAGE. | ||
| 27 | // | ||
| 28 | // This software is provided "as is" without warranty of any kind, | ||
| 29 | // either expressed or implied, including but not limited to the | ||
| 30 | // implied warranties of fitness for a particular purpose. | ||
| 31 | // | ||
| 32 | // See the COPYING file for more information. | ||
| 33 | |||
| 34 | #include "hpp/corbaserver/server.hh" | ||
| 35 | |||
| 36 | #include <dlfcn.h> | ||
| 37 | #include <errno.h> | ||
| 38 | #include <pthread.h> | ||
| 39 | #include <stdlib.h> | ||
| 40 | |||
| 41 | #include <hpp/corbaserver/server-plugin.hh> | ||
| 42 | #include <hpp/core/plugin.hh> | ||
| 43 | #include <hpp/util/debug.hh> | ||
| 44 | #include <hpp/util/exception-factory.hh> | ||
| 45 | #include <iostream> | ||
| 46 | |||
| 47 | #include "basic-server.hh" | ||
| 48 | #include "hpp/corbaserver/conversions.hh" | ||
| 49 | #include "hpp/corbaserver/servant-base.hh" | ||
| 50 | #include "hpp/corbaserver/tools-idl.hh" | ||
| 51 | |||
| 52 | namespace hpp { | ||
| 53 | namespace corbaServer { | ||
| 54 | using CORBA::Exception; | ||
| 55 | using CORBA::Object_var; | ||
| 56 | using CORBA::SystemException; | ||
| 57 | using omniORB::fatalException; | ||
| 58 | |||
| 59 | namespace { | ||
| 60 | ✗ | void usage(const char* app) { | |
| 61 | std::cerr | ||
| 62 | << "Usage: " << app << " [options] ...\n" | ||
| 63 | << " --name <name> \n" | ||
| 64 | << " --host <host> \n" | ||
| 65 | << " --port <port> \n" | ||
| 66 | << " --help \n" | ||
| 67 | << " --verbosity <level>\twhere level is a positive integer between 0 " | ||
| 68 | "(no logs) to 50 (very verbose).\n" | ||
| 69 | << " --benchmark \tenable benchmarking (written in the logs).\n" | ||
| 70 | << " --single-thread \n" | ||
| 71 | << " --multi-thread \n" | ||
| 72 | << "\n" | ||
| 73 | "Environment variables:\n" | ||
| 74 | "- HPP_LOGGINGDIR: change the directory where logs are written.\n" | ||
| 75 | "- HPP_HOST: change the default host.\n" | ||
| 76 | ✗ | "- HPP_PORT: change the default port.\n" | |
| 77 | ✗ | << std::flush; | |
| 78 | } | ||
| 79 | |||
| 80 | 8 | std::string endPoint(const std::string& host, const int port) { | |
| 81 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | std::ostringstream oss; |
| 82 |
4/8✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
|
8 | oss << "::" << host << ':' << port; |
| 83 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | return oss.str(); |
| 84 | 8 | } | |
| 85 | } // end of anonymous namespace. | ||
| 86 | |||
| 87 | class Tools : public virtual POA_hpp::Tools { | ||
| 88 | public: | ||
| 89 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | Tools() : server_(NULL) {}; |
| 90 | |||
| 91 | 8 | void setServer(Server* server) { server_ = server; } | |
| 92 | |||
| 93 | ✗ | virtual CORBA::Boolean loadServerPlugin(const char* context, | |
| 94 | const char* pluginName) { | ||
| 95 | try { | ||
| 96 | ✗ | std::string c(context), pn(pluginName); | |
| 97 | ✗ | return server_->loadPlugin(c, pn); | |
| 98 | ✗ | } catch (const std::exception& e) { | |
| 99 | ✗ | throw hpp::Error(e.what()); | |
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | ✗ | virtual CORBA::Boolean createContext(const char* context) { | |
| 104 | try { | ||
| 105 | ✗ | std::string c(context); | |
| 106 | ✗ | return server_->createContext(c); | |
| 107 | ✗ | } catch (const std::exception& e) { | |
| 108 | ✗ | throw hpp::Error(e.what()); | |
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | ✗ | virtual Names_t* getContexts() { | |
| 113 | try { | ||
| 114 | ✗ | std::vector<std::string> contexts(server_->getContexts()); | |
| 115 | ✗ | return toNames_t(contexts); | |
| 116 | ✗ | } catch (const std::exception& e) { | |
| 117 | ✗ | throw hpp::Error(e.what()); | |
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | ✗ | bool deleteContext(const char* context) { | |
| 122 | try { | ||
| 123 | ✗ | std::string c(context); | |
| 124 | ✗ | return server_->deleteContext(c); | |
| 125 | ✗ | } catch (const std::exception& e) { | |
| 126 | ✗ | throw hpp::Error(e.what()); | |
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | 27 | CORBA::Object_ptr getServer(const char* contextName, const char* pluginName, | |
| 131 | const char* objectName) { | ||
| 132 | try { | ||
| 133 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | std::string c(contextName); |
| 134 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | std::string p(pluginName); |
| 135 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | std::string o(objectName); |
| 136 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
54 | return server_->getServer(c, p, o); |
| 137 |
0/2✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
27 | } catch (const std::exception& e) { |
| 138 | ✗ | throw hpp::Error(e.what()); | |
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | ✗ | virtual void deleteServant(const char* id) { | |
| 143 | try { | ||
| 144 | ✗ | CORBA::Object_ptr obj = server_->orb()->string_to_object(id); | |
| 145 | PortableServer::ObjectId_var objectId = | ||
| 146 | ✗ | server_->poa()->reference_to_id(obj); | |
| 147 | // Remove reference in servant object map | ||
| 148 | ✗ | ServantBase_var servant = server_->poa()->id_to_servant(objectId.in()); | |
| 149 | ✗ | server_->removeServant(servant.in()); | |
| 150 | // Deactivate object | ||
| 151 | ✗ | server_->poa()->deactivate_object(objectId.in()); | |
| 152 | ✗ | } catch (const std::exception& e) { | |
| 153 | ✗ | throw hpp::Error(e.what()); | |
| 154 | ✗ | } catch (PortableServer::POA::ObjectNotActive const& e) { | |
| 155 | // This allows to call `deleteServant` twice on the | ||
| 156 | // same object. OmniORB and Python does not offer a nice mechanism | ||
| 157 | // to avoid calling this method twice. We simply warn because | ||
| 158 | // there should be no harm in continuing the program since | ||
| 159 | // the request was to delete an object which has already been | ||
| 160 | // deleted. | ||
| 161 | hppDout(warning, | ||
| 162 | "Trying to delete an non existant servant. Object not active: " | ||
| 163 | << id); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | ✗ | virtual void deleteAllServants() override { | |
| 168 | try { | ||
| 169 | ✗ | server_->clearServantsMap(); | |
| 170 | ✗ | } catch (const std::exception& e) { | |
| 171 | ✗ | throw hpp::Error(e.what()); | |
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | 1 | virtual Names_t* getAllServants() override { | |
| 176 | try { | ||
| 177 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | std::vector<std::string> names{server_->getAllObjectIds()}; |
| 178 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return toNames_t(names); |
| 179 |
0/2✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | } catch (const std::exception& e) { |
| 180 | ✗ | throw hpp::Error(e.what()); | |
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | 8 | virtual void shutdown() { server_->requestShutdown(false); } | |
| 185 | |||
| 186 | private: | ||
| 187 | Server* server_; | ||
| 188 | }; | ||
| 189 | |||
| 190 | ✗ | Server::Server(core::ProblemSolverPtr_t problemSolver, int argc, | |
| 191 | ✗ | const char* argv[], bool inMultiThread) | |
| 192 | ✗ | : multiThread_(inMultiThread), | |
| 193 | ✗ | nameService_(false), | |
| 194 | ✗ | problemSolverMap_(new ProblemSolverMap(problemSolver)) { | |
| 195 | ✗ | parseArguments(argc, argv); | |
| 196 | ✗ | initialize(); | |
| 197 | } | ||
| 198 | |||
| 199 | 8 | Server::Server(core::ProblemSolverPtr_t problemSolver, bool inMultiThread) | |
| 200 | 8 | : multiThread_(inMultiThread), | |
| 201 | 8 | nameService_(false), | |
| 202 |
4/8✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 14 not taken.
|
8 | problemSolverMap_(new ProblemSolverMap(problemSolver)) {} |
| 203 | |||
| 204 | 8 | void Server::initialize() { | |
| 205 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (!nameService_) tools_->initOmniINSPOA("hpp-corbaserver"); |
| 206 | 8 | tools_->initRootPOA(multiThread_); | |
| 207 | 8 | tools_->implementation().setServer(this); | |
| 208 | 8 | } | |
| 209 | |||
| 210 | 8 | Server::~Server() {} | |
| 211 | |||
| 212 | 8 | bool Server::parseArguments(int argc, const char* argv[]) { | |
| 213 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | mainContextId_ = "corbaserver"; |
| 214 | |||
| 215 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | std::string host = "localhost"; |
| 216 | 8 | int port = 13331; | |
| 217 | 8 | bool endPointSet = false; | |
| 218 | // Read environment variables | ||
| 219 | 8 | char* env = getenv("HPP_HOST"); | |
| 220 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (env != NULL) { |
| 221 | ✗ | host = env; | |
| 222 | ✗ | endPointSet = true; | |
| 223 | } | ||
| 224 | 8 | env = getenv("HPP_PORT"); | |
| 225 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
|
8 | if (env != NULL) { |
| 226 | 1 | port = atoi(env); | |
| 227 | 1 | endPointSet = true; | |
| 228 | } | ||
| 229 | |||
| 230 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | ORBendPoint = endPoint(host, port); |
| 231 | |||
| 232 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | for (int i = 1; i < argc; ++i) { |
| 233 | ✗ | if (strcmp(argv[i], "--name") == 0) { | |
| 234 | ✗ | if (i < argc - 1) { | |
| 235 | ✗ | mainContextId_ = argv[i + 1]; | |
| 236 | ✗ | ++i; | |
| 237 | } else | ||
| 238 | ✗ | usage(argv[0]); | |
| 239 | ✗ | std::cout << "Server main context: " << mainContextId_ << std::endl; | |
| 240 | ✗ | } else if (strcmp(argv[i], "--help") == 0) { | |
| 241 | ✗ | usage(argv[0]); | |
| 242 | ✗ | return false; | |
| 243 | ✗ | } else if (strcmp(argv[i], "--single-thread") == 0) { | |
| 244 | ✗ | multiThread_ = false; | |
| 245 | ✗ | std::cout << "Switched to single thread mode." << std::endl; | |
| 246 | ✗ | } else if (strcmp(argv[i], "--multi-thread") == 0) { | |
| 247 | ✗ | std::cout << "Switched to multi-thread mode." << std::endl; | |
| 248 | ✗ | multiThread_ = true; | |
| 249 | ✗ | } else if (strcmp(argv[i], "--use-name-service") == 0) { | |
| 250 | ✗ | std::cout << "Using name service." << std::endl; | |
| 251 | ✗ | nameService_ = true; | |
| 252 | ✗ | } else if (strcmp(argv[i], "--host") == 0) { | |
| 253 | ✗ | host = argv[++i]; | |
| 254 | ✗ | ORBendPoint = endPoint(host, port); | |
| 255 | ✗ | endPointSet = true; | |
| 256 | ✗ | } else if (strcmp(argv[i], "--port") == 0) { | |
| 257 | ✗ | port = atoi(argv[++i]); | |
| 258 | ✗ | ORBendPoint = endPoint(host, port); | |
| 259 | ✗ | endPointSet = true; | |
| 260 | ✗ | } else if (strcmp(argv[i], "-ORBendPoint") == 0) { | |
| 261 | ✗ | ORBendPoint = argv[++i]; | |
| 262 | ✗ | endPointSet = true; | |
| 263 | ✗ | } else if (strcmp(argv[i], "--verbosity") == 0) { | |
| 264 | ✗ | int verbosityLevel = atoi(argv[++i]); | |
| 265 | ✗ | ::hpp::debug::setVerbosityLevel(verbosityLevel); | |
| 266 | ✗ | } else if (strcmp(argv[i], "--benchmark") == 0) { | |
| 267 | ✗ | ::hpp::debug::enableBenchmark(true); | |
| 268 | } | ||
| 269 | } | ||
| 270 |
5/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
✓ 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.
|
8 | if (endPointSet) std::cout << "End point: " << ORBendPoint << std::endl; |
| 271 | |||
| 272 | 8 | const char* options[][2] = {{"endPoint", ORBendPoint.c_str()}, {0, 0}}; | |
| 273 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | tools_ = new corba::Server<Tools>(argc, argv, "", options); |
| 274 | |||
| 275 | 8 | return true; | |
| 276 | 8 | } | |
| 277 | |||
| 278 | 8 | void Server::startCorbaServer() { | |
| 279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (nameService_) |
| 280 | ✗ | tools_->startCorbaServer("hpp", "tools"); | |
| 281 | else | ||
| 282 | 8 | tools_->startCorbaServer(); | |
| 283 | |||
| 284 | // Creation of main context | ||
| 285 | 8 | createContext(mainContextId()); | |
| 286 | 8 | } | |
| 287 | |||
| 288 | 8 | bool Server::createContext(const std::string& name) { | |
| 289 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
|
8 | if (contexts_.find(name) != contexts_.end()) return false; |
| 290 | |||
| 291 | 8 | getContext(name); | |
| 292 | 8 | return true; | |
| 293 | } | ||
| 294 | |||
| 295 | ✗ | std::vector<std::string> Server::getContexts() const { | |
| 296 | ✗ | std::vector<std::string> contexts; | |
| 297 | ✗ | contexts.reserve(contexts_.size()); | |
| 298 | ✗ | for (auto const& pair : contexts_) contexts.push_back(pair.first); | |
| 299 | ✗ | return contexts; | |
| 300 | } | ||
| 301 | |||
| 302 | ✗ | bool Server::deleteContext(const std::string& name) { | |
| 303 | ✗ | return static_cast<bool>(contexts_.erase(name)); | |
| 304 | } | ||
| 305 | |||
| 306 | ✗ | core::ProblemSolverPtr_t Server::problemSolver() { | |
| 307 | ✗ | return problemSolverMap_->selected(); | |
| 308 | } | ||
| 309 | |||
| 310 | ✗ | ProblemSolverMapPtr_t Server::problemSolverMap() { return problemSolverMap_; } | |
| 311 | |||
| 312 | 8 | Server::Context& Server::getContext(const std::string& name) { | |
| 313 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
|
8 | if (contexts_.find(name) != contexts_.end()) { |
| 314 | ✗ | return contexts_[name]; | |
| 315 | } | ||
| 316 | |||
| 317 | 8 | Context context; | |
| 318 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
8 | context.main = ServerPluginPtr_t(new BasicServer(this)); |
| 319 |
3/6✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
|
8 | ProblemSolverMapPtr_t psm(new ProblemSolverMap(*problemSolverMap_)); |
| 320 | 8 | context.main->setProblemSolverMap(psm); | |
| 321 |
2/4✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
8 | context.main->startCorbaServer("hpp", name); |
| 322 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
8 | context.plugins[""] = context.main; |
| 323 | |||
| 324 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | return contexts_.insert(std::make_pair(name, context)).first->second; |
| 325 | 8 | } | |
| 326 | |||
| 327 | 27 | CORBA::Object_ptr Server::getServer(const std::string& contextName, | |
| 328 | const std::string& pluginName, | ||
| 329 | const std::string& objectName) { | ||
| 330 |
2/4✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 27 times.
|
27 | if (contexts_.find(contextName) == contexts_.end()) |
| 331 | ✗ | throw std::invalid_argument("No context " + contextName); | |
| 332 | |||
| 333 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | const Context& context = contexts_[contextName]; |
| 334 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | ServerPluginMap_t::const_iterator _plugin = context.plugins.find(pluginName); |
| 335 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
|
27 | if (_plugin == context.plugins.end()) |
| 336 | ✗ | throw std::invalid_argument("No plugin " + pluginName); | |
| 337 | |||
| 338 |
1/2✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
|
54 | return _plugin->second->servant(objectName); |
| 339 | } | ||
| 340 | |||
| 341 | ✗ | bool Server::loadPlugin(const std::string& contextName, | |
| 342 | const std::string& libFilename) { | ||
| 343 | // Load the plugin | ||
| 344 | ✗ | std::string lib = core::plugin::findPluginLibrary(libFilename); | |
| 345 | |||
| 346 | typedef ::hpp::corbaServer::ServerPlugin* (*PluginFunction_t)(Server*); | ||
| 347 | |||
| 348 | // Clear old errors | ||
| 349 | ✗ | const char* error = dlerror(); | |
| 350 | // void* library = dlopen(lib.c_str(), RTLD_NOW|RTLD_GLOBAL); | ||
| 351 | ✗ | void* library = dlopen(lib.c_str(), RTLD_NOW); | |
| 352 | ✗ | error = dlerror(); | |
| 353 | ✗ | if (error != NULL) { | |
| 354 | ✗ | HPP_THROW(std::runtime_error, | |
| 355 | "Error loading library " << lib << ": " << error); | ||
| 356 | } | ||
| 357 | ✗ | if (library == NULL) { | |
| 358 | // uncaught error ? | ||
| 359 | ✗ | HPP_THROW(std::runtime_error, | |
| 360 | "Unknown error while loading library " << lib << "."); | ||
| 361 | } | ||
| 362 | |||
| 363 | PluginFunction_t function = | ||
| 364 | ✗ | reinterpret_cast<PluginFunction_t>(dlsym(library, "createServerPlugin")); | |
| 365 | ✗ | error = dlerror(); | |
| 366 | ✗ | if (error != NULL) { | |
| 367 | ✗ | HPP_THROW(std::runtime_error, | |
| 368 | "Error loading library " << lib << ": " << error); | ||
| 369 | } | ||
| 370 | ✗ | if (function == NULL) { | |
| 371 | ✗ | HPP_THROW(std::runtime_error, | |
| 372 | "Symbol createServerPlugin of (correctly loaded) library " | ||
| 373 | << lib << " is NULL."); | ||
| 374 | } | ||
| 375 | |||
| 376 | // Get the context. | ||
| 377 | ✗ | Context& context = getContext(contextName); | |
| 378 | |||
| 379 | ✗ | ServerPluginPtr_t plugin(function(this)); | |
| 380 | ✗ | if (!plugin) return false; | |
| 381 | ✗ | const std::string name = plugin->name(); | |
| 382 | ✗ | if (context.plugins.find(name) != context.plugins.end()) { | |
| 383 | hppDout(info, "Plugin " << lib << " already loaded."); | ||
| 384 | ✗ | return false; | |
| 385 | } | ||
| 386 | ✗ | context.plugins[name] = plugin; | |
| 387 | ✗ | plugin->setProblemSolverMap(context.main->problemSolverMap()); | |
| 388 | ✗ | plugin->startCorbaServer("hpp", contextName); | |
| 389 | |||
| 390 | // I don't think we should do that because the symbols should not be | ||
| 391 | // removed... dlclose (library); | ||
| 392 | |||
| 393 | ✗ | return true; | |
| 394 | } | ||
| 395 | |||
| 396 | /// \brief If CORBA requests are pending, process them | ||
| 397 | 8 | int Server::processRequest(bool loop) { return tools_->processRequest(loop); } | |
| 398 | |||
| 399 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | void Server::requestShutdown(bool wait) { orb()->shutdown(wait); } |
| 400 | |||
| 401 | 11 | PortableServer::Servant Server::getServant(ServantKey servantKey) const { | |
| 402 | 11 | PortableServer::Servant servant = NULL; | |
| 403 | |||
| 404 | 11 | ReadWriteLock* lock = const_cast<ReadWriteLock*>(&this->lock_); | |
| 405 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | lock->readLock(); |
| 406 | |||
| 407 | ServantKeyToServantMap_t::const_iterator _servant = | ||
| 408 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | servantKeyToServantMap_.find(servantKey); |
| 409 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 9 times.
|
11 | if (_servant != servantKeyToServantMap_.end()) servant = _servant->second; |
| 410 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | lock->readUnlock(); |
| 411 | 11 | return servant; | |
| 412 | } | ||
| 413 | |||
| 414 | 9 | void Server::addServantKeyAndServant(ServantKey servantKey, | |
| 415 | PortableServer::Servant servant) { | ||
| 416 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | lock_.writeLock(); |
| 417 | typedef std::pair<ServantToServantKeyMap_t::iterator, bool> Ret_t; | ||
| 418 | Ret_t ret = | ||
| 419 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | servantToServantKeyMap_.insert(std::make_pair(servant, servantKey)); |
| 420 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (!ret.second) // Object not added because it already exists |
| 421 | { | ||
| 422 | ✗ | std::cerr << "An servant object was lost." << std::endl; | |
| 423 | ✗ | ret.first->second = servantKey; | |
| 424 | } | ||
| 425 | |||
| 426 | typedef std::pair<ServantKeyToServantMap_t::iterator, bool> Ret2_t; | ||
| 427 | Ret2_t ret2 = | ||
| 428 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | servantKeyToServantMap_.insert(std::make_pair(servantKey, servant)); |
| 429 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (!ret2.second) ret2.first->second = servant; |
| 430 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | lock_.writeUnlock(); |
| 431 | 9 | } | |
| 432 | |||
| 433 | ✗ | void Server::removeServant(PortableServer::Servant servant) { | |
| 434 | ✗ | lock_.writeLock(); | |
| 435 | ServantToServantKeyMap_t::iterator _it = | ||
| 436 | ✗ | servantToServantKeyMap_.find(servant); | |
| 437 | ✗ | if (_it != servantToServantKeyMap_.end()) { | |
| 438 | ✗ | servantKeyToServantMap_.erase(_it->second); | |
| 439 | ✗ | servantToServantKeyMap_.erase(_it); | |
| 440 | } | ||
| 441 | ✗ | lock_.writeUnlock(); | |
| 442 | } | ||
| 443 | |||
| 444 | ✗ | void Server::clearServantsMap() { | |
| 445 | ✗ | PortableServer::POA_var _poa(poa()); | |
| 446 | ✗ | lock_.writeLock(); | |
| 447 | ✗ | for (const auto& pair : servantKeyToServantMap_) { | |
| 448 | ✗ | PortableServer::ObjectId_var objectId = _poa->servant_to_id(pair.second); | |
| 449 | ✗ | _poa->deactivate_object(objectId.in()); | |
| 450 | } | ||
| 451 | ✗ | servantKeyToServantMap_.clear(); | |
| 452 | ✗ | servantToServantKeyMap_.clear(); | |
| 453 | ✗ | lock_.writeUnlock(); | |
| 454 | } | ||
| 455 | |||
| 456 | 1 | std::vector<std::string> Server::getAllObjectIds() { | |
| 457 | 1 | std::vector<std::string> objectIds; | |
| 458 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | PortableServer::POA_var _poa(poa()); |
| 459 | |||
| 460 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | lock_.readLock(); |
| 461 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | objectIds.reserve(servantKeyToServantMap_.size()); |
| 462 |
2/2✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
|
2 | for (const auto& pair : servantKeyToServantMap_) { |
| 463 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | PortableServer::ObjectId_var objectId = _poa->servant_to_id(pair.second); |
| 464 | 1 | objectIds.emplace_back( | |
| 465 |
4/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
1 | orb()->object_to_string(_poa->id_to_reference(objectId))); |
| 466 | 1 | } | |
| 467 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | lock_.readUnlock(); |
| 468 | 2 | return objectIds; | |
| 469 | 1 | } | |
| 470 | |||
| 471 | } // end of namespace corbaServer. | ||
| 472 | } // end of namespace hpp. | ||
| 473 |