summaryrefslogtreecommitdiff
path: root/cpp/src/IcePack/ServerManagerI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IcePack/ServerManagerI.cpp')
-rw-r--r--cpp/src/IcePack/ServerManagerI.cpp313
1 files changed, 313 insertions, 0 deletions
diff --git a/cpp/src/IcePack/ServerManagerI.cpp b/cpp/src/IcePack/ServerManagerI.cpp
new file mode 100644
index 00000000000..6b150c06838
--- /dev/null
+++ b/cpp/src/IcePack/ServerManagerI.cpp
@@ -0,0 +1,313 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <Ice/Functional.h>
+#include <Ice/LoggerUtil.h>
+#include <IcePack/ServerManagerI.h>
+#include <IcePack/AdapterManager.h>
+#include <IcePack/Activator.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePack;
+
+class ServerNameToServer
+{
+public:
+
+ ServerNameToServer(const ObjectAdapterPtr& adapter) :
+ _adapter(adapter)
+ {
+ }
+
+ ServerPrx
+ operator()(const string& name)
+ {
+ Identity ident;
+ ident.category = "server";
+ ident.name = name;
+ return ServerPrx::uncheckedCast(_adapter->createProxy(ident));
+ }
+
+private:
+
+ ObjectAdapterPtr _adapter;
+};
+
+IcePack::ServerI::ServerI(const ObjectAdapterPtr& adapter, const ActivatorPrx& activator) :
+ _adapter(adapter),
+ _activator(activator)
+{
+}
+
+IcePack::ServerI::~ServerI()
+{
+}
+
+ServerDescription
+IcePack::ServerI::getServerDescription(const Current&)
+{
+ return _description;
+}
+
+bool
+IcePack::ServerI::start(const Current&)
+{
+ while(true)
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+ if(!_activator)
+ return false;
+
+ switch(_state)
+ {
+ case Inactive:
+ _state = Activating;
+ break;
+
+ case Activating:
+ wait(); // TODO: Timeout?
+ continue;
+
+ case Active:
+ return true; // Raise an exception instead?
+
+ case Deactivating:
+ wait();
+ continue;
+
+ case Destroyed:
+ throw ObjectNotExistException(__FILE__,__LINE__);
+ }
+ break;
+ }
+
+ try
+ {
+ bool activated = _activator->activate(ServerNameToServer(_adapter)(_description.name));
+ setState(activated ? Active : Inactive);
+ return activated;
+ }
+ catch (const SystemException& ex)
+ {
+ Warning out(_adapter->getCommunicator()->getLogger());
+ out << "activation failed for server `" << _description.name << "':\n";
+ out << ex;
+
+ setState(Inactive);
+ return false;
+ }
+}
+
+void
+IcePack::ServerI::terminationCallback(const Current&)
+{
+ //
+ // Callback from the activator indicating that the server
+ // stopped. Change state to deactivating while we mark the server
+ // adapters as inactive.
+ //
+ setState(Deactivating);
+
+ //
+ // Mark each adapter as inactive. _adapters is immutable when
+ // state == Deactivating.
+ //
+ for(Adapters::iterator p = _adapters.begin(); p != _adapters.end(); ++p)
+ {
+ (*p)->markAsInactive();
+ }
+
+ setState(Inactive);
+}
+
+ServerState
+IcePack::ServerI::getState(const Current&)
+{
+ IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+ return _state;
+}
+
+void
+IcePack::ServerI::setState(ServerState state)
+{
+ IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+
+ if(state == Destroyed && (_state == Active || _state == Deactivating))
+ throw ServerNotInactiveException();
+
+ _state = state;
+
+ notifyAll();
+}
+
+IcePack::ServerManagerI::ServerManagerI(const ObjectAdapterPtr& adapter,
+ const AdapterManagerPrx& adapterManager,
+ const ActivatorPrx& activator) :
+ _adapter(adapter),
+ _adapterManager(adapterManager),
+ _activator(activator)
+{
+}
+
+IcePack::ServerManagerI::~ServerManagerI()
+{
+}
+
+ServerPrx
+IcePack::ServerManagerI::create(const ServerDescription& description, const Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ ServerPrx server = ServerNameToServer(_adapter)(description.name);
+ try
+ {
+ server->ice_ping();
+
+ //
+ // The server already exists.
+ //
+ throw ServerExistsException();
+ }
+ catch (const ObjectNotExistException&)
+ {
+ }
+
+ //
+ // Create the server. Set its state to Activating so that we can
+ // safelly register the adapters without any race conditions. If a
+ // request comes in for an adapter we've just registerd, the
+ // server won't be started as long as we are not in the Inactive
+ // state.
+ //
+ ServerI* serverI = new ServerI(_adapter, _activator);
+ ServerPtr s = serverI;
+ serverI->_description = description;
+ serverI->_state = Activating;
+
+ //
+ // The server object might receives requests as soon as it returns
+ // from this call. This is the reason why we've created the server
+ // in the activating state -- to block any attempts to activate
+ // the server. The server state is set to inactive once it's fully
+ // created.
+ //
+ server = ServerPrx::uncheckedCast(_adapter->add(serverI, server->ice_getIdentity()));
+
+ try
+ {
+ //
+ // Register the server adapters to enabled automatic
+ // activation. If an adapter already exists, rollback the
+ // server creation and throw an exception.
+ //
+ for(AdapterNames::const_iterator p = description.adapters.begin(); p != description.adapters.end(); ++p)
+ {
+ AdapterDescription desc;
+ desc.name = (*p);
+ desc.server = server;
+ serverI->_adapters.push_back(_adapterManager->create(desc));
+ }
+ }
+ catch (const AdapterExistsException&)
+ {
+ //
+ // The adapter is already registered with a server, remove the
+ // server.
+ //
+ _adapter->remove(server->ice_getIdentity());
+ serverI->setState(Destroyed);
+ throw;
+ }
+
+ //
+ // Set the server state as inactive. At this point the server can
+ // be automatically started if a request for one of its adapter
+ // comes in.
+ //
+ serverI->setState(Inactive);
+
+ //
+ // Add this server name to our server names internal list.
+ //
+ _serverNames.insert(description.name);
+
+ return server;
+}
+
+ServerPrx
+IcePack::ServerManagerI::findByName(const string& name, const Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ ServerPrx server = ServerNameToServer(_adapter)(name);
+ try
+ {
+ server->ice_ping();
+ return server;
+ }
+ catch (const ObjectNotExistException&)
+ {
+ return 0;
+ }
+}
+
+void
+IcePack::ServerManagerI::remove(const string& name, const Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ ServerPrx server = ServerNameToServer(_adapter)(name);
+ try
+ {
+ server->ice_ping();
+ }
+ catch (const ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+
+ //
+ // Mark the server as destroyed.
+ //
+ ServerI* serverI = dynamic_cast<ServerI*>(_adapter->proxyToServant(server).get());
+ assert(serverI);
+ serverI->setState(Destroyed);
+
+ //
+ // Remove server adapters.
+ //
+ ServerDescription description = serverI->_description;
+ for(AdapterNames::iterator p = description.adapters.begin(); p != description.adapters.end(); ++p)
+ {
+ _adapterManager->remove(*p);
+ }
+
+ _adapter->remove(server->ice_getIdentity());
+
+ //
+ // Remove the server name from our internal server name set.
+ //
+ _serverNames.erase(_serverNames.find(name));
+}
+
+ServerNames
+IcePack::ServerManagerI::getAll(const Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ ServerNames names;
+ names.reserve(_serverNames.size());
+ copy(_serverNames.begin(), _serverNames.end(), back_inserter(names));
+
+ return names;
+}
+