summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2004-04-19 20:55:36 +0000
committerBernard Normier <bernard@zeroc.com>2004-04-19 20:55:36 +0000
commit8e39b811b7b71c2e5cf2f623b5d108a62d882d5e (patch)
tree16df76b8ecdd90dae6557b447dcd3847df381757 /cpp/src
parentChanged looking detection policy to DB_LOCK_YOUNGEST (diff)
downloadice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.tar.bz2
ice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.tar.xz
ice-8e39b811b7b71c2e5cf2f623b5d108a62d882d5e.zip
Added keep, keepFacet, remove and removeFacet to Evictor; implemented
IceUtil::Cache properly
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Freeze/EvictorI.cpp288
-rw-r--r--cpp/src/Freeze/EvictorI.h5
-rw-r--r--cpp/src/Freeze/ObjectStore.cpp1
-rw-r--r--cpp/src/Freeze/ObjectStore.h1
-rw-r--r--cpp/src/IceUtil/CountDownLatch.cpp148
-rw-r--r--cpp/src/IceUtil/Makefile3
-rw-r--r--cpp/src/IceUtil/iceutil.dsp8
7 files changed, 395 insertions, 59 deletions
diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp
index c81525ef805..70dd963b0b9 100644
--- a/cpp/src/Freeze/EvictorI.cpp
+++ b/cpp/src/Freeze/EvictorI.cpp
@@ -322,11 +322,11 @@ Freeze::EvictorI::addFacet(const ObjectPtr& servant, const Identity& ident, cons
EvictorElementPtr element = new EvictorElement(*store);
element->status = EvictorElement::dead;
- pair<EvictorElementPtr, bool> ir = store->insert(ident, element);
+ EvictorElementPtr oldElt = store->putIfAbsent(ident, element);
- if(ir.second == false)
+ if(oldElt != 0)
{
- element = ir.first;
+ element = oldElt;
}
{
@@ -439,11 +439,11 @@ Freeze::EvictorI::createObject(const Identity& ident, const ObjectPtr& servant)
EvictorElementPtr element = new EvictorElement(*store);
element->status = EvictorElement::dead;
- pair<EvictorElementPtr, bool> ir = store->insert(ident, element);
+ EvictorElementPtr oldElt = store->putIfAbsent(ident, element);
- if(ir.second == false)
+ if(oldElt != 0)
{
- element = ir.first;
+ element = oldElt;
}
{
@@ -559,46 +559,62 @@ Freeze::EvictorI::removeFacet(const Identity& ident, const string& facet)
}
fixEvictPosition(element);
- IceUtil::Mutex::Lock lock(element->mutex);
-
- switch(element->status)
{
- case EvictorElement::clean:
- {
- element->status = EvictorElement::destroyed;
- element->rec.servant = 0;
- addToModifiedQueue(element);
- break;
- }
- case EvictorElement::created:
- {
- element->status = EvictorElement::dead;
- element->rec.servant = 0;
- break;
- }
- case EvictorElement::modified:
- {
- element->status = EvictorElement::destroyed;
- element->rec.servant = 0;
- //
- // Not necessary to push it on the modified queue, as a modified
- // element is either on the queue already or about to be saved
- // (at which point it becomes clean)
- //
- break;
- }
- case EvictorElement::destroyed:
- case EvictorElement::dead:
- {
- notThere = true;
- break;
- }
- default:
+ IceUtil::Mutex::Lock lock(element->mutex);
+
+ switch(element->status)
{
- assert(0);
- break;
+ case EvictorElement::clean:
+ {
+ element->status = EvictorElement::destroyed;
+ element->rec.servant = 0;
+ addToModifiedQueue(element);
+ break;
+ }
+ case EvictorElement::created:
+ {
+ element->status = EvictorElement::dead;
+ element->rec.servant = 0;
+ break;
+ }
+ case EvictorElement::modified:
+ {
+ element->status = EvictorElement::destroyed;
+ element->rec.servant = 0;
+ //
+ // Not necessary to push it on the modified queue, as a modified
+ // element is either on the queue already or about to be saved
+ // (at which point it becomes clean)
+ //
+ break;
+ }
+ case EvictorElement::destroyed:
+ case EvictorElement::dead:
+ {
+ notThere = true;
+ break;
+ }
+ default:
+ {
+ assert(0);
+ break;
+ }
}
}
+ if(element->keepCount > 0)
+ {
+ assert(notThere == false);
+
+ element->keepCount = 0;
+ //
+ // Add to front of evictor queue
+ //
+ // Note that save evicts dead objects
+ //
+ _evictorList.push_front(element);
+ _currentEvictorSize++;
+ element->evictPosition = _evictorList.begin();
+ }
}
break; // for(;;)
}
@@ -645,6 +661,156 @@ Freeze::EvictorI::destroyObject(const Identity& ident)
}
}
+void
+Freeze::EvictorI::keep(const Identity& ident)
+{
+ keepFacet(ident, "");
+}
+
+void
+Freeze::EvictorI::keepFacet(const Identity& ident, const string& facet)
+{
+ bool notThere = false;
+
+ ObjectStore* store = findStore(facet);
+ if(store == 0)
+ {
+ notThere = true;
+ }
+ else
+ {
+ for(;;)
+ {
+ EvictorElementPtr element = store->pin(ident);
+ if(element == 0)
+ {
+ notThere = true;
+ break;
+ }
+
+ Lock sync(*this);
+ if(_deactivated)
+ {
+ throw EvictorDeactivatedException(__FILE__, __LINE__);
+ }
+
+ if(element->stale)
+ {
+ //
+ // try again
+ //
+ continue;
+ }
+
+
+ {
+ IceUtil::Mutex::Lock lockElement(element->mutex);
+ if(element->status == EvictorElement::destroyed || element->status == EvictorElement::dead)
+ {
+ notThere = true;
+ break;
+ }
+ }
+
+ //
+ // Found!
+ //
+
+ if(element->keepCount == 0)
+ {
+ if(element->usageCount < 0)
+ {
+ //
+ // New object
+ //
+ element->usageCount = 0;
+ }
+ else
+ {
+ _evictorList.erase(element->evictPosition);
+ _currentEvictorSize--;
+ }
+ element->keepCount = 1;
+ }
+ else
+ {
+ element->keepCount++;
+ }
+ break;
+ }
+ }
+
+ if(notThere)
+ {
+ NotRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "servant";
+ ex.id = identityToString(ident);
+ if(!facet.empty())
+ {
+ ex.id += " -f " + facet;
+ }
+ throw ex;
+ }
+}
+
+void
+Freeze::EvictorI::release(const Identity& ident)
+{
+ releaseFacet(ident, "");
+}
+
+void
+Freeze::EvictorI::releaseFacet(const Identity& ident, const string& facet)
+{
+ {
+ Lock sync(*this);
+
+ if(_deactivated)
+ {
+ throw EvictorDeactivatedException(__FILE__, __LINE__);
+ }
+
+ StoreMap::iterator p = _storeMap.find(facet);
+ if(p != _storeMap.end())
+ {
+ ObjectStore* store = (*p).second;
+
+ EvictorElementPtr element = store->getIfPinned(ident);
+ if(element != 0)
+ {
+ assert(!element->stale);
+ if(element->keepCount > 0)
+ {
+ if(--element->keepCount == 0)
+ {
+ //
+ // Add to front of evictor queue
+ //
+ // Note that the element cannot be destroyed or dead since
+ // its keepCount was > 0.
+ //
+ _evictorList.push_front(element);
+ _currentEvictorSize++;
+ element->evictPosition = _evictorList.begin();
+ }
+ //
+ // Success
+ //
+ return;
+ }
+ }
+ }
+ }
+
+ NotRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "servant";
+ ex.id = identityToString(ident);
+ if(!facet.empty())
+ {
+ ex.id += " -f " + facet;
+ }
+ throw ex;
+}
EvictorIteratorPtr
Freeze::EvictorI::getIterator(const string& facet, Int batchSize)
@@ -692,7 +858,7 @@ Freeze::EvictorI::hasFacet(const Identity& ident, const string& facet)
return false;
}
- ObjectStore* store = (*p).second;
+ store = (*p).second;
EvictorElementPtr element = store->getIfPinned(ident);
if(element != 0)
@@ -858,7 +1024,7 @@ Freeze::EvictorI::finished(const Current& current, const ObjectPtr& servant, con
{
addToModifiedQueue(element);
}
- else
+ else if(element->usageCount == 0 && element->keepCount == 0)
{
//
// Evict as many elements as necessary.
@@ -1230,7 +1396,7 @@ Freeze::EvictorI::run()
EvictorElementPtr& element = *q;
if(!element->stale)
{
- if(element->usageCount == 0)
+ if(element->usageCount == 0 && element->keepCount == 0)
{
//
// Get rid of unused dead elements
@@ -1345,6 +1511,7 @@ Freeze::EvictorI::evict()
EvictorElementPtr& element = *p;
assert(!element->stale);
+ assert(element->keepCount == 0);
if(_trace >= 2 || (_trace >= 1 && _evictorList.size() % 50 == 0))
{
@@ -1374,27 +1541,32 @@ void
Freeze::EvictorI::fixEvictPosition(const EvictorElementPtr& element)
{
assert(!element->stale);
- if(element->usageCount < 0)
- {
- //
- // New object
- //
- element->usageCount = 0;
- _currentEvictorSize++;
- }
- else
+
+ if(element->keepCount == 0)
{
- _evictorList.erase(element->evictPosition);
+ if(element->usageCount < 0)
+ {
+ //
+ // New object
+ //
+ element->usageCount = 0;
+ _currentEvictorSize++;
+ }
+ else
+ {
+ _evictorList.erase(element->evictPosition);
+ }
+ _evictorList.push_front(element);
+ element->evictPosition = _evictorList.begin();
}
- _evictorList.push_front(element);
- element->evictPosition = _evictorList.begin();
}
void
Freeze::EvictorI::evict(const EvictorElementPtr& element)
{
assert(!element->stale);
-
+ assert(element->keepCount == 0);
+
_evictorList.erase(element->evictPosition);
_currentEvictorSize--;
element->stale = true;
diff --git a/cpp/src/Freeze/EvictorI.h b/cpp/src/Freeze/EvictorI.h
index 91dc4b60675..8cbbae5315e 100644
--- a/cpp/src/Freeze/EvictorI.h
+++ b/cpp/src/Freeze/EvictorI.h
@@ -53,6 +53,11 @@ public:
virtual void removeFacet(const Ice::Identity&, const std::string&);
virtual void destroyObject(const Ice::Identity&);
+ virtual void keep(const Ice::Identity&);
+ virtual void keepFacet(const Ice::Identity&, const std::string&);
+ virtual void release(const Ice::Identity&);
+ virtual void releaseFacet(const Ice::Identity&, const std::string&);
+
virtual bool hasObject(const Ice::Identity&);
virtual bool hasFacet(const Ice::Identity&, const std::string&);
diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp
index d8e955c8321..ab45a2da208 100644
--- a/cpp/src/Freeze/ObjectStore.cpp
+++ b/cpp/src/Freeze/ObjectStore.cpp
@@ -345,6 +345,7 @@ Freeze::ObjectStore::pinned(const EvictorElementPtr& element, Cache::Position p)
Freeze::EvictorElement::EvictorElement(ObjectStore& s) :
store(s),
usageCount(-1),
+ keepCount(0),
stale(true),
status(clean)
{
diff --git a/cpp/src/Freeze/ObjectStore.h b/cpp/src/Freeze/ObjectStore.h
index 614dd0024d6..8e0c2a500ca 100644
--- a/cpp/src/Freeze/ObjectStore.h
+++ b/cpp/src/Freeze/ObjectStore.h
@@ -143,6 +143,7 @@ struct EvictorElement : public Ice::LocalObject
//
std::list<EvictorElementPtr>::iterator evictPosition;
int usageCount;
+ int keepCount;
bool stale;
//
diff --git a/cpp/src/IceUtil/CountDownLatch.cpp b/cpp/src/IceUtil/CountDownLatch.cpp
new file mode 100644
index 00000000000..6e1f37d8646
--- /dev/null
+++ b/cpp/src/IceUtil/CountDownLatch.cpp
@@ -0,0 +1,148 @@
+// **********************************************************************
+//
+// Copyright (c) 2004
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <IceUtil/CountDownLatch.h>
+#include <IceUtil/ThreadException.h>
+
+IceUtil::CountDownLatch::CountDownLatch(int count) :
+ _count(count)
+{
+ if(count < 0)
+ {
+ throw Exception(__FILE__, __LINE__);
+ }
+
+#ifdef _WIN32
+ _event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if(_event == NULL)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, GetLastError());
+ }
+#else
+ int rc = pthread_mutex_init(&_mutex, 0);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+
+ rc = pthread_cond_init(&_cond, 0);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+#endif
+}
+
+
+void
+IceUtil::CountDownLatch::await() const
+{
+#ifdef _WIN32
+ int* countPtr = const_cast<int*>(&_count);
+ while(InterlockedCompareExchange(countPtr, 0, 0) > 0)
+ {
+ DWORD rc = WaitForSingleObject(_event, INFINITE);
+ assert(rc == WAIT_OBJECT_0 || rc == WAIT_FAILED);
+
+ if(rc == WAIT_FAILED)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, GetLastError());
+ }
+ }
+#else
+ lock();
+ while(_count > 0)
+ {
+ int rc = pthread_cond_wait(&_cond, &_mutex);
+ if(rc != 0)
+ {
+ pthread_mutex_unlock(&_mutex);
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+ }
+ unlock();
+
+#endif
+}
+
+void
+IceUtil::CountDownLatch::countDown()
+{
+#ifdef _WIN32
+ if(InterlockedDecrement(&_count) == 0)
+ {
+ if(SetEvent(_event) == 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, GetLastError());
+ }
+ }
+#else
+ bool broadcast = false;
+
+ lock();
+ if(_count > 0 && --_count == 0)
+ {
+ broadcast = true;
+ }
+ unlock();
+
+ if(broadcast)
+ {
+ int rc = pthread_cond_broadcast(&_cond);
+ if(rc != 0)
+ {
+ pthread_mutex_unlock(&_mutex);
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+ }
+#endif
+}
+
+int
+IceUtil::CountDownLatch::getCount() const
+{
+#ifdef _WIN32
+ int* countPtr = const_cast<int*>(&_count);
+ int count = InterlockedCompareExchange(countPtr, 0, 0);
+ return count > 0 ? count : 0;
+#else
+ lock();
+ int result = _count;
+ unlock();
+ return result;
+#endif
+}
+
+#ifndef _WIN32
+void
+IceUtil::CountDownLatch::lock() const
+{
+ int rc = pthread_mutex_lock(&_mutex);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+}
+
+void
+IceUtil::CountDownLatch::unlock() const
+{
+ int rc = pthread_mutex_unlock(&_mutex);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__, rc);
+ }
+}
+
+#endif
diff --git a/cpp/src/IceUtil/Makefile b/cpp/src/IceUtil/Makefile
index 533f74d2f6a..6059d14187e 100644
--- a/cpp/src/IceUtil/Makefile
+++ b/cpp/src/IceUtil/Makefile
@@ -36,7 +36,8 @@ OBJS = Exception.o \
Base64.o \
GCShared.o \
GCRecMutex.o \
- GC.o
+ GC.o \
+ CountDownLatch.o
SRCS = $(OBJS:.o=.cpp)
diff --git a/cpp/src/IceUtil/iceutil.dsp b/cpp/src/IceUtil/iceutil.dsp
index 3927dabe9be..ab68750322d 100644
--- a/cpp/src/IceUtil/iceutil.dsp
+++ b/cpp/src/IceUtil/iceutil.dsp
@@ -114,6 +114,10 @@ SOURCE=.\Cond.cpp
# End Source File
# Begin Source File
+SOURCE=.\CountDownLatch.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\CtrlCHandler.cpp
# End Source File
# Begin Source File
@@ -190,6 +194,10 @@ SOURCE=..\..\include\IceUtil\Cond.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\IceUtil\CountDownLatch.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IceUtil\Config.h
# End Source File
# Begin Source File