#include #include "PipeConditionVar.h" void PipeConditionVar::set() { pthread_mutex_lock(&_mutex); if (!_set) { write(_writeHandle, "P", 1); _set = true; } pthread_mutex_unlock(&_mutex); } void PipeConditionVar::clear() { pthread_mutex_lock(&_mutex); if (_set) { char buffer; read(_readHandle, &buffer, 1); _set = false; } pthread_mutex_unlock(&_mutex); } PipeConditionVar::PipeConditionVar() : _set(false) { pthread_mutex_init(&_mutex, NULL); int filedes[2]; _error = pipe(filedes); if (_error) { _readHandle = 0; _writeHandle = 0; } else { _readHandle = filedes[0]; _writeHandle = filedes[1]; _pollSet.addForRead(_readHandle); } } PipeConditionVar::~PipeConditionVar() { if (_writeHandle) close(_writeHandle); //close(_readHandle); // Ensure that noone is currently using the PipeConditionVar. In particular, // one thread calls set(). A second thread calls wait(). The second thread // immediately deletes the PipeConditionVar. (This really happens in // ../tikiller/CandleClient.C) This object is deleted before the call to // set() is finished. That can cause problems that are hard to track down. // Waiting on the lock here will prevent that case. pthread_mutex_lock(&_mutex); pthread_mutex_unlock(&_mutex); pthread_mutex_destroy(&_mutex); if (_readHandle) close(_readHandle); } void PipeConditionVar::wait(long seconds, long microseconds) const { timeval timeout; timeout.tv_sec = seconds; timeout.tv_usec = microseconds; wait(&timeout); } void PipeConditionVar::wait(timeval const *pause) const { // The "if" is more than just an optimization. If you call this twice // in a row, and it is set, then you will immediately return both // times. // This only works if only one thread is allowed to do a wait on the // condition variable. That is the standard useage. if (!isSet()) { // Originally I created a new PollSet each time we got here. Later I // added _pollSet to the class defintion so it would only be created // and initialized once. There was no change in functionality. It would // be very hard to remove the const keyword from this function. IPollSet &pollSet = const_cast< IPollSet & >(_pollSet); pollSet.setTimeout(pause); pollSet.poll(); } }