diff options
author | Benoit Foucher <benoit@zeroc.com> | 2015-06-08 13:05:22 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2015-06-08 13:05:22 +0200 |
commit | b2538adea86a17fccbacf87814361f050c97ae7e (patch) | |
tree | db900e7f606ca8ce9d114f11cf3ac2e9cc2abaf4 /cpp/src/IceGrid/Allocatable.cpp | |
parent | Fix IceSSL.CertFile property typo (diff) | |
download | ice-b2538adea86a17fccbacf87814361f050c97ae7e.tar.bz2 ice-b2538adea86a17fccbacf87814361f050c97ae7e.tar.xz ice-b2538adea86a17fccbacf87814361f050c97ae7e.zip |
Fixed ICE-6573 - IceGrid application update failure when updating server with allocatables and clients are waiting to allocate the allocatable
Diffstat (limited to 'cpp/src/IceGrid/Allocatable.cpp')
-rw-r--r-- | cpp/src/IceGrid/Allocatable.cpp | 114 |
1 files changed, 60 insertions, 54 deletions
diff --git a/cpp/src/IceGrid/Allocatable.cpp b/cpp/src/IceGrid/Allocatable.cpp index 9cbe97ea406..1c07ac2971b 100644 --- a/cpp/src/IceGrid/Allocatable.cpp +++ b/cpp/src/IceGrid/Allocatable.cpp @@ -22,7 +22,7 @@ AllocationRequest::pending() { Lock sync(*this); assert(_state == Initial); - + if(_timeout == 0) { _state = Canceled; @@ -89,8 +89,8 @@ AllocationRequest::allocate(const AllocatablePtr& /*allocatable*/, const Session } } -void -AllocationRequest::cancel(const AllocationException& ex) +void +AllocationRequest::cancel(const Ice::UserException& ex) { Lock sync(*this); switch(_state) @@ -107,7 +107,7 @@ AllocationRequest::cancel(const AllocationException& ex) } _session->removeAllocationRequest(this); break; - } + } _state = Canceled; canceled(ex); @@ -128,7 +128,7 @@ AllocationRequest::runTimerTask() // TimerTask::runTimerTask() method implementa _session->removeAllocationRequest(this); break; } - + _state = Canceled; canceled(AllocationTimeoutException()); } @@ -153,7 +153,7 @@ AllocationRequest::AllocationRequest(const SessionIPtr& session) : { } -Allocatable::Allocatable(bool allocatable, const AllocatablePtr& parent) : +Allocatable::Allocatable(bool allocatable, const AllocatablePtr& parent) : _allocatable(allocatable || (parent && parent->isAllocatable())), _count(0), _releasing(false) @@ -232,13 +232,13 @@ Allocatable::release(const SessionIPtr& session, bool fromRelease) { throw AllocationException("can't release object which is not allocated"); } - + if(--_count == 0) { _session = 0; released(session); - + isReleased = true; if(!fromRelease && !_requests.empty()) @@ -278,51 +278,65 @@ Allocatable::release(const SessionIPtr& session, bool fromRelease) return; } } - + // // Try to allocate the allocatable with the request or if // there's no request, just notify the allocatable that it can // be allocated again. // - if((request && allocatable->allocate(request, true)) || (!request && allocatable->canTryAllocate())) + try { - while(true) + if((request && allocatable->allocate(request, true)) || (!request && allocatable->canTryAllocate())) { + while(true) { - Lock sync(*this); - assert(_count); - - allocatable = 0; - request = 0; - - // - // Check if there's other requests from the session - // waiting to allocate this allocatable. - // - list<pair<AllocatablePtr, AllocationRequestPtr> >::iterator p = _requests.begin(); - while(p != _requests.end()) { - if(p->second && p->second->getSession() == _session) + Lock sync(*this); + assert(_count); + + allocatable = 0; + request = 0; + + // + // Check if there's other requests from the session + // waiting to allocate this allocatable. + // + list<pair<AllocatablePtr, AllocationRequestPtr> >::iterator p = _requests.begin(); + while(p != _requests.end()) + { + if(p->second && p->second->getSession() == _session) + { + allocatable = p->first; + request = p->second; + _requests.erase(p); + break; + } + ++p; + } + if(!allocatable) { - allocatable = p->first; - request = p->second; - _requests.erase(p); - break; + _releasing = false; + notifyAll(); + return; // We're done, the allocatable was released (but is allocated again)! } - ++p; - } - if(!allocatable) + } + + try + { + assert(allocatable && request); + allocatable->allocate(request, true); + } + catch(const Ice::UserException& ex) { - _releasing = false; - notifyAll(); - return; // We're done, the allocatable was released (but is allocated again)! + request->cancel(ex); } } - - assert(allocatable && request); - allocatable->allocate(request, true); } } + catch(const Ice::UserException& ex) + { + request->cancel(ex); + } } } else if(isReleased) @@ -346,8 +360,8 @@ Allocatable::operator<(const Allocatable& r) const } void -Allocatable::queueAllocationAttempt(const AllocatablePtr& allocatable, - const AllocationRequestPtr& request, +Allocatable::queueAllocationAttempt(const AllocatablePtr& allocatable, + const AllocationRequestPtr& request, bool tryAllocate) { assert(!_parent); @@ -361,7 +375,7 @@ Allocatable::queueAllocationAttempt(const AllocatablePtr& allocatable, else { _requests.push_back(make_pair(allocatable, AllocationRequestPtr())); - } + } } void @@ -401,7 +415,7 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo { return false; } - + bool queueWithParent = false; int allocationCount = 0; try @@ -451,21 +465,13 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo queueAllocationAttempt(this, request, tryAllocate); } } - catch(const SessionDestroyedException& ex) + catch(...) { if(_parent) { _parent->release(request->getSession(), fromRelease); } - throw ex; - } - catch(const AllocationException& ex) - { - if(_parent) - { - _parent->release(request->getSession(), fromRelease); - } - throw ex; + throw; } if(allocationCount == 1) @@ -484,8 +490,8 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo } bool -Allocatable::allocateFromChild(const AllocationRequestPtr& request, - const AllocatablePtr& child, +Allocatable::allocateFromChild(const AllocationRequestPtr& request, + const AllocatablePtr& child, bool tryAllocate, bool fromRelease) { @@ -493,7 +499,7 @@ Allocatable::allocateFromChild(const AllocationRequestPtr& request, { return false; } - + int allocationCount = 0; { Lock sync(*this); |