#ifndef SHARED_VAR_H_ #define SHARED_VAR_H_ #include // has pthread_ routines // ---- Class for shared variable with lock -------------------------- // By defining a template class for shared variables, we can package // together the variable and the lock needed to control access to it, // and be sure the lock gets properly initialized and freed. template class sharedVar { public: // public member variable T data; // the shared variable -- public to permit // flexible access when none of the member // functions below are quite right. public: // Constructor (no parameters) and destructor. sharedVar(void) { pthread_mutex_init(&dataLock, NULL); } sharedVar(const T & val) { pthread_mutex_init(&dataLock, NULL); data = val; } ~sharedVar(void) { pthread_mutex_destroy(&dataLock); } private: // Copy constructor and assignment operator: Make private so // they can't be used (and we don't have to write them). sharedVar(const sharedVar & d); sharedVar & operator= (const sharedVar & d); public: // Function to get the lock associated with the variable. void lock(void) { pthread_mutex_lock(&dataLock); } // Function to release the lock associated with the variable. void unlock(void) { pthread_mutex_unlock(&dataLock); } // Function to perform thread-safe read of "data": // Returns current value (read while holding the lock). T safeRead(void) { lock(); T returnVal = data; unlock(); return returnVal; } // Function to perform thread-safe write of "data": // Replaces current value with "val" (modified while holding // the lock). void safeWrite(const T & val) { lock(); data = val; unlock(); } // Function to perform thread-safe update of "data" (e.g., // add 1 to it). // Replaces current value with the result of calling // "op(current value, val)", where "op" is a function with // prototype T op(T v1, T v2). template void safeUpdate(BinaryOp op, const T & val) { lock(); data = op(data, val); unlock(); } private: // private member variable(s) pthread_mutex_t dataLock; }; #endif // SHARED_VAR_H_