summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/Allocatable.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-04-24 09:46:12 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-04-24 09:46:12 +0000
commita5fdbf7412b96cecd45314f9d9eb37aaf77a2bf1 (patch)
treea2f26b3e3207ac925239385101f18a5459da1664 /cpp/src/IceGrid/Allocatable.cpp
parentUnix Fix. (diff)
downloadice-a5fdbf7412b96cecd45314f9d9eb37aaf77a2bf1.tar.bz2
ice-a5fdbf7412b96cecd45314f9d9eb37aaf77a2bf1.tar.xz
ice-a5fdbf7412b96cecd45314f9d9eb37aaf77a2bf1.zip
Added first cut of the allocation mechanism.
Diffstat (limited to 'cpp/src/IceGrid/Allocatable.cpp')
-rw-r--r--cpp/src/IceGrid/Allocatable.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/Allocatable.cpp b/cpp/src/IceGrid/Allocatable.cpp
new file mode 100644
index 00000000000..4760bafe09b
--- /dev/null
+++ b/cpp/src/IceGrid/Allocatable.cpp
@@ -0,0 +1,187 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceGrid/Allocatable.h>
+#include <IceGrid/SessionI.h>
+
+using namespace std;
+using namespace IceGrid;
+
+AllocationRequest::~AllocationRequest()
+{
+}
+
+bool
+AllocationRequest::setAllocatable(const AllocatablePtr& allocatable)
+{
+ Lock sync(*this);
+ assert(!_allocatable);
+ if(_canceled)
+ {
+ return false;
+ }
+ _allocatable = allocatable;
+ allocated(_allocatable);
+ return true;
+}
+
+void
+AllocationRequest::cancel()
+{
+ Lock sync(*this);
+ if(_canceled)
+ {
+ return;
+ }
+ _canceled = true;
+ canceled();
+}
+
+bool
+AllocationRequest::checkTimeout(const IceUtil::Time& now)
+{
+ assert(_timeout > 0);
+ {
+ Lock sync(*this);
+ if(_canceled)
+ {
+ return true;
+ }
+ _canceled = _expiration < now;
+ if(!_canceled)
+ {
+ return false;
+ }
+ timeout();
+ }
+ _session->removeAllocationRequest(this);
+ return true;
+}
+
+void
+AllocationRequest::allocate()
+{
+ _session->addAllocationRequest(this);
+}
+
+void
+AllocationRequest::release(const SessionIPtr& session)
+{
+ //
+ // Check if the session releasing the object is indeed the session
+ // which initiated the allocation request.
+ //
+ if(_session != session)
+ {
+ throw AllocationException("can't release object which is not allocated");
+ }
+ _session->removeAllocationRequest(this);
+}
+
+bool
+AllocationRequest::operator<(const AllocationRequest& r) const
+{
+ return this < &r;
+}
+
+AllocationRequest::AllocationRequest(const SessionIPtr& session) :
+ _session(session),
+ _timeout(_session->getAllocationTimeout()),
+ _expiration(_timeout > 0 ? (IceUtil::Time::now() + IceUtil::Time::milliSeconds(_timeout)) : IceUtil::Time()),
+ _canceled(false)
+{
+}
+
+Allocatable::Allocatable(bool allocatable) : _allocatable(allocatable), _allocated(false)
+{
+}
+
+Allocatable::~Allocatable()
+{
+}
+
+void
+Allocatable::allocate(const AllocationRequestPtr& request, bool allocateOnce)
+{
+ IceUtil::Mutex::Lock sync(_allocateMutex);
+ if(_allocatable)
+ {
+ if(_allocated)
+ {
+ if(_allocated->getSession() == request->getSession())
+ {
+ if(allocateOnce)
+ {
+ throw AllocationException("object already allocated by the session");
+ }
+ request->setAllocatable(this);
+ }
+ else if(request->getTimeout())
+ {
+ request->allocate();
+ _requests.push_back(request); // TODO: XXX: monitor request timeout if timeout != -1
+ }
+ else
+ {
+ request->timeout();
+ }
+ }
+ else if(request->setAllocatable(this))
+ {
+ _allocated = request;
+ _allocated->allocate();
+ }
+ }
+ else
+ {
+ if(allocateOnce)
+ {
+ throw AllocationException("can't allocate non allocatable object");
+ }
+ bool rc = request->setAllocatable(this);
+ assert(rc);
+ }
+}
+
+bool
+Allocatable::tryAllocate(const AllocationRequestPtr& request)
+{
+ IceUtil::Mutex::Lock sync(_allocateMutex);
+ if(_allocatable && _allocated)
+ {
+ return false;
+ }
+ else if(request->setAllocatable(this))
+ {
+ _allocated = request;
+ _allocated->allocate();
+ }
+ return true;
+}
+
+void
+Allocatable::release(const SessionIPtr& session)
+{
+ IceUtil::Mutex::Lock sync(_allocateMutex);
+ if(!_allocated)
+ {
+ throw AllocationException("object not allocated");
+ }
+ _allocated->release(session);
+ while(!_requests.empty())
+ {
+ _allocated = _requests.front();
+ _requests.pop_front();
+ if(_allocated->setAllocatable(this))
+ {
+ return;
+ }
+ }
+ _allocated = 0;
+}