/* * SyncC++ * * Copyright(c) Haifeng Li 2002 * All Rights Reserved * */ #ifndef __HLI_MONITOR_H #define __HLI_MONITOR_H #include "mutex.h" #include "rwlock.h" #define LINED( x ) x##__LINE__ #define synchronized( lock ) \ for ( const _lock_block& LINED(_auto_lock) = _make_auto_lock( lock ); \ LINED(_auto_lock) > 0; ) #define syncread( rwlock ) \ for ( const _read_block LINED(_auto_lock)( rwlock ); LINED(_auto_lock) > 0; ) #define syncwrite( rwlock ) \ for ( const _write_block LINED(_auto_lock)( rwlock ); LINED(_auto_lock) > 0; ) #define transaction( trans ) \ for ( const _trans_block& LINED(_auto_trans) = _make_auto_trans( trans ); \ LINED(_auto_trans); LINED(_auto_trans).finish() ) class _lock_block { public: _lock_block ( ) : _counter( 1 ) { } operator int ( ) const { return _counter--; } private: mutable int _counter; }; template < typename Lock_T > class _auto_lock : public _lock_block { public: _auto_lock ( Lock_T& lock ) : _lock( &lock ) { _lock->lock(); } ~_auto_lock ( ) { _lock->unlock(); } private: Lock_T* _lock; }; template < typename Lock_T > inline _auto_lock < Lock_T > _make_auto_lock ( Lock_T& lock ) { return _auto_lock( lock ); } class _read_lock : public _lock_block { public: _read_lock ( rwlock& lock ) : _lock( &lock ) { _lock->rlock(); } ~_read_lock ( ) { _lock->unlock(); } private: rwlock* _lock; }; class _write_lock : public _lock_block { public: _write_lock ( rwlock& lock ) : _lock( &lock ) { _lock->wlock(); } ~_write_lock ( ) { _lock->unlock(); } private: rwlock* _lock; }; class _trans_block { public: _trans_block ( ) : _abort( true ) { } operator bool ( ) const { return _abort; } void finish ( ) const { _abort = false; } protected: mutable bool _abort; }; template < typename Trans_T > class _auto_trans : public _trans_block { public: _auto_trans ( Trans_T& trans ) : _trans( &trans ) { _trans->start(); } ~_auto_trans ( ) { if ( _abort ) _trans->rollback(); else _trans->commit(); } private: Trans_T* _trans; }; template < typename Trans_T > inline _auto_trans < Trans_T > _make_auto_trans ( Trans_T& trans ) { return _auto_trans( trans ); } #endif // __HLI_MONITOR_H