diff -c -r Ice-3.4.2/cpp/src/Glacier2/Blobject.cpp Ice-3.4.2.new/cpp/src/Glacier2/Blobject.cpp *** Ice-3.4.2/cpp/src/Glacier2/Blobject.cpp 2011-06-15 12:43:58.000000000 -0700 --- Ice-3.4.2.new/cpp/src/Glacier2/Blobject.cpp 2012-01-26 11:57:54.594083057 -0800 *************** *** 171,176 **** --- 171,185 ---- } void + Glacier2::Blobject::destroy() + { + if(_requestQueue) + { + _requestQueue->destroy(); + } + } + + void Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Object_ice_invokePtr& amdCB, const std::pair& inParams, const Current& current) { diff -c -r Ice-3.4.2/cpp/src/Glacier2/Blobject.h Ice-3.4.2.new/cpp/src/Glacier2/Blobject.h *** Ice-3.4.2/cpp/src/Glacier2/Blobject.h 2011-06-15 12:43:58.000000000 -0700 --- Ice-3.4.2.new/cpp/src/Glacier2/Blobject.h 2012-01-26 11:56:54.175971818 -0800 *************** *** 24,29 **** --- 24,31 ---- Blobject(const InstancePtr&, const Ice::ConnectionPtr&, const Ice::Context&); virtual ~Blobject(); + void destroy(); + protected: void invoke(Ice::ObjectPrx&, const Ice::AMD_Object_ice_invokePtr&, diff -c -r Ice-3.4.2/cpp/src/Glacier2/RequestQueue.cpp Ice-3.4.2.new/cpp/src/Glacier2/RequestQueue.cpp *** Ice-3.4.2/cpp/src/Glacier2/RequestQueue.cpp 2011-06-15 12:43:58.000000000 -0700 --- Ice-3.4.2.new/cpp/src/Glacier2/RequestQueue.cpp 2012-01-26 13:27:36.620235674 -0800 *************** *** 185,191 **** _callback(newCallback_Object_ice_invoke(this, &RequestQueue::response, &RequestQueue::exception, &RequestQueue::sent)), _flushCallback(newCallback_Connection_flushBatchRequests(this, &RequestQueue::exception, &RequestQueue::sent)), ! _pendingSend(false) { } --- 185,192 ---- _callback(newCallback_Object_ice_invoke(this, &RequestQueue::response, &RequestQueue::exception, &RequestQueue::sent)), _flushCallback(newCallback_Connection_flushBatchRequests(this, &RequestQueue::exception, &RequestQueue::sent)), ! _pendingSend(false), ! _destroyed(false) { } *************** *** 241,246 **** --- 242,278 ---- } void + Glacier2::RequestQueue::destroy() + { + IceUtil::Mutex::Lock lock(*this); + + _destroyed = true; + + // + // Although the session has been destroyed, we cannot destroy this queue + // until all requests have completed. + // + if(_requests.empty()) + { + destroyInternal(); + } + } + + void + Glacier2::RequestQueue::destroyInternal() + { + // + // Must be called with the mutex locked. + // + + // + // Remove cyclic references. + // + const_cast(_callback) = 0; + const_cast(_flushCallback) = 0; + } + + void Glacier2::RequestQueue::flush() { assert(_connection); *************** *** 289,294 **** --- 321,331 ---- _pendingSendRequest = 0; } } + + if(_destroyed && _requests.empty()) + { + destroyInternal(); + } } void *************** *** 312,317 **** --- 349,359 ---- } } _requests.clear(); + + if(_destroyed) + { + destroyInternal(); + } } void diff -c -r Ice-3.4.2/cpp/src/Glacier2/RequestQueue.h Ice-3.4.2.new/cpp/src/Glacier2/RequestQueue.h *** Ice-3.4.2/cpp/src/Glacier2/RequestQueue.h 2011-06-15 12:43:58.000000000 -0700 --- Ice-3.4.2.new/cpp/src/Glacier2/RequestQueue.h 2012-01-26 13:27:29.312929831 -0800 *************** *** 65,72 **** --- 65,76 ---- bool addRequest(const RequestPtr&); void flushRequests(std::set&); + void destroy(); + private: + void destroyInternal(); + void flush(); void flush(std::set&); *************** *** 83,88 **** --- 87,93 ---- std::deque _requests; bool _pendingSend; RequestPtr _pendingSendRequest; + bool _destroyed; }; typedef IceUtil::Handle RequestQueuePtr; diff -c -r Ice-3.4.2/cpp/src/Glacier2/RouterI.cpp Ice-3.4.2.new/cpp/src/Glacier2/RouterI.cpp *** Ice-3.4.2/cpp/src/Glacier2/RouterI.cpp 2011-06-15 12:43:58.000000000 -0700 --- Ice-3.4.2.new/cpp/src/Glacier2/RouterI.cpp 2012-01-26 11:56:30.989171821 -0800 *************** *** 98,103 **** --- 98,109 ---- _session->destroy_async(amiCB); } } + + _clientBlobject->destroy(); + if(_serverBlobject) + { + _serverBlobject->destroy(); + } } ObjectPrx