diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-11-10 14:34:52 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-11-10 14:34:52 +0000 |
commit | d8480f31455c708d0072a8d1a6a28f4b19bd647e (patch) | |
tree | 6d282b3fe4bf9ce7fe08c6da6b728f1f9912d76f /cpp | |
parent | Filter out IPv6 addresses in getLocalHosts (diff) | |
download | ice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.tar.bz2 ice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.tar.xz ice-d8480f31455c708d0072a8d1a6a28f4b19bd647e.zip |
Memory leak fixes
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/IceGrid/Activator.cpp | 74 | ||||
-rw-r--r-- | cpp/src/IceGrid/Activator.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/IceGridNode.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeI.cpp | 66 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeI.h | 8 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeSessionManager.cpp | 7 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeSessionManager.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.cpp | 15 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionManager.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/WaitQueue.cpp | 3 |
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 |