Listing 3: The monitor class definition

#include <assert.h>
#include "CMonMutex.h"

template<class T> class CMonitor
{
public:

   template<class T> class CShield
   {
   public:
      CShield(T& rElement, IMutex* pMutex,
         unsigned short usTimeOut = INFINITE)
      {
         m_pElement  = &rElement;
         m_pMutex    = pMutex;
         m_usTimeOut = usTimeOut;
         m_bCopy     = false;
      }

      CShield(const CShield& shield)
      {
         assert( shield.m_bCopy != true );

         m_pElement  = shield.m_pElement;
         m_pMutex    = shield.m_pMutex;
         m_usTimeOut = shield.m_usTimeOut;
         m_bCopy     = true;

         m_pMutex->wait(m_usTimeOut);
      }

      ~CShield()
      {
         if( m_bCopy )
         {
            m_pMutex->release();
         }
      }

      T& element() const
      {
         return *m_pElement;
      }

   protected:
      T*             m_pElement;  // pointer to protected object
      IMutex*        m_pMutex;    // pointer to the mutex used
      unsigned short m_usTimeOut; // timeout value for mutex
      bool           m_bCopy;     // indicates if this is a copy

   private:
      // these methods are hidden here so that the complier
      // wont generate them
      CShield();
      CShield& operator=(const CShield& shield);
   };
   // --- end of CShield class ---

   CMonitor(T& rElement, unsigned short usTimeOut = INFINITE)
   {
      m_usTimeOut = usTimeOut;
      m_pElement  = &rElement;

      m_pShield =
         new CShield<T>(*m_pElement, &m_Mutex, m_usTimeOut);
   }

   virtual ~CMonitor()
   {
      delete m_pShield;
   }

   CShield<T> Safe()
   {
      return *m_pShield;
   }

protected:
   unsigned short m_usTimeOut; // timeout to use when waiting
   T*             m_pElement;  // pointer to protected element
   CMonMutex      m_Mutex;     // mutex to use for synchronization
   CShield<T>*    m_pShield;   // pointer to internal shield object

private:
};

#endif //end of file