ReplicaEntryPtr ReplicaCache::add(const string& name, const ReplicaSessionIPtr& session) { Lock sync(*this); ReplicaEntryPtr entry; while((entry = getImpl(name))) { ReplicaSessionIPtr session = entry->getSession(); if(session->isDestroyed()) { wait(); // Wait for the session to be removed. } else { // // Check if the replica is still reachable, if not, we // destroy its session. // sync.release(); try { session->getInternalRegistry()->ice_ping(); throw ReplicaActiveException(); } catch(const Ice::LocalException&) { try { session->destroy(); } catch(const Ice::LocalException&) { } } sync.acquire(); } } if(_traceLevels && _traceLevels->replica > 0) { Ice::Trace out(_traceLevels->logger, _traceLevels->replicaCat); out << "replica `" << name << "' up"; } try { _observers->replicaAdded(session->getInternalRegistry()); } catch(const Ice::ConnectionRefusedException&) { // Expected if the replica is being shutdown. } catch(const Ice::LocalException& ex) { TraceLevelsPtr traceLevels = getTraceLevels(); if(traceLevels) { Ice::Warning out(traceLevels->logger); out << "unexpected exception while publishing `replicaAdded' update:\n" << ex; } } return addImpl(name, new ReplicaEntry(name, session)); }