// Interface of Waiter, also takes care of mutex_ & cond_ init and destroy.
class Waiter : boost::noncopyable
{
public:
virtual void wait() = 0;
virtual void signal() = 0;
protected:
Waiter()
{
pthread_mutex_init(&mutex_, NULL);
pthread_cond_init(&cond_, NULL);
}
~Waiter()
{
pthread_mutex_destroy(&mutex_);
pthread_cond_destroy(&cond_);
}
pthread_mutex_t mutex_;
pthread_cond_t cond_;
};
// Version 7: broadcast to wakeup multiple waiting threads
// Probably the best version among above.
class Waiter7 : public Waiter
{
public:
void wait() override
{
pthread_mutex_lock(&mutex_);
while (!signaled_)
{
pthread_cond_wait(&cond_, &mutex_);
}
pthread_mutex_unlock(&mutex_);
}
void signal() override // Sorry, bad name in base class, poor OOP
{
broadcast();
}
void broadcast()
{
pthread_mutex_lock(&mutex_);
pthread_cond_broadcast(&cond_);
signaled_ = true;
pthread_mutex_unlock(&mutex_);
}
private:
bool signaled_ = false;
};