summaryrefslogtreecommitdiff
path: root/cpp/include/IceUtil/Cache.h
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2007-06-12 19:01:18 -0400
committerBernard Normier <bernard@zeroc.com>2007-06-12 19:01:18 -0400
commite097664d0d79d255ffe2c21e8185d1324ef43f96 (patch)
tree48465b67627f3c7383567421a56acbc27bf5f9d2 /cpp/include/IceUtil/Cache.h
parentBug 2222 - add note about MFC demos not compiling with 2005 Express (diff)
downloadice-e097664d0d79d255ffe2c21e8185d1324ef43f96.tar.bz2
ice-e097664d0d79d255ffe2c21e8185d1324ef43f96.tar.xz
ice-e097664d0d79d255ffe2c21e8185d1324ef43f96.zip
Fixed deadlock in Freeze transactional evictor
Diffstat (limited to 'cpp/include/IceUtil/Cache.h')
-rw-r--r--cpp/include/IceUtil/Cache.h77
1 files changed, 28 insertions, 49 deletions
diff --git a/cpp/include/IceUtil/Cache.h b/cpp/include/IceUtil/Cache.h
index 04afc7564b7..1449734e908 100644
--- a/cpp/include/IceUtil/Cache.h
+++ b/cpp/include/IceUtil/Cache.h
@@ -57,12 +57,10 @@ public:
typedef typename std::map<Key, CacheValue>::iterator Position;
-
- Handle<Value> getIfPinned(const Key&) const;
+ Handle<Value> getIfPinned(const Key&, bool = false) const;
void unpin(Position);
- Handle<Value> unpin(const Key&);
-
+
void clear();
size_t size() const;
@@ -95,62 +93,28 @@ private:
template<typename Key, typename Value> Handle<Value>
-Cache<Key, Value>::getIfPinned(const Key& key) const
-{
- Mutex::Lock sync(_mutex);
- typename CacheMap::const_iterator p = _map.find(key);
- if(p != _map.end())
- {
- return (*p).second.obj;
- }
- else
- {
- return 0;
- }
-}
-
-template<typename Key, typename Value> void
-Cache<Key, Value>::unpin(typename Cache::Position p)
-{
- //
- // There is no risk to erase a 'being loaded' position,
- // since such position nevr got outside yet!
- //
- Mutex::Lock sync(_mutex);
- _map.erase(p);
-}
-
-template<typename Key, typename Value> Handle<Value>
-Cache<Key, Value>::unpin(const Key& key)
+Cache<Key, Value>::getIfPinned(const Key& key, bool wait) const
{
Mutex::Lock sync(_mutex);
for(;;)
{
- typename CacheMap::iterator p = _map.find(key);
-
- if(p == _map.end())
- {
- return 0;
- }
-
- Handle<Value> result = p->second.obj;
-
- if(result != 0)
- {
- _map.erase(p);
- return result;
- }
- else
+ typename CacheMap::const_iterator p = _map.find(key);
+ if(p != _map.end())
{
+ Handle<Value> result = (*p).second.obj;
+ if(result != 0 || wait == false)
+ {
+ return result;
+ }
+
//
- // The object is being loaded so we need to wait:
- // we can't erase 'p' while the loading thread is using it
+ // The object is being loaded: we wait
//
if(p->second.latch == 0)
{
- p->second.latch = new Latch;
+ const_cast<CacheValue&>(p->second).latch = new Latch;
}
Latch* latch = p->second.latch;
@@ -166,9 +130,24 @@ Cache<Key, Value>::unpin(const Key& key)
// Try again
//
}
+ else
+ {
+ return 0;
+ }
}
}
+template<typename Key, typename Value> void
+Cache<Key, Value>::unpin(typename Cache::Position p)
+{
+ //
+ // There is no risk to erase a 'being loaded' position,
+ // since such position nevr got outside yet!
+ //
+ Mutex::Lock sync(_mutex);
+ _map.erase(p);
+}
+
template<typename Key, typename Value> void
Cache<Key, Value>::clear()
{