#ifndef LOCKINGPTR_H #define LOCKINGPTR_H ///////////////////////////////////////////////////////////////////// // lockingPtr.h - provides serialized access to class objects // // ver 1.0 // // Language: Visual C++, ver 6.0 // // Platform: Dell Dimension 8100, Win2000, SP 2 // // Application: CSE691 - Useful for projects #2 and #3 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////// /* This class follows closely that described by Andrei Alexandrescu in "Generic:volatile -- Multithreaded Programmer's Best Friend ... ", C/C++ Users Journal, Feb 2001. Class Operation =============== An object of the lockingPtr class provides serialized access to objects it references. It implements a smart pointer that uses an object of the Mutex class to provide a lock mechanism. Public Interface: ================= myObjType myObj; // some arbitrary object Mutex mtx; // provides a lock lockingPtr pMyObj(myObj,mtx); // serializes access pMyObj->memberFunction(args); // to myObj mtx.lock(); // acquire a lock cout << "\n a serialized use of cout" << endl; mtx.unlock(); // release the lock */ /////////////////////////////////////////////////////////////// // build process // /////////////////////////////////////////////////////////////// // required files: // // lockingPtr.h, lockingPtr.cpp // // // // command line compile: // // cl /GX /GZ /DTEST_LOCKINGPTR lockingPtr.cpp // /////////////////////////////////////////////////////////////// /* Maintenance History: ==================== ver 1.0 : 10 Oct 2001 - first release */ // /////////////////////////////////////////////////////////////// // class declaration for Mutex // /////////////////////////////////////////////////////////////// #include class Mutex { public: Mutex(); ~Mutex(); void lock(); void unlock(); private: CRITICAL_SECTION cs; }; Mutex::Mutex() { InitializeCriticalSection(&cs); } Mutex::~Mutex() { DeleteCriticalSection(&cs); } void Mutex::lock() { EnterCriticalSection(&cs); } void Mutex::unlock() { LeaveCriticalSection(&cs); } /////////////////////////////////////////////////////////////// // class declaration for lockingPtr // /////////////////////////////////////////////////////////////// template class lockingPtr { public: lockingPtr(volatile T &obj, Mutex &mtx); ~lockingPtr(); T& operator*(); T* operator->(); private: T* _pObj; Mutex *_pMtx; lockingPtr(const lockingPtr&); lockingPtr& operator=(const lockingPtr&); }; template inline lockingPtr::lockingPtr(volatile T &obj, Mutex &mtx) : _pObj(const_cast(&obj)), _pMtx(&mtx) { mtx.lock(); } template inline lockingPtr::~lockingPtr() { _pMtx->unlock(); } template inline T& lockingPtr::operator*() { return *_pObj; } template inline T* lockingPtr::operator->() { return _pObj; } #endif