164 lines
3.4 KiB
C++

// Copyright (C) 2003 Intel Corporation
//////////////////////////////////////////////////////////////////////////
// SyncMap.h
//
// This file contains the definition of the SyncMap class
//////////////////////////////////////////////////////////////////////////
#include "Lock.h"
#include <map>
using namespace std;
template <class Key, class T>
class SyncMap
{
public:
typedef map<Key,T> TYPE;
//typedef TYPE::iterator iterator;
//SyncMap iterator.
//The class semantics is:
//The first existing iterator on the object locks the
//map when constructed, the last existing iterator
//unlocks it on destruction.
//So, when using SyncMap functions returning iterator
//make sure that all iterators are destroyed/out of scope
//before calling any other SyncMap member function.
class iterator: public TYPE::iterator {
public:
typedef TYPE::iterator BaseClass;
iterator():BaseClass(),_objPtr(0){}
iterator(TYPE::iterator i, SyncMap<Key,T> * _theObj):
BaseClass(i), _objPtr(_theObj) {
if( _objPtr ){
Lock l(_objPtr->_itSem);
if( ++_objPtr->_itCount == 1 ){
_objPtr->_lock.acquire();
}
}
}
iterator( iterator& _other):BaseClass(_other){
_objPtr = _other._objPtr;
if( _objPtr ){
Lock l(_objPtr->_itSem);
++_objPtr->_itCount;
}
}
iterator& operator=( iterator& _other){
if( this != &_other ){
//this is very important!
//must copy base class content:
*((BaseClass*)this) = *((BaseClass*)&_other);
if (_objPtr != 0) {
Lock l(_objPtr->_itSem);
--_objPtr->_itCount;
if (!_objPtr->_itCount) {
_objPtr->_lock.release();
}
}
//increment only if we are
//constructing the object here
Lock l(_other._objPtr->_itSem);
_objPtr = _other._objPtr;
++_objPtr->_itCount;
}
return *this;
}
bool operator==(const BaseClass& i){
return ((BaseClass)*this == i );
}
~iterator(){
if( _objPtr ){
Lock l(_objPtr->_itSem);
if( -- _objPtr->_itCount == 0){
_objPtr->_lock.release();
}
}
}
private:
SyncMap<Key,T> * _objPtr;
};
SyncMap (void):_lock(),_itSem(), _itCount(0), _map() {}
SyncMap (TYPE c):_lock(),_itSem(),_itCount(0){ this->_map = c; }
TYPE operator== (const TYPE m) {
Lock l (this->_lock);
return this->_map == i;
}
void operator= (const SyncMap &sm) {
// Check for identity to avoid dead_lock!
if (this != &sm) {
Lock l (this->_lock);
this->_map = sm._map;
}
}
operator TYPE () {
Lock l (this->_lock);
return this->_map;
}
TYPE::_Tref operator [](const Key& key) {
Lock l (this->_lock);
return _map[key];
}
iterator find(const Key& key){
TYPE::iterator temp;
iterator it(temp, this);
it = iterator(_map.find(key), this);
return it;
}
TYPE::size_type size(){
Lock l (this->_lock);
return _map.size();
}
void clear(){
Lock l (this->_lock);
_map.clear();
}
bool insert(const TYPE::value_type& x){
Lock l (this->_lock);
return (_map.insert(x)).second;
}
TYPE::size_type erase(const Key& key){
Lock l (this->_lock);
return _map.erase(key);
}
iterator begin(){
TYPE::iterator temp;
iterator it(temp, this);
it = iterator(_map.begin(), this);
return it;
}
iterator end(){
TYPE::iterator temp;
iterator it(temp, this);
it = iterator(_map.end(), this);
return it;
}
private:
friend class iterator;
Semaphore _lock;
unsigned _itCount;
Semaphore _itSem;
TYPE _map;
};