windows-nt/Source/XPSP1/NT/termsrv/remdsk/server/sessmgr/map.h

300 lines
6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
map.h
Abstract:
Implementation of MAP<> template based on STL's map<>
Author:
HueiWang 2/17/2000
--*/
#ifndef __MAP_H__
#define __MAP_H__
#include "tsstl.h"
#include "locks.h"
template<class KEY, class T, class Pred = less<KEY>, class A = allocator<T> >
class MAP : public map<KEY, T, Pred, A> {
private:
//
// Difference between this MAP<> and STL's map<> is that this
// template protect data via critical section, refer to STL's map<>
// for detail of member function.
//
// critical section to lock the tree.
CCriticalSection m_CriticalSection;
//
//map<KEY, T, Pred, A>::iterator m_it;
public:
// LOCK_ITERATOR, derive from STL's map<>::iterator
typedef struct __Iterator : map<KEY, T, Pred, A>::iterator {
CCriticalSection& lock;
__Iterator(
const __Iterator& it
) : lock(it.lock)
/*++
--*/
{
lock.Lock();
*this = it;
}
__Iterator(
CCriticalSection& m,
iterator it
) :
lock(m)
{
lock.Lock();
*(map<KEY, T, Pred, A>::iterator *)this = it;
}
~__Iterator()
{
lock.UnLock();
}
__Iterator&
operator=(const __Iterator& it )
{
if( this != &it )
{
// No additional Lock() here since
// our constructor already holding a lock
*(map<KEY, T, Pred, A>::iterator *)this = (map<KEY, T, Pred, A>::iterator)it;
}
return *this;
}
} LOCK_ITERATOR;
LOCK_ITERATOR
begin()
/*++
overload map<>::begin()
--*/
{
// Double lock is necessary, caller could do
// <...>::LOCK_ITERATOR it = <>.find();
// and before LOCK_ITERATOR destructor got call, call might do
// it = <>.find() again, that will increase lock count by 1 and
// no way to release it.
CCriticalSectionLocker lock( m_CriticalSection );
return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::begin());
}
explicit
MAP(
const Pred& comp = Pred(),
const A& al = A()
) : map<KEY, T, Pred, A>( comp, al )
/*++
--*/
{
//m_it = end();
}
MAP(const map& x) : map(x)
{
m_it = end();
}
MAP(
const value_type *first,
const value_type *last,
const Pred& comp = Pred(),
const A& al = A()
) : map( first, last, comp, al )
{
//m_it = end();
}
//virtual ~MAP()
//{
// map<KEY, T, Pred, A>::~map();
//}
//---------------------------------------------------------
void
Cleanup()
{
erase_all();
}
//---------------------------------------------------------
void
Lock()
/*++
Explicity lock the data tree
--*/
{
m_CriticalSection.Lock();
}
//---------------------------------------------------------
void
Unlock()
/*++
lock lock the data tree
--*/
{
m_CriticalSection.UnLock();
}
//---------------------------------------------------------
bool
TryLock()
/*++
Try locking the tree, same as Win32's TryEnterCriticalSection().
--*/
{
return m_CriticalSection.TryLock();
}
//---------------------------------------------------------
A::reference operator[](
const KEY& key
)
/*++
Overload map<>::operator[] to lock tree.
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return map<KEY, T, Pred, A>::operator[](key);
}
//---------------------------------------------------------
pair<iterator, bool>
insert(iterator it, const value_type& x)
/*++
overload map<>;;insert()
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return map<KEY, T, Pred, A>::insert(Key);
}
//---------------------------------------------------------
void
insert(
const value_type* first,
const value_type* last
)
/*++
overload map<>::insert().
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
map<KEY, T, Pred, A>::insert(first, lase);
}
//---------------------------------------------------------
LOCK_ITERATOR
erase(
iterator it
)
/*++
overload map<>::erase()
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(it));
}
//---------------------------------------------------------
void
erase_all()
/*++
delete all data in the tree
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
erase( map<KEY, T, Pred, A>::begin(), end() );
return;
}
//---------------------------------------------------------
LOCK_ITERATOR
erase(
iterator first,
iterator last
)
/*++
Overload map<>::erase()
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return LOCK_ITERATOR(m_CriticalSection, map<KEY, T, Pred, A>::erase(first, last));
}
//---------------------------------------------------------
size_type
erase(
const KEY& key
)
/*++
overload map<>::erase()
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return map<KEY, T, Pred, A>::erase(key);
}
LOCK_ITERATOR
find(
const KEY& key
)
/*++
overload map<>::find()
--*/
{
CCriticalSectionLocker lock( m_CriticalSection );
return LOCK_ITERATOR( m_CriticalSection, map<KEY, T, Pred, A>::find(key) );
}
};
#endif