summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/Allocatable.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2015-06-08 13:05:22 +0200
committerBenoit Foucher <benoit@zeroc.com>2015-06-08 13:05:22 +0200
commitb2538adea86a17fccbacf87814361f050c97ae7e (patch)
treedb900e7f606ca8ce9d114f11cf3ac2e9cc2abaf4 /cpp/src/IceGrid/Allocatable.cpp
parentFix IceSSL.CertFile property typo (diff)
downloadice-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.cpp114
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);