#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <assert.h>
enum MutexProtocol
{ PrioInherit, PrioNone };
// clase Cond;
plantilla <typename T>
clase LockT
{ public: LockT (const T & mutex): _mutex (mutex) { _mutex.lock (); _ adquirido = verdadero; } ~ LockT () { if (_acquired) { _mutex.unlock (); } } void adquirir () const { if (_acquired) { // lanzar ThreadLockedException (__ FILE__, __LINE__); } _mutex.lock (); _ adquirido = verdadero;
}
bool tryAcquire () const
{ if (_acquired) { // lanzar ThreadLockedException (__ FILE__, __LINE__); } _acquired = _mutex.tryLock (); return _acquired; }
void release () const
{ if (! _acquired) { // lanzar ThreadLockedException (__ FILE__, __LINE__); } _mutex.unlock (); _acquired = falso; }
bool adquirido () const
{ return _acquired; } protected: // Constructor de TryLockT LockT (const T & mutex, bool): _mutex (mutex) { _acquired = _mutex.tryLock (); }
privado:
// No se ha implementado; evita el uso accidental.
//
LockT (const LockT &);
LockT & operator = (const LockT &);
const T & _mutex;
mutable bool _acquired;
// clase de amigo Cond;
};
plantilla <typename T>
clase TryLockT: public LockT <T>
{ public:
TryLockT (const T & mutex):
LockT <T> (mutex, true)
{}
};
class Mutex
{ public: typedef LockT <Mutex> Lock; typedef TryLockT <Mutex> TryLock;
Mutex en línea ();
Mutex en línea (MutexProtocol);
~ Mutex ();
//
// Tenga en cuenta que lock / tryLock & unlock en general no deben usarse
// directamente. En su lugar, utilice Lock & TryLock.
//
void lock () const;
//
// Devuelve verdadero si se adquirió el bloqueo y falso en caso contrario.
//
bool tryLock () const;
void desbloquear () const;
//
// Devuelve verdadero si el mutex se desbloqueará al llamar a unlock ()
// (falso en caso contrario). Para las exclusiones mutuas no recursivas, esto siempre
// devolverá verdadero.
// Esta función es utilizada por la implementación del Monitor para saber si
// el Mutex ha sido bloqueado por primera vez, o desbloqueado por
// última vez (es decir, otro hilo puede adquirir el mutex).
// Precondición: el mutex debe estar bloqueado.
//
bool willUnlock () const;
privado:
init void en línea (MutexProtocol);
//
Mutex no copiable (const Mutex &);
operador vacío = (const Mutex &);
//
// LockState y las variaciones de bloqueo / desbloqueo son para uso de la
// implementación de la variable Condición.
//
estructura LockState
{ # ifdef ICE_HAS_WIN32_CONDVAR CRITICAL_SECTION * mutex; # endif }; Desbloqueo vacío (LockState &) const; bloqueo de vacío (LockState &) const; // clase de amigo Cond; mutable CRITICAL_SECTION _mutex; };
//
// Por motivos de rendimiento, las siguientes funciones están en línea.
//
Mutex en línea :: Mutex ()
{ init (PrioNone); } inline Mutex :: Mutex (MutexProtocol) { init (PrioNone); }
inline void Mutex :: init (MutexProtocol)
{ InitializeCriticalSection (& _ mutex); }
Mutex en línea :: ~ Mutex ()
{ DeleteCriticalSection (& _ mutex); }
inline void Mutex :: lock () const
{ EnterCriticalSection (& _ mutex); afirmar (_mutex.RecursionCount == 1); }
inline bool Mutex :: tryLock () const
{ if (! TryEnterCriticalSection (& _ mutex)) { return false; } if (_mutex.RecursionCount> 1) { LeaveCriticalSection (& _ mutex); // lanzar ThreadLockedException (__ FILE__, __LINE__); } devuelve verdadero; }
inline void Mutex :: unlock () const
{ assert (_mutex.RecursionCount == 1); LeaveCriticalSection (& _ mutex); }
inline void Mutex :: unlock (LockState &) const
{ LeaveCriticalSection (& _ mutex); }
inline void Mutex :: lock (LockState &) const
{ EnterCriticalSection (& _ mutex); }
inline bool Mutex :: willUnlock () const
{ return true; }
prueba void ()
{ Mutex _mutex; Mutex :: Bloquear sincronización (_mutex); }
int main ()
{ prueba (); getchar (); return 0; }