OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 12 matching lines...) Expand all Loading... |
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 */ | 28 */ |
29 | 29 |
30 #ifndef MessageQueue_h | 30 #ifndef MessageQueue_h |
31 #define MessageQueue_h | 31 #define MessageQueue_h |
32 | 32 |
| 33 #include <limits> |
33 #include <wtf/Assertions.h> | 34 #include <wtf/Assertions.h> |
34 #include <wtf/Deque.h> | 35 #include <wtf/Deque.h> |
35 #include <wtf/Noncopyable.h> | 36 #include <wtf/Noncopyable.h> |
36 #include <wtf/Threading.h> | 37 #include <wtf/Threading.h> |
37 | 38 |
38 namespace WTF { | 39 namespace WTF { |
39 | 40 |
40 enum MessageQueueWaitResult { | 41 enum MessageQueueWaitResult { |
41 MessageQueueTerminated, // Queue was destroyed while waiting for m
essage. | 42 MessageQueueTerminated, // Queue was destroyed while waiting for m
essage. |
42 MessageQueueTimeout, // Timeout was specified and it expired. | 43 MessageQueueTimeout, // Timeout was specified and it expired. |
43 MessageQueueMessageReceived, // A message was successfully received and
returned. | 44 MessageQueueMessageReceived, // A message was successfully received and
returned. |
44 }; | 45 }; |
45 | 46 |
46 template<typename DataType> | 47 template<typename DataType> |
47 class MessageQueue : Noncopyable { | 48 class MessageQueue : Noncopyable { |
48 public: | 49 public: |
49 MessageQueue() : m_killed(false) {} | 50 MessageQueue() : m_killed(false) {} |
50 | 51 |
51 void append(const DataType&); | 52 void append(const DataType&); |
52 void prepend(const DataType&); | 53 void prepend(const DataType&); |
53 bool waitForMessage(DataType&); | 54 bool waitForMessage(DataType&); |
54 template<typename Predicate> | 55 template<typename Predicate> |
55 MessageQueueWaitResult waitForMessageFiltered(DataType&, Predicate&); | 56 MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Pred
icate&, double absoluteTime); |
56 MessageQueueWaitResult waitForMessageTimed(DataType&, double absoluteTim
e); | |
57 void kill(); | 57 void kill(); |
58 | 58 |
59 bool tryGetMessage(DataType&); | 59 bool tryGetMessage(DataType&); |
60 bool killed() const; | 60 bool killed() const; |
61 | 61 |
62 // The result of isEmpty() is only valid if no other thread is manipulat
ing the queue at the same time. | 62 // The result of isEmpty() is only valid if no other thread is manipulat
ing the queue at the same time. |
63 bool isEmpty(); | 63 bool isEmpty(); |
64 | 64 |
| 65 static double infiniteTime() { return std::numeric_limits<double>::max()
; } |
| 66 |
65 private: | 67 private: |
| 68 static bool alwaysTruePredicate(DataType&) { return true; } |
| 69 |
66 mutable Mutex m_mutex; | 70 mutable Mutex m_mutex; |
67 ThreadCondition m_condition; | 71 ThreadCondition m_condition; |
68 Deque<DataType> m_queue; | 72 Deque<DataType> m_queue; |
69 bool m_killed; | 73 bool m_killed; |
70 }; | 74 }; |
71 | 75 |
72 template<typename DataType> | 76 template<typename DataType> |
73 inline void MessageQueue<DataType>::append(const DataType& message) | 77 inline void MessageQueue<DataType>::append(const DataType& message) |
74 { | 78 { |
75 MutexLocker lock(m_mutex); | 79 MutexLocker lock(m_mutex); |
76 m_queue.append(message); | 80 m_queue.append(message); |
77 m_condition.signal(); | 81 m_condition.signal(); |
78 } | 82 } |
79 | 83 |
80 template<typename DataType> | 84 template<typename DataType> |
81 inline void MessageQueue<DataType>::prepend(const DataType& message) | 85 inline void MessageQueue<DataType>::prepend(const DataType& message) |
82 { | 86 { |
83 MutexLocker lock(m_mutex); | 87 MutexLocker lock(m_mutex); |
84 m_queue.prepend(message); | 88 m_queue.prepend(message); |
85 m_condition.signal(); | 89 m_condition.signal(); |
86 } | 90 } |
87 | 91 |
88 template<typename DataType> | 92 template<typename DataType> |
89 inline bool MessageQueue<DataType>::waitForMessage(DataType& result) | 93 inline bool MessageQueue<DataType>::waitForMessage(DataType& result) |
90 { | 94 { |
91 MutexLocker lock(m_mutex); | 95 MessageQueueWaitResult exitReason = waitForMessageFilteredWithTimeout(re
sult, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime()); |
92 | 96 ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueu
eMessageReceived); |
93 while (!m_killed && m_queue.isEmpty()) | 97 return exitReason == MessageQueueMessageReceived; |
94 m_condition.wait(m_mutex); | |
95 | |
96 if (m_killed) | |
97 return false; | |
98 | |
99 ASSERT(!m_queue.isEmpty()); | |
100 result = m_queue.first(); | |
101 m_queue.removeFirst(); | |
102 return true; | |
103 } | 98 } |
104 | 99 |
105 template<typename DataType> | 100 template<typename DataType> |
106 template<typename Predicate> | 101 template<typename Predicate> |
107 inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFiltered
(DataType& result, Predicate& predicate) | 102 inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFiltered
WithTimeout(DataType& result, Predicate& predicate, double absoluteTime) |
108 { | 103 { |
109 MutexLocker lock(m_mutex); | 104 MutexLocker lock(m_mutex); |
| 105 bool timedOut = false; |
110 | 106 |
111 DequeConstIterator<DataType> found = m_queue.end(); | 107 DequeConstIterator<DataType> found = m_queue.end(); |
112 while (!m_killed && (found = m_queue.findIf(predicate)) == m_queue.end()
) | 108 while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) ==
m_queue.end()) |
113 m_condition.wait(m_mutex); | 109 timedOut = !m_condition.timedWait(m_mutex, absoluteTime); |
| 110 |
| 111 ASSERT(!timedOut || absoluteTime != infiniteTime()); |
114 | 112 |
115 if (m_killed) | 113 if (m_killed) |
116 return MessageQueueTerminated; | 114 return MessageQueueTerminated; |
117 | 115 |
| 116 if (timedOut) |
| 117 return MessageQueueTimeout; |
| 118 |
118 ASSERT(found != m_queue.end()); | 119 ASSERT(found != m_queue.end()); |
119 result = *found; | 120 result = *found; |
120 m_queue.remove(found); | 121 m_queue.remove(found); |
121 return MessageQueueMessageReceived; | 122 return MessageQueueMessageReceived; |
122 } | 123 } |
123 | 124 |
124 template<typename DataType> | |
125 inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageTimed(Da
taType& result, double absoluteTime) | |
126 { | |
127 MutexLocker lock(m_mutex); | |
128 bool timedOut = false; | |
129 | |
130 while (!m_killed && !timedOut && m_queue.isEmpty()) | |
131 timedOut = !m_condition.timedWait(m_mutex, absoluteTime); | |
132 | |
133 if (m_killed) | |
134 return MessageQueueTerminated; | |
135 | |
136 if (timedOut) | |
137 return MessageQueueTimeout; | |
138 | |
139 ASSERT(!m_queue.isEmpty()); | |
140 result = m_queue.first(); | |
141 m_queue.removeFirst(); | |
142 return MessageQueueMessageReceived; | |
143 } | |
144 | |
145 template<typename DataType> | 125 template<typename DataType> |
146 inline bool MessageQueue<DataType>::tryGetMessage(DataType& result) | 126 inline bool MessageQueue<DataType>::tryGetMessage(DataType& result) |
147 { | 127 { |
148 MutexLocker lock(m_mutex); | 128 MutexLocker lock(m_mutex); |
149 if (m_killed) | 129 if (m_killed) |
150 return false; | 130 return false; |
151 if (m_queue.isEmpty()) | 131 if (m_queue.isEmpty()) |
152 return false; | 132 return false; |
153 | 133 |
154 result = m_queue.first(); | 134 result = m_queue.first(); |
(...skipping 27 matching lines...) Expand all Loading... |
182 } // namespace WTF | 162 } // namespace WTF |
183 | 163 |
184 using WTF::MessageQueue; | 164 using WTF::MessageQueue; |
185 // MessageQueueWaitResult enum and all its values. | 165 // MessageQueueWaitResult enum and all its values. |
186 using WTF::MessageQueueWaitResult; | 166 using WTF::MessageQueueWaitResult; |
187 using WTF::MessageQueueTerminated; | 167 using WTF::MessageQueueTerminated; |
188 using WTF::MessageQueueTimeout; | 168 using WTF::MessageQueueTimeout; |
189 using WTF::MessageQueueMessageReceived; | 169 using WTF::MessageQueueMessageReceived; |
190 | 170 |
191 #endif // MessageQueue_h | 171 #endif // MessageQueue_h |
OLD | NEW |