summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-11-10 14:34:52 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-11-10 14:34:52 +0000
commitd8480f31455c708d0072a8d1a6a28f4b19bd647e (patch)
tree6d282b3fe4bf9ce7fe08c6da6b728f1f9912d76f /cpp
parentFilter out IPv6 addresses in getLocalHosts (diff)
downloadice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.tar.bz2
ice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.tar.xz
ice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.zip
Memory leak fixes
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/IceGrid/Activator.cpp74
-rw-r--r--cpp/src/IceGrid/Activator.h2
-rw-r--r--cpp/src/IceGrid/IceGridNode.cpp5
-rw-r--r--cpp/src/IceGrid/NodeI.cpp66
-rw-r--r--cpp/src/IceGrid/NodeI.h8
-rw-r--r--cpp/src/IceGrid/NodeSessionManager.cpp7
-rw-r--r--cpp/src/IceGrid/NodeSessionManager.h2
-rw-r--r--cpp/src/IceGrid/ServerI.cpp15
-rw-r--r--cpp/src/IceGrid/ServerI.h2
-rw-r--r--cpp/src/IceGrid/SessionManager.h2
-rw-r--r--cpp/src/IceGrid/WaitQueue.cpp3
11 files changed, 113 insertions, 73 deletions
diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp
index 4e8151d8014..62dd2c6920f 100644
--- a/cpp/src/IceGrid/Activator.cpp
+++ b/cpp/src/IceGrid/Activator.cpp
@@ -989,15 +989,43 @@ Activator::shutdown()
void
Activator::destroy()
{
+ map<string, Process> processes;
{
IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
assert(_deactivating);
+ processes = _processes;
}
//
- // Deactivate all the processes.
+ // Stop all active processes.
//
- deactivateAll();
+ for(map<string, Process>::iterator p = processes.begin(); p != processes.end(); ++p)
+ {
+ //
+ // Stop the server. The listener thread should detect the
+ // process deactivation and remove it from the activator's
+ // list of active processes.
+ //
+ try
+ {
+ p->second.server->stop_async(0);
+ }
+ catch(const ServerStopException&)
+ {
+ // Server already stopped or destroyed.
+ }
+ catch(const ObjectNotExistException&)
+ {
+ //
+ // Expected if the server was in the process of being destroyed.
+ //
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "unexpected exception raised by server `" << p->first << "' stop:\n" << ex;
+ }
+ }
//
// Join the termination listener thread. This thread terminates
@@ -1006,6 +1034,7 @@ Activator::destroy()
//
_thread->getThreadControl().join();
_thread = 0;
+ assert(_processes.empty());
}
void
@@ -1032,47 +1061,6 @@ Activator::runTerminationListener()
}
void
-Activator::deactivateAll()
-{
- //
- // Stop all active processes.
- //
- map<string, Process> processes;
- {
- IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
- processes = _processes;
- }
-
- for(map<string, Process>::iterator p = processes.begin(); p != processes.end(); ++p)
- {
- //
- // Stop the server. The listener thread should detect the
- // process deactivation and remove it from the activator's
- // list of active processes.
- //
- try
- {
- p->second.server->stop_async(0);
- }
- catch(const ServerStopException&)
- {
- // Server already stopped or destroyed.
- }
- catch(const ObjectNotExistException&)
- {
- //
- // Expected if the server was in the process of being destroyed.
- //
- }
- catch(const Ice::LocalException& ex)
- {
- Ice::Warning out(_traceLevels->logger);
- out << "unexpected exception raised by server `" << p->first << "' stop:\n" << ex;
- }
- }
-}
-
-void
Activator::terminationListener()
{
#ifdef _WIN32
diff --git a/cpp/src/IceGrid/Activator.h b/cpp/src/IceGrid/Activator.h
index b8f4753f262..fe2165070dd 100644
--- a/cpp/src/IceGrid/Activator.h
+++ b/cpp/src/IceGrid/Activator.h
@@ -57,8 +57,6 @@ public:
private:
- void deactivateAll();
-
void terminationListener();
void clearInterrupt();
void setInterrupt();
diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp
index 27426b3c3bc..cd314f84bd7 100644
--- a/cpp/src/IceGrid/IceGridNode.cpp
+++ b/cpp/src/IceGrid/IceGridNode.cpp
@@ -660,6 +660,11 @@ NodeService::stop()
// Terminate the node sessions with the registries.
//
_sessions.destroy();
+
+ //
+ // Break cylic reference counts.
+ //
+ _node->destroy();
_node = 0;
//
diff --git a/cpp/src/IceGrid/NodeI.cpp b/cpp/src/IceGrid/NodeI.cpp
index 1fbf58643ec..8c08d9b38bb 100644
--- a/cpp/src/IceGrid/NodeI.cpp
+++ b/cpp/src/IceGrid/NodeI.cpp
@@ -510,6 +510,13 @@ NodeI::shutdown(const Ice::Current&) const
_activator->shutdown();
}
+void
+NodeI::destroy()
+{
+ IceUtil::Mutex::Lock sync(_serversLock);
+ _serversByApplication.clear();
+}
+
Ice::CommunicatorPtr
NodeI::getCommunicator() const
{
@@ -593,10 +600,11 @@ NodeI::checkConsistency(const NodeSessionPrx& session)
}
void
-NodeI::addObserver(const string& replicaName, const NodeObserverPrx& observer)
+NodeI::addObserver(const NodeSessionPrx& session, const NodeObserverPrx& observer)
{
IceUtil::Mutex::Lock sync(_observerMutex);
- _observers.insert(make_pair(replicaName, observer));
+ assert(_observers.find(session) == _observers.end());
+ _observers.insert(make_pair(session, observer));
ServerDynamicInfoSeq serverInfos;
AdapterDynamicInfoSeq adapterInfos;
@@ -630,10 +638,11 @@ NodeI::addObserver(const string& replicaName, const NodeObserverPrx& observer)
}
void
-NodeI::removeObserver(const string& replicaName)
+NodeI::removeObserver(const NodeSessionPrx& session)
{
IceUtil::Mutex::Lock sync(_observerMutex);
- _observers.erase(replicaName);
+ assert(_observers.find(session) != _observers.end());
+ _observers.erase(session);
}
void
@@ -650,15 +659,26 @@ NodeI::observerUpdateServer(const ServerDynamicInfo& info)
_serversDynamicInfo[info.id] = info;
}
- for(map<string, NodeObserverPrx>::const_iterator p = _observers.begin(); p != _observers.end(); ++p)
+ //
+ // Send the update and make sure we don't send the update twice to
+ // the same observer (it's possible for the observer to be
+ // registered twice if a replica is removed and added right away
+ // after).
+ //
+ set<NodeObserverPrx> sent;
+ for(map<NodeSessionPrx, NodeObserverPrx>::const_iterator p = _observers.begin(); p != _observers.end(); ++p)
{
- try
- {
- p->second->updateServer(_name, info);
- }
- catch(const Ice::LocalException&)
+ if(sent.find(p->second) == sent.end())
{
- // IGNORE
+ try
+ {
+ p->second->updateServer(_name, info);
+ sent.insert(p->second);
+ }
+ catch(const Ice::LocalException&)
+ {
+ // IGNORE
+ }
}
}
}
@@ -677,15 +697,25 @@ NodeI::observerUpdateAdapter(const AdapterDynamicInfo& info)
_adaptersDynamicInfo.erase(info.id);
}
- for(map<string, NodeObserverPrx>::const_iterator p = _observers.begin(); p != _observers.end(); ++p)
+ //
+ // Send the update and make sure we don't send the update twice to
+ // the same observer (it's possible for the observer to be
+ // registered twice if a replica is removed and added right away
+ // after).
+ //
+ set<NodeObserverPrx> sent;
+ for(map<NodeSessionPrx, NodeObserverPrx>::const_iterator p = _observers.begin(); p != _observers.end(); ++p)
{
- try
+ if(sent.find(p->second) == sent.end())
{
- p->second->updateAdapter(_name, info);
- }
- catch(const Ice::LocalException&)
- {
- // IGNORE
+ try
+ {
+ p->second->updateAdapter(_name, info);
+ }
+ catch(const Ice::LocalException&)
+ {
+ // IGNORE
+ }
}
}
}
diff --git a/cpp/src/IceGrid/NodeI.h b/cpp/src/IceGrid/NodeI.h
index 46df88855ad..f10d86627fa 100644
--- a/cpp/src/IceGrid/NodeI.h
+++ b/cpp/src/IceGrid/NodeI.h
@@ -53,6 +53,8 @@ public:
virtual std::string getHostname(const Ice::Current& = Ice::Current()) const;
virtual LoadInfo getLoad(const Ice::Current& = Ice::Current()) const;
virtual void shutdown(const Ice::Current&) const;
+
+ void destroy();
WaitQueuePtr getWaitQueue() const;
Ice::CommunicatorPtr getCommunicator() const;
@@ -66,8 +68,8 @@ public:
void checkConsistency(const NodeSessionPrx&);
NodeSessionPrx getMasterNodeSession() const;
- void addObserver(const std::string&, const NodeObserverPrx&);
- void removeObserver(const std::string&);
+ void addObserver(const NodeSessionPrx&, const NodeObserverPrx&);
+ void removeObserver(const NodeSessionPrx&);
void observerUpdateServer(const ServerDynamicInfo&);
void observerUpdateAdapter(const AdapterDynamicInfo&);
@@ -99,7 +101,7 @@ private:
std::string _tmpDir;
unsigned long _serial;
IceUtil::Mutex _observerMutex;
- std::map<std::string, NodeObserverPrx> _observers;
+ std::map<NodeSessionPrx, NodeObserverPrx> _observers;
std::map<std::string, ServerDynamicInfo> _serversDynamicInfo;
std::map<std::string, AdapterDynamicInfo> _adaptersDynamicInfo;
mutable PlatformInfo _platform;
diff --git a/cpp/src/IceGrid/NodeSessionManager.cpp b/cpp/src/IceGrid/NodeSessionManager.cpp
index 71981be12fd..1bef61986af 100644
--- a/cpp/src/IceGrid/NodeSessionManager.cpp
+++ b/cpp/src/IceGrid/NodeSessionManager.cpp
@@ -140,14 +140,14 @@ NodeSessionKeepAliveThread::createSessionImpl(const InternalRegistryPrx& registr
{
timeout = IceUtil::Time::seconds(t / 2);
}
- _node->addObserver(_name, session->getObserver());
+ _node->addObserver(session, session->getObserver());
return session;
}
void
NodeSessionKeepAliveThread::destroySession(const NodeSessionPrx& session)
{
- _node->removeObserver(_name);
+ _node->removeObserver(session);
try
{
@@ -185,6 +185,8 @@ NodeSessionKeepAliveThread::keepAlive(const NodeSessionPrx& session)
}
catch(const Ice::LocalException& ex)
{
+ _node->removeObserver(session);
+
if(_node->getTraceLevels() && _node->getTraceLevels()->replica > 0)
{
Ice::Trace out(_node->getTraceLevels()->logger, _node->getTraceLevels()->replicaCat);
@@ -343,6 +345,7 @@ NodeSessionManager::replicaRemoved(const InternalRegistryPrx& replica)
}
if(thread)
{
+ _node->removeObserver(thread->getSession()); // Needs to be done here because we don't destroy the session.
thread->terminate(false); // Don't destroy the session, the replica is being shutdown!
thread->getThreadControl().join();
}
diff --git a/cpp/src/IceGrid/NodeSessionManager.h b/cpp/src/IceGrid/NodeSessionManager.h
index e2a2f4a79e7..ee22a262521 100644
--- a/cpp/src/IceGrid/NodeSessionManager.h
+++ b/cpp/src/IceGrid/NodeSessionManager.h
@@ -34,6 +34,8 @@ public:
virtual void destroySession(const NodeSessionPrx&);
virtual bool keepAlive(const NodeSessionPrx&);
+ std::string getName() const { return _name; }
+
protected:
virtual NodeSessionPrx createSessionImpl(const InternalRegistryPrx&, IceUtil::Time&);
diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp
index cbf66ab51de..05c6125ad9a 100644
--- a/cpp/src/IceGrid/ServerI.cpp
+++ b/cpp/src/IceGrid/ServerI.cpp
@@ -262,21 +262,30 @@ ServerCommand::ServerCommand(const ServerIPtr& server) : _server(server)
{
}
+ServerCommand::~ServerCommand()
+{
+}
+
TimedServerCommand::TimedServerCommand(const ServerIPtr& server, const WaitQueuePtr& waitQueue, int timeout) :
- ServerCommand(server), _waitQueue(waitQueue), _timer(new CommandTimeoutItem(this)), _timeout(timeout)
+ ServerCommand(server), _waitQueue(waitQueue), _timeout(timeout)
{
}
void
TimedServerCommand::startTimer()
{
+ _timer = new CommandTimeoutItem(this);
_waitQueue->add(_timer, IceUtil::Time::seconds(_timeout));
}
void
TimedServerCommand::stopTimer()
{
- _waitQueue->remove(_timer);
+ if(_timer)
+ {
+ _waitQueue->remove(_timer);
+ _timer = 0;
+ }
}
LoadCommand::LoadCommand(const ServerIPtr& server) :
@@ -394,7 +403,7 @@ DestroyCommand::finished()
for(vector<AMD_Node_destroyServerPtr>::const_iterator p = _destroyCB.begin(); p != _destroyCB.end(); ++p)
{
(*p)->ice_response();
- }
+ }
}
PatchCommand::PatchCommand(const ServerIPtr& server) :
diff --git a/cpp/src/IceGrid/ServerI.h b/cpp/src/IceGrid/ServerI.h
index 6aa620d631a..8412d1598a5 100644
--- a/cpp/src/IceGrid/ServerI.h
+++ b/cpp/src/IceGrid/ServerI.h
@@ -170,6 +170,8 @@ class ServerCommand : public IceUtil::SimpleShared
public:
ServerCommand(const ServerIPtr&);
+ virtual ~ServerCommand();
+
virtual void execute() = 0;
virtual ServerI::InternalServerState nextState() = 0;
diff --git a/cpp/src/IceGrid/SessionManager.h b/cpp/src/IceGrid/SessionManager.h
index a1403b0cfba..30326f6a79c 100644
--- a/cpp/src/IceGrid/SessionManager.h
+++ b/cpp/src/IceGrid/SessionManager.h
@@ -96,7 +96,7 @@ public:
//
if(_nextAction == None)
{
- if(_state == Connected || (action == Connect || action == KeepAlive))
+ if(_state == Connected || action == Connect || action == KeepAlive)
{
IceUtil::Time wakeTime = IceUtil::Time::now() + timeout;
while(_state != Destroyed && _nextAction == None)
diff --git a/cpp/src/IceGrid/WaitQueue.cpp b/cpp/src/IceGrid/WaitQueue.cpp
index 50f8eeaf399..c959973ac1a 100644
--- a/cpp/src/IceGrid/WaitQueue.cpp
+++ b/cpp/src/IceGrid/WaitQueue.cpp
@@ -103,7 +103,7 @@ WaitQueue::run()
break;
}
}
-
+
if(!_waitQueue.empty())
{
for(list<WaitItemPtr>::iterator p = _waitQueue.begin(); p != _waitQueue.end(); ++p)
@@ -111,6 +111,7 @@ WaitQueue::run()
(*p)->expired(true);
}
}
+ _waitQueue.clear(); // Break cyclic reference counts.
}
void