diff options
author | Bernard Normier <bernard@zeroc.com> | 2004-04-19 20:55:36 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2004-04-19 20:55:36 +0000 |
commit | 8e39b811b7b71c2e5cf2f623b5d108a62d882d5e (patch) | |
tree | 16df76b8ecdd90dae6557b447dcd3847df381757 /cpp/src | |
parent | Changed looking detection policy to DB_LOCK_YOUNGEST (diff) | |
download | ice-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.cpp | 288 | ||||
-rw-r--r-- | cpp/src/Freeze/EvictorI.h | 5 | ||||
-rw-r--r-- | cpp/src/Freeze/ObjectStore.cpp | 1 | ||||
-rw-r--r-- | cpp/src/Freeze/ObjectStore.h | 1 | ||||
-rw-r--r-- | cpp/src/IceUtil/CountDownLatch.cpp | 148 | ||||
-rw-r--r-- | cpp/src/IceUtil/Makefile | 3 | ||||
-rw-r--r-- | cpp/src/IceUtil/iceutil.dsp | 8 |
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
|