1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   detail/event.hpp
9  * \author Andrey Semashev
10  * \date   24.07.2011
11  */
12 
13 #ifndef BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
14 #define BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
15 
16 #include <boost/log/detail/config.hpp>
17 
18 #ifdef BOOST_HAS_PRAGMA_ONCE
19 #pragma once
20 #endif
21 
22 #ifndef BOOST_LOG_NO_THREADS
23 
24 #if defined(BOOST_THREAD_PLATFORM_PTHREAD)
25 #   include <boost/atomic/capabilities.hpp>
26 #   if (defined(linux) || defined(__linux) || defined(__linux__)) && BOOST_ATOMIC_INT_LOCK_FREE == 2
27 #       include <boost/atomic/atomic.hpp>
28 #       define BOOST_LOG_EVENT_USE_FUTEX
29 #   elif defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES + 0) > 0 && BOOST_ATOMIC_FLAG_LOCK_FREE == 2
30 #       include <semaphore.h>
31 #       include <boost/cstdint.hpp>
32 #       include <boost/atomic/atomic_flag.hpp>
33 #       define BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE
34 #   endif
35 #elif defined(BOOST_THREAD_PLATFORM_WIN32)
36 #   include <boost/cstdint.hpp>
37 #   define BOOST_LOG_EVENT_USE_WINAPI
38 #endif
39 
40 #if !defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE) && !defined(BOOST_LOG_EVENT_USE_WINAPI)
41 #   include <boost/thread/mutex.hpp>
42 #   include <boost/thread/condition_variable.hpp>
43 #   define BOOST_LOG_EVENT_USE_BOOST_CONDITION
44 #endif
45 
46 #include <boost/log/detail/header.hpp>
47 
48 namespace boost {
49 
50 BOOST_LOG_OPEN_NAMESPACE
51 
52 namespace aux {
53 
54 #if defined(BOOST_LOG_EVENT_USE_FUTEX)
55 
56 class futex_based_event
57 {
58 private:
59     boost::atomic< int > m_state;
60 
61 public:
62     //! Default constructor
63     BOOST_LOG_API futex_based_event();
64     //! Destructor
65     BOOST_LOG_API ~futex_based_event();
66 
67     //! Waits for the object to become signalled
68     BOOST_LOG_API void wait();
69     //! Sets the object to a signalled state
70     BOOST_LOG_API void set_signalled();
71 
72     //  Copying prohibited
73     BOOST_DELETED_FUNCTION(futex_based_event(futex_based_event const&))
74     BOOST_DELETED_FUNCTION(futex_based_event& operator= (futex_based_event const&))
75 };
76 
77 typedef futex_based_event event;
78 
79 #elif defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
80 
81 class sem_based_event
82 {
83 private:
84     boost::atomic_flag m_state;
85     sem_t m_semaphore;
86 
87 public:
88     //! Default constructor
89     BOOST_LOG_API sem_based_event();
90     //! Destructor
91     BOOST_LOG_API ~sem_based_event();
92 
93     //! Waits for the object to become signalled
94     BOOST_LOG_API void wait();
95     //! Sets the object to a signalled state
96     BOOST_LOG_API void set_signalled();
97 
98     //  Copying prohibited
99     BOOST_DELETED_FUNCTION(sem_based_event(sem_based_event const&))
100     BOOST_DELETED_FUNCTION(sem_based_event& operator= (sem_based_event const&))
101 };
102 
103 typedef sem_based_event event;
104 
105 #elif defined(BOOST_LOG_EVENT_USE_WINAPI)
106 
107 class winapi_based_event
108 {
109 private:
110     boost::uint32_t m_state;
111     void* m_event;
112 
113 public:
114     //! Default constructor
115     BOOST_LOG_API winapi_based_event();
116     //! Destructor
117     BOOST_LOG_API ~winapi_based_event();
118 
119     //! Waits for the object to become signalled
120     BOOST_LOG_API void wait();
121     //! Sets the object to a signalled state
122     BOOST_LOG_API void set_signalled();
123 
124     //  Copying prohibited
125     BOOST_DELETED_FUNCTION(winapi_based_event(winapi_based_event const&))
126     BOOST_DELETED_FUNCTION(winapi_based_event& operator= (winapi_based_event const&))
127 };
128 
129 typedef winapi_based_event event;
130 
131 #else
132 
133 class generic_event
134 {
135 private:
136     boost::mutex m_mutex;
137     boost::condition_variable m_cond;
138     bool m_state;
139 
140 public:
141     //! Default constructor
142     BOOST_LOG_API generic_event();
143     //! Destructor
144     BOOST_LOG_API ~generic_event();
145 
146     //! Waits for the object to become signalled
147     BOOST_LOG_API void wait();
148     //! Sets the object to a signalled state
149     BOOST_LOG_API void set_signalled();
150 
151     //  Copying prohibited
152     BOOST_DELETED_FUNCTION(generic_event(generic_event const&))
153     BOOST_DELETED_FUNCTION(generic_event& operator= (generic_event const&))
154 };
155 
156 typedef generic_event event;
157 
158 #endif
159 
160 } // namespace aux
161 
162 BOOST_LOG_CLOSE_NAMESPACE // namespace log
163 
164 } // namespace boost
165 
166 #include <boost/log/detail/footer.hpp>
167 
168 #endif // BOOST_LOG_NO_THREADS
169 
170 #endif // BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
171