diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/DynamicLibrary.cpp | 58 | ||||
-rw-r--r-- | cpp/src/Ice/PluginManagerI.cpp | 119 | ||||
-rw-r--r-- | cpp/src/Ice/PluginManagerI.h | 14 | ||||
-rw-r--r-- | cpp/src/IceBox/ServiceManagerI.cpp | 99 |
4 files changed, 173 insertions, 117 deletions
diff --git a/cpp/src/Ice/DynamicLibrary.cpp b/cpp/src/Ice/DynamicLibrary.cpp index 5b690df5f2b..ab724a9847a 100644 --- a/cpp/src/Ice/DynamicLibrary.cpp +++ b/cpp/src/Ice/DynamicLibrary.cpp @@ -50,7 +50,28 @@ IceInternal::DynamicLibrary::~DynamicLibrary() IceInternal::DynamicLibrary::symbol_type IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIceVersion) { + +#ifdef _WIN32 + bool isFilePath = entryPoint.find('\\') != string::npos || entryPoint.find('/') != string::npos; +#else + bool isFilePath = entryPoint.find('/') != string::npos; +#endif + string::size_type colon = entryPoint.rfind(':'); + +#ifdef _WIN32 + const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if(colon == 1 && driveLetters.find(entryPoint[0]) != string::npos && + (entryPoint[2] == '\\' || entryPoint[2] == '/')) + { + // + // The only colon we found is in the drive specification, as in "C:\MyDir". + // This means the function name is missing. + // + colon = string::npos; + } +#endif + string::size_type comma = entryPoint.find(','); if(colon == string::npos || colon == entryPoint.size() - 1 || (comma != string::npos && (comma > colon || comma == colon - 1))) @@ -58,9 +79,22 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc _err = "invalid entry point format `" + entryPoint + "'"; return 0; } + string libSpec = entryPoint.substr(0, colon); string funcName = entryPoint.substr(colon + 1); - string libName, version, debug; + string libPath, libName, version, debug; + + if(isFilePath) + { +#ifdef _WIN32 + string::size_type separator = entryPoint.find_last_of("/\\"); +#else + string::size_type separator = entryPoint.rfind('/'); +#endif + libPath = libSpec.substr(0, separator + 1); + libSpec = libSpec.substr(separator + 1); + } + if(comma == string::npos) { libName = libSpec; @@ -70,7 +104,7 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc int minorVersion = (ICE_INT_VERSION / 100) - majorVersion * 100; ostringstream os; os << majorVersion * 10 + minorVersion; - + int patchVersion = ICE_INT_VERSION % 100; if(patchVersion > 50) { @@ -89,10 +123,10 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc version = libSpec.substr(comma + 1); } - string lib; + string lib = libPath; #ifdef _WIN32 - lib = libName; + lib += libName; # ifdef COMPSUFFIX // @@ -114,13 +148,13 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc lib += ".dll"; #elif defined(__APPLE__) - lib = "lib" + libName; - if(!version.empty()) + lib += "lib" + libName; + if(!version.empty()) { lib += "." + version; } #elif defined(__hpux) - lib = "lib" + libName; + lib += "lib" + libName; if(!version.empty()) { lib += "." + version; @@ -130,14 +164,14 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc lib += ".sl"; } #elif defined(_AIX) - lib = "lib" + libName + ".a(lib" + libName + ".so"; + lib += "lib" + libName + ".a(lib" + libName + ".so"; if(!version.empty()) { lib += "." + version; } lib += ")"; #else - lib = "lib" + libName + ".so"; + lib += "lib" + libName + ".so"; if(!version.empty()) { lib += "." + version; @@ -217,16 +251,16 @@ IceInternal::DynamicLibrary::getSymbol(const string& name) #else symbol_type result = dlsym(_hnd, name.c_str()); #endif - + if(result == 0) { // // Remember the most recent error in _err. // #ifdef _WIN32 - _err = IceUtilInternal::lastErrorToString(); + _err = IceUtilInternal::lastErrorToString(); #else - const char* err = dlerror(); + const char* err = dlerror(); if(err) { _err = err; diff --git a/cpp/src/Ice/PluginManagerI.cpp b/cpp/src/Ice/PluginManagerI.cpp index 513a3036ea6..bb2bcd37959 100644 --- a/cpp/src/Ice/PluginManagerI.cpp +++ b/cpp/src/Ice/PluginManagerI.cpp @@ -7,6 +7,7 @@ // // ********************************************************************** +#include <IceUtil/Options.h> #include <Ice/PluginManagerI.h> #include <Ice/DynamicLibrary.h> #include <Ice/Communicator.h> @@ -40,10 +41,10 @@ Ice::PluginManagerI::initializePlugins() vector<PluginPtr> initializedPlugins; try { - for(vector<PluginPtr>::iterator p = _initOrder.begin(); p != _initOrder.end(); ++p) + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) { - (*p)->initialize(); - initializedPlugins.push_back(*p); + p->plugin->initialize(); + initializedPlugins.push_back(p->plugin); } } catch(...) @@ -75,10 +76,9 @@ Ice::PluginManagerI::getPlugins() IceUtil::Mutex::Lock sync(*this); StringSeq names; - map<string, PluginPtr>::iterator r; - for(r = _plugins.begin(); r != _plugins.end(); ++r) + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) { - names.push_back((*r).first); + names.push_back(p->name); } return names; } @@ -93,10 +93,10 @@ Ice::PluginManagerI::getPlugin(const string& name) throw CommunicatorDestroyedException(__FILE__, __LINE__); } - map<string, PluginPtr>::const_iterator r = _plugins.find(name); - if(r != _plugins.end()) + PluginPtr p = findPlugin(name); + if(p) { - return (*r).second; + return p; } NotRegisteredException ex(__FILE__, __LINE__); @@ -115,15 +115,18 @@ Ice::PluginManagerI::addPlugin(const string& name, const PluginPtr& plugin) throw CommunicatorDestroyedException(__FILE__, __LINE__); } - map<string, PluginPtr>::const_iterator r = _plugins.find(name); - if(r != _plugins.end()) + if(findPlugin(name)) { AlreadyRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = _kindOfObject; ex.id = name; throw ex; } - _plugins[name] = plugin; + + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); } void @@ -135,40 +138,44 @@ Ice::PluginManagerI::destroy() { if(_initialized) { - map<string, PluginPtr>::iterator r; - for(r = _plugins.begin(); r != _plugins.end(); ++r) + + // + // Destroy the plug-ins that have been successfully initialized, in the + // reverse order. + // + for(PluginInfoList::reverse_iterator p = _plugins.rbegin(); p != _plugins.rend(); ++p) { try { - r->second->destroy(); - r->second = 0; + p->plugin->destroy(); } catch(const std::exception& ex) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << ex.what(); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << ex.what(); } catch(const std::string& str) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << str; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << str; } catch(const char* msg) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << msg; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << msg; } catch(...) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction"; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction"; } } } - + _communicator = 0; } + _plugins.clear(); _libraries = 0; } @@ -206,7 +213,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) { string name = *p; - if(_plugins.find(name) != _plugins.end()) + if(findPlugin(name)) { PluginInitializationException ex(__FILE__, __LINE__); ex.reason = "plug-in `" + name + "' already loaded"; @@ -239,7 +246,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) // // Load any remaining plug-ins that weren't specified in PluginLoadOrder. // - + while(!plugins.empty()) { PropertyDict::iterator p = plugins.begin(); @@ -262,7 +269,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) name = name.substr(0, dotPos); loadPlugin(name, p->second, cmdArgs); plugins.erase(p); - + plugins.erase("Ice.Plugin." + name); } else @@ -273,7 +280,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) dotPos = string::npos; } } - + if(dotPos == string::npos) { // @@ -299,36 +306,29 @@ Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, St { assert(_communicator); // - // Separate the entry point from the arguments. + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. // - string entryPoint; StringSeq args; - const string delim = " \t\n"; - string::size_type pos = pluginSpec.find_first_of(delim); - if(pos == string::npos) + try { - entryPoint = pluginSpec; + args = IceUtilInternal::Options::split(pluginSpec); } - else + catch(const IceUtilInternal::BadOptException& ex) { - entryPoint = pluginSpec.substr(0, pos); - string::size_type beg = pluginSpec.find_first_not_of(delim, pos); - while(beg != string::npos) - { - string::size_type end = pluginSpec.find_first_of(delim, beg); - if(end == string::npos) - { - args.push_back(pluginSpec.substr(beg)); - beg = end; - } - else - { - args.push_back(pluginSpec.substr(beg, end - beg)); - beg = pluginSpec.find_first_not_of(delim, end); - } - } + PluginInitializationException e(__FILE__, __LINE__); + e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.reason; + throw e; } + assert(!args.empty()); + + // + // Shift the arguments. + // + const string entryPoint = args[0]; + args.erase(args.begin()); + // // Convert command-line options into properties. First we // convert the options from the plug-in configuration, then @@ -373,15 +373,30 @@ Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, St throw e; } - _plugins[name] = plugin; - _initOrder.push_back(plugin); + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); _libraries->add(library); } +Ice::PluginPtr +Ice::PluginManagerI::findPlugin(const string& name) const +{ + for(PluginInfoList::const_iterator p = _plugins.begin(); p != _plugins.end(); ++p) + { + if(name == p->name) + { + return p->plugin; + } + } + return 0; +} + void -IceInternal::loadPlugin(const Ice::CommunicatorPtr& communicator, - const string& name, +IceInternal::loadPlugin(const Ice::CommunicatorPtr& communicator, + const string& name, const string& pluginSpec, Ice::StringSeq& cmdArgs) { diff --git a/cpp/src/Ice/PluginManagerI.h b/cpp/src/Ice/PluginManagerI.h index ecb73fa3a43..a7b7578ebaa 100644 --- a/cpp/src/Ice/PluginManagerI.h +++ b/cpp/src/Ice/PluginManagerI.h @@ -41,17 +41,25 @@ private: PluginManagerI(const CommunicatorPtr&, const IceInternal::DynamicLibraryListPtr&); friend class IceInternal::Instance; - friend void IceInternal::loadPlugin(const Ice::CommunicatorPtr&, const std::string&, const std::string&, + friend void IceInternal::loadPlugin(const Ice::CommunicatorPtr&, const std::string&, const std::string&, Ice::StringSeq&); void loadPlugins(int&, char*[]); void loadPlugin(const std::string&, const std::string&, StringSeq&); + PluginPtr findPlugin(const std::string&) const; + CommunicatorPtr _communicator; IceInternal::DynamicLibraryListPtr _libraries; - std::map<std::string, PluginPtr> _plugins; - std::vector<PluginPtr> _initOrder; + struct PluginInfo + { + std::string name; + PluginPtr plugin; + }; + typedef std::vector<PluginInfo> PluginInfoList; + + PluginInfoList _plugins; bool _initialized; static const char * const _kindOfObject; }; diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp index 60f0959dcb5..f91e9cd8da2 100644 --- a/cpp/src/IceBox/ServiceManagerI.cpp +++ b/cpp/src/IceBox/ServiceManagerI.cpp @@ -22,18 +22,18 @@ using namespace std; typedef IceBox::Service* (*SERVICE_FACTORY)(CommunicatorPtr); -namespace +namespace { class PropertiesAdminI : public PropertiesAdmin { public: - + PropertiesAdminI(const PropertiesPtr& properties) : _properties(properties) { } - + virtual string getProperty(const string& name, const Current&) { return _properties->getProperty(name); @@ -43,10 +43,10 @@ public: { return _properties->getPropertiesForPrefix(prefix); } - + private: - const PropertiesPtr _properties; + const PropertiesPtr _properties; }; struct StartServiceInfo @@ -56,28 +56,28 @@ struct StartServiceInfo name = service; // - // Separate the entry point from the arguments. + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. // - string::size_type pos = value.find_first_of(" \t\n"); - if(pos == string::npos) + try { - entryPoint = value; + args = IceUtilInternal::Options::split(value); } - else + catch(const IceUtilInternal::BadOptException& ex) { - entryPoint = value.substr(0, pos); - try - { - args = IceUtilInternal::Options::split(value.substr(pos + 1)); - } - catch(const IceUtilInternal::BadOptException& ex) - { - FailureException e(__FILE__, __LINE__); - e.reason = "ServiceManager: invalid arguments for service `" + name + "':\n" + ex.reason; - throw e; - } + PluginInitializationException e(__FILE__, __LINE__); + e.reason = "invalid arguments for service `" + name + "':\n" + ex.reason; + throw e; } + assert(!args.empty()); + + // + // Shift the arguments. + // + entryPoint = args[0]; + args.erase(args.begin()); + for(Ice::StringSeq::const_iterator p = serverArgs.begin(); p != serverArgs.end(); ++p) { if(p->find("--" + name + ".") == 0) @@ -92,10 +92,9 @@ struct StartServiceInfo Ice::StringSeq args; }; - } -IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator, int& argc, char* argv[]) : +IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator, int& argc, char* argv[]) : _communicator(communicator), _pendingStatusChanges(false), _traceServiceObserver(0), @@ -169,7 +168,7 @@ IceBox::ServiceManagerI::startService(const string& name, const Current&) Warning out(_logger); out << "ServiceManager: unknown exception in start for service " << info.name; } - + { IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); @@ -290,7 +289,7 @@ IceBox::ServiceManagerI::addObserver(const ServiceObserverPrx& observer, const I { Trace out(_logger, "IceBox.ServiceObserver"); out << "Added service observer " << _communicator->proxyToString(observer); - } + } vector<string> activeServices; for(vector<ServiceInfo>::iterator p = _services.begin(); p != _services.end(); ++p) @@ -301,7 +300,7 @@ IceBox::ServiceManagerI::addObserver(const ServiceObserverPrx& observer, const I activeServices.push_back(info.name); } } - + if(activeServices.size() > 0) { observer->begin_servicesStarted(activeServices, _observerCompletedCB); @@ -345,7 +344,7 @@ IceBox::ServiceManagerI::start() // // IceBox.Service.Foo=entry_point [args] // - // We parse the service properties specified in IceBox.LoadOrder + // We parse the service properties specified in IceBox.LoadOrder // first, then the ones from remaining services. // const string prefix = "IceBox.Service."; @@ -369,7 +368,7 @@ IceBox::ServiceManagerI::start() { servicesInfo.push_back(StartServiceInfo(p->first.substr(prefix.size()), p->second, _argv)); } - + // // Check if some services are using the shared communicator in which // case we create the shared communicator now with a property set which @@ -416,12 +415,12 @@ IceBox::ServiceManagerI::start() { initData.properties->setProperty(r->first, r->second); } - + // - // Parse <service>.* command line options (the Ice command line options + // Parse <service>.* command line options (the Ice command line options // were parsed by the createProperties above) // - q->args = initData.properties->parseCommandLineOptions(q->name, q->args); + q->args = initData.properties->parseCommandLineOptions(q->name, q->args); } _sharedCommunicator = initialize(initData); } @@ -462,7 +461,7 @@ IceBox::ServiceManagerI::start() // // Add a Properties facet for each service - // + // for(vector<ServiceInfo>::iterator r = _services.begin(); r != _services.end(); ++r) { const ServiceInfo& info = *r; @@ -470,7 +469,7 @@ IceBox::ServiceManagerI::start() _communicator->addAdminFacet(new PropertiesAdminI(communicator->getProperties()), "IceBox.Service." + info.name + ".Properties"); } - + _communicator->getAdmin(); } catch(const ObjectAdapterDeactivatedException&) @@ -611,7 +610,7 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, communicator = _sharedCommunicator; } else - { + { // // Create the service properties. We use the communicator properties as the default // properties if IceBox.InheritProperties is set. @@ -627,25 +626,25 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, initData.properties = createProperties(info.args, initData.properties); // - // Next, parse the service "<service>.*" command line options (the Ice command + // Next, parse the service "<service>.*" command line options (the Ice command // line options were parsed by the createProperties above) // info.args = initData.properties->parseCommandLineOptions(service, info.args); } - + // // Clone the logger to assign a new prefix. // initData.logger = _logger->cloneWithPrefix(initData.properties->getProperty("Ice.ProgramName")); - + // - // Remaining command line options are passed to the communicator. This is + // Remaining command line options are passed to the communicator. This is // necessary for Ice plug-in properties (e.g.: IceSSL). // info.communicator = initialize(info.args, initData); communicator = info.communicator; } - + // // Start the service. // @@ -656,8 +655,8 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, // // There is no need to notify the observers since the 'start all' - // (that indirectly calls this function) occurs before the creation of - // the Server Admin object, and before the activation of the main + // (that indirectly calls this function) occurs before the creation of + // the Server Admin object, and before the activation of the main // object adapter (so before any observer can be registered) // } @@ -750,7 +749,7 @@ IceBox::ServiceManagerI::stopAll() vector<string> stoppedServices; // - // First, for each service, we call stop on the service and flush its database environment to + // First, for each service, we call stop on the service and flush its database environment to // the disk. // for(p = _services.rbegin(); p != _services.rend(); ++p) @@ -782,7 +781,7 @@ IceBox::ServiceManagerI::stopAll() for(p = _services.rbegin(); p != _services.rend(); ++p) { ServiceInfo& info = *p; - + try { _communicator->removeAdminFacet("IceBox.Service." + info.name + ".Properties"); @@ -815,9 +814,9 @@ IceBox::ServiceManagerI::stopAll() } // - // Release the service, the service communicator and then the library. The order is important, + // Release the service, the service communicator and then the library. The order is important, // the service must be released before destroying the communicator so that the communicator - // leak detector doesn't report potential leaks, and the communicator must be destroyed before + // leak detector doesn't report potential leaks, and the communicator must be destroyed before // the library is released since the library will destroy its global state. // try @@ -850,7 +849,7 @@ IceBox::ServiceManagerI::stopAll() out << ex; } } - + try { info.library = 0; @@ -915,7 +914,7 @@ IceBox::ServiceManagerI::servicesStopped(const vector<string>& services, const s void IceBox::ServiceManagerI::observerRemoved(const ServiceObserverPrx& observer, const std::exception& ex) -{ +{ if(_traceServiceObserver >= 1) { // @@ -929,8 +928,8 @@ IceBox::ServiceManagerI::observerRemoved(const ServiceObserverPrx& observer, con out << "Removed service observer " << _communicator->proxyToString(observer) << "\nafter catching " << ex.what(); } - } -} + } +} Ice::PropertiesPtr IceBox::ServiceManagerI::createServiceProperties(const string& service) @@ -946,7 +945,7 @@ IceBox::ServiceManagerI::createServiceProperties(const string& service) { properties = createProperties(); } - + string programName = communicatorProperties->getProperty("Ice.ProgramName"); if(programName.empty()) { |