summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2012-08-16 15:58:01 +0200
committerJose <jose@zeroc.com>2012-08-16 15:58:01 +0200
commit0b82edbd44b61ab36592f73728e76d1fd11a3aa2 (patch)
tree8f8a0b6d5cb22a95dfc4b2c257d0eb7c0fe62c9b /cpp
parentICE-4820 - Service class public API (diff)
downloadice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.tar.bz2
ice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.tar.xz
ice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.zip
ICE-4609 - Add ability to load shared library with full path
- C++/Java now also support to load Services and Plugins from a full path, this was already supported by .NET - Fixed the parsing of plug-in arguments to correct split the arguments - Fixed Plugin manager destroy C++/Java/C#, the plugin must are now destroyed in initialization reverse order as documented.
Diffstat (limited to 'cpp')
-rwxr-xr-xcpp/allTests.py1
-rw-r--r--cpp/src/Ice/DynamicLibrary.cpp58
-rw-r--r--cpp/src/Ice/PluginManagerI.cpp119
-rw-r--r--cpp/src/Ice/PluginManagerI.h14
-rw-r--r--cpp/src/IceBox/ServiceManagerI.cpp99
-rw-r--r--cpp/test/Ice/Makefile3
-rw-r--r--cpp/test/Ice/Makefile.mak1
-rw-r--r--cpp/test/Ice/plugin/.depend1
-rw-r--r--cpp/test/Ice/plugin/.depend.mak1
-rw-r--r--cpp/test/Ice/plugin/.gitignore7
-rw-r--r--cpp/test/Ice/plugin/Client.cpp187
-rw-r--r--cpp/test/Ice/plugin/Makefile51
-rw-r--r--cpp/test/Ice/plugin/Makefile.mak68
-rw-r--r--cpp/test/Ice/plugin/Plugin.cpp404
-rw-r--r--cpp/test/Ice/plugin/plugins/.gitignore0
-rwxr-xr-xcpp/test/Ice/plugin/run.py25
-rw-r--r--cpp/test/WinRT/TestSuite/MainPage.xaml.cpp3
17 files changed, 923 insertions, 119 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py
index f124bf519bd..d3107df594f 100755
--- a/cpp/allTests.py
+++ b/cpp/allTests.py
@@ -66,6 +66,7 @@ tests = [
("Ice/defaultServant", ["core"]),
("Ice/defaultValue", ["core"]),
("Ice/invoke", ["core", "novc6"]),
+ ("Ice/plugin", ["core"]),
("Ice/hash", ["once"]),
("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl
("IceBox/configuration", ["core", "noipv6", "novc6", "nomingw"]),
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())
{
diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile
index 15092758312..ea2d27fe5fa 100644
--- a/cpp/test/Ice/Makefile
+++ b/cpp/test/Ice/Makefile
@@ -42,7 +42,8 @@ SUBDIRS = proxy \
defaultValue \
threadPoolPriority \
invoke \
- properties
+ properties \
+ plugin
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak
index eaa8112b30a..dfd91c1bda1 100644
--- a/cpp/test/Ice/Makefile.mak
+++ b/cpp/test/Ice/Makefile.mak
@@ -29,6 +29,7 @@ SUBDIRS = proxy \
retry \
timeout \
udp \
+ plugin \
stream
!if "$(WINRT)" != "yes"
diff --git a/cpp/test/Ice/plugin/.depend b/cpp/test/Ice/plugin/.depend
new file mode 100644
index 00000000000..1d479e875ec
--- /dev/null
+++ b/cpp/test/Ice/plugin/.depend
@@ -0,0 +1 @@
+Plugin$(OBJEXT): Plugin.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/Dispatcher.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/Stream.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/CommunicatorAsync.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/ConnectionAsync.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/FactoryTableInit.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h ../../include/TestCommon.h
diff --git a/cpp/test/Ice/plugin/.depend.mak b/cpp/test/Ice/plugin/.depend.mak
new file mode 100644
index 00000000000..e02b2718caf
--- /dev/null
+++ b/cpp/test/Ice/plugin/.depend.mak
@@ -0,0 +1 @@
+Plugin$(OBJEXT): Plugin.cpp "$(includedir)/Ice/Ice.h" "$(includedir)/Ice/Initialize.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Handle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointIF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/StatsF.h" "$(includedir)/Ice/Dispatcher.h" "$(includedir)/Ice/StringConverter.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/Ice/Stream.h" "$(includedir)/IceUtil/Unicode.h" "$(includedir)/Ice/LocalException.h" "$(includedir)/Ice/Properties.h" "$(includedir)/Ice/Outgoing.h" "$(includedir)/Ice/Incoming.h" "$(includedir)/Ice/ServantLocatorF.h" "$(includedir)/Ice/ServantManagerF.h" "$(includedir)/Ice/Direct.h" "$(includedir)/Ice/Logger.h" "$(includedir)/Ice/LoggerUtil.h" "$(includedir)/Ice/Stats.h" "$(includedir)/Ice/Communicator.h" "$(includedir)/Ice/RouterF.h" "$(includedir)/Ice/LocatorF.h" "$(includedir)/Ice/PluginF.h" "$(includedir)/Ice/ImplicitContextF.h" "$(includedir)/Ice/CommunicatorAsync.h" "$(includedir)/Ice/ObjectFactory.h" "$(includedir)/Ice/ObjectAdapter.h" "$(includedir)/Ice/FacetMap.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/ServantLocator.h" "$(includedir)/Ice/IncomingAsync.h" "$(includedir)/Ice/Process.h" "$(includedir)/Ice/Application.h" "$(includedir)/Ice/Connection.h" "$(includedir)/Ice/ConnectionAsync.h" "$(includedir)/Ice/Functional.h" "$(includedir)/IceUtil/Functional.h" "$(includedir)/Ice/ImplicitContext.h" "$(includedir)/Ice/Locator.h" "$(includedir)/Ice/FactoryTableInit.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/ProcessF.h" "$(includedir)/Ice/Router.h" "$(includedir)/Ice/DispatchInterceptor.h" "$(includedir)/Ice/IconvStringConverter.h" ../../include/TestCommon.h
diff --git a/cpp/test/Ice/plugin/.gitignore b/cpp/test/Ice/plugin/.gitignore
new file mode 100644
index 00000000000..a86ad423f93
--- /dev/null
+++ b/cpp/test/Ice/plugin/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+plugins/libTestPlugin.so.3.4.2
+plugins/libTestPlugin.so.34
+plugins/libTestPlugin.so
diff --git a/cpp/test/Ice/plugin/Client.cpp b/cpp/test/Ice/plugin/Client.cpp
new file mode 100644
index 00000000000..a54ec9e65c2
--- /dev/null
+++ b/cpp/test/Ice/plugin/Client.cpp
@@ -0,0 +1,187 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <TestCommon.h>
+
+using namespace std;
+
+DEFINE_TEST("client")
+
+namespace
+{
+
+class MyPlugin : public Ice::Plugin
+{
+
+public:
+
+ MyPlugin() :
+ _initialized(false),
+ _destroyed(false)
+ {
+ }
+
+ bool
+ isInitialized() const
+ {
+ return _initialized;
+ }
+
+ bool
+ isDestroyed() const
+ {
+ return _destroyed;
+ }
+
+ void
+ initialize()
+ {
+ _initialized = true;
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ }
+
+ ~MyPlugin()
+ {
+ test(_initialized);
+ test(_destroyed);
+ }
+
+private:
+
+ const Ice::CommunicatorPtr _communicator;
+ bool _initialized;
+ bool _destroyed;
+};
+typedef IceUtil::Handle<MyPlugin> MyPluginPtr;
+
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status = EXIT_SUCCESS;
+ Ice::CommunicatorPtr communicator;
+
+ cout << "testing a simple plug-in... " << flush;
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Plugin.Test",
+ "plugins/TestPlugin:createPlugin 'C:\\Program Files\\' --DatabasePath "
+ "'C:\\Program Files\\Application\\db'" );
+ communicator = Ice::initialize(argc, argv, initData);
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ test(false);
+ }
+ cout << "ok" << endl;
+
+ cout << "testing a simple plug-in that fails to initialize... " << flush;
+ communicator = 0;
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Plugin.Test", "plugins/TestPlugin:createPluginInitializeFail");
+ communicator = Ice::initialize(argc, argv, initData);
+ test(false);
+ }
+ catch(const std::exception& ex)
+ {
+ test(string(ex.what()) == "PluginInitializeFailExeption");
+ }
+ test(!communicator);
+ cout << "ok" << endl;
+
+ cout << "testing plug-in load order... " << flush;
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Plugin.PluginOne", "plugins/TestPlugin:createPluginOne");
+ initData.properties->setProperty("Ice.Plugin.PluginTwo", "plugins/TestPlugin:createPluginTwo");
+ initData.properties->setProperty("Ice.Plugin.PluginThree", "plugins/TestPlugin:createPluginThree");
+ initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); // Exclude PluginThree
+ communicator = Ice::initialize(argc, argv, initData);
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ test(false);
+ }
+ cout << "ok" << endl;
+
+ cout << "testing plug-in manager... " << flush;
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Plugin.PluginOne", "plugins/TestPlugin:createPluginOne");
+ initData.properties->setProperty("Ice.Plugin.PluginTwo", "plugins/TestPlugin:createPluginTwo");
+ initData.properties->setProperty("Ice.Plugin.PluginThree", "plugins/TestPlugin:createPluginThree");
+ initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo");
+ initData.properties->setProperty("Ice.InitPlugins", "0");
+ communicator = Ice::initialize(argc, argv, initData);
+
+ Ice::PluginManagerPtr pm = communicator->getPluginManager();
+ test(pm->getPlugin("PluginOne"));
+ test(pm->getPlugin("PluginTwo"));
+ test(pm->getPlugin("PluginThree"));
+
+ MyPluginPtr p4 = new MyPlugin;
+ pm->addPlugin("PluginFour", p4);
+ test(pm->getPlugin("PluginFour"));
+
+ pm->initializePlugins();
+
+ test(p4->isInitialized());
+
+ communicator->destroy();
+
+ test(p4->isDestroyed());
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ test(false);
+ }
+ cout << "ok" << endl;
+
+ cout << "testing destroy when a plug-in fails to initialize... " << flush;
+ communicator = 0;
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Plugin.PluginOneFail", "plugins/TestPlugin:createPluginOneFail");
+ initData.properties->setProperty("Ice.Plugin.PluginTwoFail", "plugins/TestPlugin:createPluginTwoFail");
+ initData.properties->setProperty("Ice.Plugin.PluginThreeFail", "plugins/TestPlugin:createPluginThreeFail");
+ initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOneFail, PluginTwoFail, PluginThreeFail");
+ communicator = Ice::initialize(argc, argv, initData);
+ }
+ catch(const std::exception& ex)
+ {
+ test(string(ex.what()) == "PluginInitializeFailExeption");
+ }
+ test(!communicator);
+ cout << "ok" << endl;
+
+ return status;
+}
diff --git a/cpp/test/Ice/plugin/Makefile b/cpp/test/Ice/plugin/Makefile
new file mode 100644
index 00000000000..446a4b7c8ac
--- /dev/null
+++ b/cpp/test/Ice/plugin/Makefile
@@ -0,0 +1,51 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+PLUGINLIBFILENAME = $(call mklibfilename,TestPlugin,$(VERSION))
+PLUGINSONAME = $(call mksoname,TestPlugin,$(SOVERSION))
+PLUGINLIBNAME = $(call mklibname,TestPlugin)
+CLIENT = client
+PLUGINDIR = plugins
+
+TARGETS = $(CLIENT) $(call mklibtargets,$(PLUGINDIR)/$(PLUGINLIBFILENAME),$(PLUGINDIR)/$(PLUGINSONAME),$(PLUGINDIR)/$(PLUGINLIBNAME))
+
+COBJS = Client.o \
+
+POBJS = Plugin.o
+
+SRCS = $(COBJS:.o=.cpp) \
+ $(SOBJS:.o=.cpp) \
+ $(POBJS:.o=.cpp)
+
+LINKWITH := -lIceUtil -lIce
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(COBJS) $(LIBS)
+
+$(PLUGINDIR)/$(PLUGINLIBFILENAME): $(POBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(PLUGINSONAME),$(POBJS),$(LINKWITH))
+
+$(PLUGINDIR)/$(PLUGINSONAME): $(PLUGINDIR)/$(PLUGINLIBFILENAME)
+ rm -f $@
+ ln -s $(PLUGINLIBFILENAME) $@
+
+$(PLUGINDIR)/$(PLUGINLIBNAME): $(PLUGINDIR)/$(PLUGINSONAME)
+ rm -f $@
+ ln -s $(PLUGINSONAME) $@
+
+
+include .depend
diff --git a/cpp/test/Ice/plugin/Makefile.mak b/cpp/test/Ice/plugin/Makefile.mak
new file mode 100644
index 00000000000..c1baf6957f2
--- /dev/null
+++ b/cpp/test/Ice/plugin/Makefile.mak
@@ -0,0 +1,68 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!if "$(WINRT)" != "yes"
+NAME_PREFIX =
+EXT = .exe
+!else
+NAME_PREFIX = Ice_plugin_
+EXT = .dll
+!endif
+
+CLIENT = $(NAME_PREFIX)client
+LIBNAME = TestPlugin$(LIBSUFFIX).lib
+DLLNAME = TestPlugin$(SOVERSION)$(LIBSUFFIX).dll
+PLUGINDIR = plugins
+
+TARGETS = $(CLIENT)$(EXT) $(PLUGINDIR)\$(LIBNAME) $(PLUGINDIR)\$(DLLNAME)
+
+COBJS = Client.obj
+
+POBJS = Plugin.obj
+
+SRCS = $(COBJS:.obj=.cpp) \
+ $(POBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT).pdb
+PPDBFLAGS = /pdb:$(DLLNAME:.dll=.pdb)
+!endif
+
+!if "$(WINRT)" != "yes"
+LD_TESTFLAGS = $(LD_EXEFLAGS) $(SETARGV)
+!else
+LD_TESTFLAGS = $(LD_DLLFLAGS) /export:dllMain
+!endif
+
+LINKWITH = $(LIBS)
+
+$(PLUGINDIR)\$(LIBNAME): $(PLUGINDIR)\$(DLLNAME)
+
+$(PLUGINDIR)\$(DLLNAME): $(POBJS)
+ $(LINK) $(BASE):0x22000000 $(LD_DLLFLAGS) $(PDBFLAGS) $(POBJS) $(PREOUT)$@ $(PRELIBS)$(LINKWITH)
+ move $(PLUGINDIR)\$(DLLNAME:.dll=.lib) $(PLUGINDIR)\$(LIBNAME)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#2 && del /q $@.manifest
+ @if exist $(PLUGINDIR)\$(DLLNAME:.dll=.exp) del /q $(PLUGINDIR)\$(DLLNAME:.dll=.exp)
+
+$(CLIENT)$(EXT): $(COBJS)
+ $(LINK) $(LD_TESTFLAGS) $(CPDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q $(PLUGINDIR)\*.ilk $(PLUGINDIR)\*.pdb
+
+!include .depend.mak
diff --git a/cpp/test/Ice/plugin/Plugin.cpp b/cpp/test/Ice/plugin/Plugin.cpp
new file mode 100644
index 00000000000..0fc9cbad24d
--- /dev/null
+++ b/cpp/test/Ice/plugin/Plugin.cpp
@@ -0,0 +1,404 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <TestCommon.h>
+
+using namespace std;
+
+namespace
+{
+
+class Plugin : public Ice::Plugin
+{
+
+public:
+
+ Plugin(const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args) :
+ _communicator(communicator),
+ _args(args),
+ _initialized(false),
+ _destroyed(false)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _initialized = true;
+ test(_args.size() == 3);
+ test(_args[0] == "C:\\Program Files\\");
+ test(_args[1] == "--DatabasePath");
+ test(_args[2] == "C:\\Program Files\\Application\\db");
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ }
+
+ ~Plugin()
+ {
+ test(_initialized);
+ test(_destroyed);
+ }
+
+private:
+
+ const Ice::CommunicatorPtr _communicator;
+ Ice::StringSeq _args;
+ bool _initialized;
+ bool _destroyed;
+};
+
+class PluginInitializeFailExeption : public std::exception
+{
+
+public:
+
+ PluginInitializeFailExeption() throw() {}
+ virtual ~PluginInitializeFailExeption() throw() {}
+ virtual const char* what() const throw() { return "PluginInitializeFailExeption"; }
+};
+
+class PluginInitializeFail : public Ice::Plugin
+{
+
+public:
+
+ PluginInitializeFail(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ throw PluginInitializeFailExeption();
+ }
+
+ void
+ destroy()
+ {
+ test(false);
+ }
+
+private:
+
+ const Ice::CommunicatorPtr _communicator;
+};
+
+class BasePlugin;
+typedef IceUtil::Handle<BasePlugin> BasePluginPtr;
+
+class BasePlugin : public Ice::Plugin
+{
+
+public:
+
+ BasePlugin(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator),
+ _initialized(false),
+ _destroyed(false)
+ {
+ }
+
+ bool
+ isInitialized() const
+ {
+ return _initialized;
+ }
+
+ bool
+ isDestroyed() const
+ {
+ return _destroyed;
+ }
+
+protected:
+
+ const Ice::CommunicatorPtr _communicator;
+ bool _initialized;
+ bool _destroyed;
+ BasePluginPtr _other;
+};
+
+
+class PluginOne : public BasePlugin
+{
+
+public:
+
+ PluginOne(const Ice::CommunicatorPtr& communicator) :
+ BasePlugin(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwo"));
+ test(!_other->isInitialized());
+ _initialized = true;
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ test(_other->isDestroyed());
+ }
+};
+
+class PluginTwo : public BasePlugin
+{
+
+public:
+
+ PluginTwo(const Ice::CommunicatorPtr& communicator) :
+ BasePlugin(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _initialized = true;
+ _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginOne"));
+ test(_other->isInitialized());
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ test(!_other->isDestroyed());
+ }
+};
+
+class PluginThree : public BasePlugin
+{
+
+public:
+
+ PluginThree(const Ice::CommunicatorPtr& communicator) :
+ BasePlugin(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _initialized = true;
+ _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwo"));
+ test(_other->isInitialized());
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ test(!_other->isDestroyed());
+ }
+};
+
+class BasePluginFail;
+typedef IceUtil::Handle<BasePluginFail> BasePluginFailPtr;
+
+class BasePluginFail : public Ice::Plugin
+{
+
+public:
+
+ BasePluginFail(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator),
+ _initialized(false),
+ _destroyed(false)
+ {
+ }
+
+ bool
+ isInitialized() const
+ {
+ return _initialized;
+ }
+
+ bool
+ isDestroyed() const
+ {
+ return _destroyed;
+ }
+
+protected:
+
+ const Ice::CommunicatorPtr _communicator;
+ bool _initialized;
+ bool _destroyed;
+ BasePluginFailPtr _one;
+ BasePluginFailPtr _two;
+ BasePluginFailPtr _three;
+};
+
+
+class PluginOneFail : public BasePluginFail
+{
+
+public:
+
+ PluginOneFail(const Ice::CommunicatorPtr& communicator) :
+ BasePluginFail(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _two = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwoFail"));
+ test(!_two->isInitialized());
+ _three = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginThreeFail"));
+ test(!_three->isInitialized());
+ _initialized = true;
+ }
+
+ void
+ destroy()
+ {
+ test(_two->isDestroyed());
+ //
+ // Not destroyed because initialize fails.
+ //
+ test(!_three->isDestroyed());
+ _destroyed = true;
+ }
+
+ ~PluginOneFail()
+ {
+ test(_initialized);
+ test(_destroyed);
+ }
+};
+
+class PluginTwoFail : public BasePluginFail
+{
+
+public:
+
+ PluginTwoFail(const Ice::CommunicatorPtr& communicator) :
+ BasePluginFail(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ _initialized = true;
+ _one = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginOneFail"));
+ test(_one->isInitialized());
+ _three = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginThreeFail"));
+ test(!_three->isInitialized());
+ }
+
+ void
+ destroy()
+ {
+ _destroyed = true;
+ test(!_one->isDestroyed());
+ }
+
+ ~PluginTwoFail()
+ {
+ test(_initialized);
+ test(_destroyed);
+ }
+};
+
+class PluginThreeFail : public BasePluginFail
+{
+
+public:
+
+ PluginThreeFail(const Ice::CommunicatorPtr& communicator) :
+ BasePluginFail(communicator)
+ {
+ }
+
+ void
+ initialize()
+ {
+ throw PluginInitializeFailExeption();
+ }
+
+ void
+ destroy()
+ {
+ test(false);
+ }
+
+ ~PluginThreeFail()
+ {
+ test(!_initialized);
+ test(!_destroyed);
+ }
+};
+
+}
+
+extern "C"
+{
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPlugin(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq& args)
+{
+ return new Plugin(communicator, args);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginInitializeFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginInitializeFail(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginOne(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginOne(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginTwo(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginTwo(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginThree(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginThree(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginOneFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginOneFail(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginTwoFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginTwoFail(communicator);
+}
+
+ICE_DECLSPEC_EXPORT ::Ice::Plugin*
+createPluginThreeFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
+{
+ return new PluginThreeFail(communicator);
+}
+
+}
diff --git a/cpp/test/Ice/plugin/plugins/.gitignore b/cpp/test/Ice/plugin/plugins/.gitignore
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/cpp/test/Ice/plugin/plugins/.gitignore
diff --git a/cpp/test/Ice/plugin/run.py b/cpp/test/Ice/plugin/run.py
new file mode 100755
index 00000000000..3c4472ca289
--- /dev/null
+++ b/cpp/test/Ice/plugin/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+client = os.path.join(os.getcwd(), "client")
+TestUtil.simpleTest(client)
+
diff --git a/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp b/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp
index 1b36c721576..becadead55f 100644
--- a/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp
+++ b/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp
@@ -301,7 +301,8 @@ static const TestCase allTest[] =
{"Ice\\stream", "Ice_stream_", "client.dll", 0, 0, 0},
{"Ice\\timeout", "Ice_timeout_", "client.dll", "server.dll", 0, 0 },
{"Ice\\udp", "Ice_udp_", "client.dll", "server.dll", 0, 0 },
- {"Ice\\hash", "Ice_hash_", "client.dll", 0, 0, 0}
+ {"Ice\\hash", "Ice_hash_", "client.dll", 0, 0, 0},
+ {"Ice\\plugin", "Ice_plugin_", "client.dll", 0, 0, 0}
};
class TestRunner : public IceUtil::Thread