// Copyright (C) 2003 Intel Corporation ////////////////////////////////////////////////////////////////////////// // SyncMap.h // // This file contains the definition of the SyncMap class ////////////////////////////////////////////////////////////////////////// #include "Lock.h" #include using namespace std; template class SyncMap { public: typedef map 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 * _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 * _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; };