menu: added new Keywords tag to .desktop files
[barry.git] / src / semaphore.h
blob35dbd02326a390ce945f6080232feb06af279d98
1 ///
2 /// \file semaphore.h
3 /// Simple class implementing a semaphore using pthreads mutex and condvar.
4 ///
6 /*
7 Copyright (C) 2010, RealVNC Ltd.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #ifndef __BARRY_SEMAPHORE_H__
23 #define __BARRY_SEMAPHORE_H__
25 #include "scoped_lock.h"
26 #include <pthread.h>
28 namespace Barry {
30 class semaphore
32 pthread_mutex_t *m_mutex;
33 pthread_cond_t *m_cv;
34 int m_value;
35 public:
36 semaphore(pthread_mutex_t &mutex, pthread_cond_t &cv, int value = 0)
37 : m_mutex(&mutex)
38 , m_cv(&cv)
39 , m_value(value)
43 // Waits for the value of this semaphore to be greater than 0 and then
44 // decrements it by one before returning.
45 void WaitForSignal()
47 scoped_lock lock(*m_mutex);
48 while( m_value <= 0 ) {
49 int ret = pthread_cond_wait(m_cv, m_mutex);
50 if( ret != 0 ) {
51 throw Barry::Error("semaphore: failed to wait on condvar");
54 --m_value;
55 lock.unlock();
58 // Checks for a semaphore signal without blocking. Returns true and decrements
59 // the semaphore if the value is greater than 0, otherwise returns false.
60 bool ReceiveSignal()
62 bool ret = false;
63 scoped_lock lock(*m_mutex);
64 if( m_value > 0 ) {
65 --m_value;
66 ret = true;
68 lock.unlock();
69 return ret;
72 // Increments the value of this semaphore by 1, waking any sleeping threads waiting
73 // on this semaphore.
74 void Signal()
76 scoped_lock lock(*m_mutex);
77 ++m_value;
78 int ret = pthread_cond_signal(m_cv);
79 if( ret != 0 ) {
80 throw Barry::Error("Condvar: failed to signal condvar");
82 lock.unlock();
86 } // namespace Barry
88 #endif