1 /***************************************************************************
2  *  foxxll/common/onoff_switch.hpp
3  *
4  *  Kind of binary semaphore: initially OFF, then multiple waiters can attach
5  *  to the switch, which get notified one-by-one when switched ON.
6  *
7  *  Part of FOXXLL. See http://foxxll.org
8  *
9  *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
10  *  Copyright (C) 2013 Timo Bingmann <tb@panthema.net>
11  *
12  *  Distributed under the Boost Software License, Version 1.0.
13  *  (See accompanying file LICENSE_1_0.txt or copy at
14  *  http://www.boost.org/LICENSE_1_0.txt)
15  **************************************************************************/
16 
17 #ifndef FOXXLL_COMMON_ONOFF_SWITCH_HEADER
18 #define FOXXLL_COMMON_ONOFF_SWITCH_HEADER
19 
20 #include <condition_variable>
21 #include <mutex>
22 
23 namespace foxxll {
24 
25 class onoff_switch
26 {
27     //! mutex for condition variable
28     std::mutex mutex_;
29 
30     //! condition variable
31     std::condition_variable cond_;
32 
33     //! the switch's state
34     bool on_;
35 
36 public:
37     //! construct switch
onoff_switch(bool flag=false)38     explicit onoff_switch(bool flag = false)
39         : on_(flag)
40     { }
41 
42     //! non-copyable: delete copy-constructor
43     onoff_switch(const onoff_switch&) = delete;
44     //! non-copyable: delete assignment operator
45     onoff_switch& operator = (const onoff_switch&) = delete;
46 
47     //! turn switch ON and notify one waiter
on()48     void on()
49     {
50         std::unique_lock<std::mutex> lock(mutex_);
51         on_ = true;
52         cond_.notify_one();
53     }
54 
55     //! turn switch OFF and notify one waiter
off()56     void off()
57     {
58         std::unique_lock<std::mutex> lock(mutex_);
59         on_ = false;
60         cond_.notify_one();
61     }
62 
63     //! wait for switch to turn ON
wait_for_on()64     void wait_for_on()
65     {
66         std::unique_lock<std::mutex> lock(mutex_);
67         if (!on_)
68             cond_.wait(lock);
69     }
70 
71     //! wait for switch to turn OFF
wait_for_off()72     void wait_for_off()
73     {
74         std::unique_lock<std::mutex> lock(mutex_);
75         if (on_)
76             cond_.wait(lock);
77     }
78 
79     //! return true if switch is ON
is_on()80     bool is_on()
81     {
82         std::unique_lock<std::mutex> lock(mutex_);
83         return on_;
84     }
85 };
86 
87 } // namespace foxxll
88 
89 #endif // !FOXXLL_COMMON_ONOFF_SWITCH_HEADER
90 
91 /**************************************************************************/
92