164 lines
3.4 KiB
C++
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;
|
|
};
|