RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
posix_event.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 //
20 // detail/posix_event.hpp
21 // ~~~~~~~~~~~~~~~~~~~~~~
22 //
23 // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
24 //
25 // Distributed under the Boost Software License, Version 1.0. (See accompanying
26 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
27 //
28
29 #ifndef RCF_DETAIL_POSIX_EVENT_HPP
30 #define RCF_DETAIL_POSIX_EVENT_HPP
31
32 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
33 # pragma once
34 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
35
36 #if defined(BOOST_HAS_PTHREADS)
37
38 #include <boost/assert.hpp>
39 #include <pthread.h>
40 #include <errno.h>
41
42 #include <RCF/thread/push_options.hpp>
43
44 #include <sys/time.h>
45
46 namespace RCF {
47 namespace detail {
48
49 class posix_event
50 : private noncopyable
51 {
52 public:
53 // Constructor.
54 RCF_EXPORT posix_event();
55
56 // Destructor.
57 ~posix_event()
58 {
59 ::pthread_cond_destroy(&cond_);
60 }
61
62 // Signal one waiting thread.
63 template <typename Lock>
64 void signal_one(Lock& lock)
65 {
66 BOOST_ASSERT(lock.locked());
67 (void)lock;
68 ::pthread_cond_signal(&cond_); // Ignore EINVAL.
69 }
70
71 // Signal all waiting threads.
72 template <typename Lock>
73 void signal_all(Lock& lock)
74 {
75 BOOST_ASSERT(lock.locked());
76 (void)lock;
77 ::pthread_cond_broadcast(&cond_); // Ignore EINVAL.
78 }
79
80 // Reset the event.
81 template <typename Lock>
82 void clear(Lock& lock)
83 {
84 BOOST_ASSERT(lock.locked());
85 (void)lock;
86 }
87
88 // Wait for the event to become signalled.
89 template <typename Lock>
90 void wait(Lock& lock)
91 {
92 // POSIX automatically unlocks and locks the mutex.
93
94 BOOST_ASSERT(lock.locked());
95 ::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL.
96 }
97
98 template <typename Lock>
99 bool timed_wait(Lock& lock, boost::uint32_t waitMs)
100 {
101 BOOST_ASSERT(lock.locked());
102
103 struct timeval tp = {0};
104 gettimeofday(&tp, NULL);
105
106 // Convert from timeval to timespec.
107 struct timespec ts = {0};
108 ts.tv_sec = tp.tv_sec;
109 ts.tv_nsec = tp.tv_usec * 1000;
110
111 // Add waitMs to current time.
112 ts.tv_sec += (waitMs / 1000);
113 boost::uint32_t remainderMs = waitMs % 1000;
114 ts.tv_nsec += (remainderMs * 1000 * 1000);
115
116 // Check for overflow in tv_nsec.
117 if (ts.tv_nsec >= 1000*1000*1000)
118 {
119 BOOST_ASSERT(ts.tv_nsec < 2*1000*1000*1000);
120 ts.tv_sec += 1;
121 ts.tv_nsec -= 1000*1000*1000;
122 }
123
124 // POSIX automatically unlocks and locks the mutex.
125
126 int ret = ::pthread_cond_timedwait(&cond_, &lock.mutex().mutex_, &ts); // Ignore EINVAL.
127 if (ret == ETIMEDOUT)
128 {
129 return false;
130 }
131
132 return true;
133 }
134
135 // Signal the event.
136 template <typename Lock>
137 void notify_all(Lock& lock)
138 {
139 signal_all(lock);
140 }
141
142 protected:
143 ::pthread_cond_t cond_;
144 };
145
146 } // namespace detail
147 } // namespace RCF
148
149 #include <RCF/thread/pop_options.hpp>
150
151
152 #endif // defined(BOOST_HAS_PTHREADS)
153
154 #endif // RCF_DETAIL_POSIX_EVENT_HPP