Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: Source/WTF/wtf/MessageQueue.h

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef MessageQueue_h
31 #define MessageQueue_h
32
33 #include <limits>
34 #include <wtf/Assertions.h>
35 #include <wtf/Deque.h>
36 #include <wtf/Noncopyable.h>
37 #include <wtf/Threading.h>
38
39 namespace WTF {
40
41 enum MessageQueueWaitResult {
42 MessageQueueTerminated, // Queue was destroyed while waiting for m essage.
43 MessageQueueTimeout, // Timeout was specified and it expired.
44 MessageQueueMessageReceived // A message was successfully received and returned.
45 };
46
47 // The queue takes ownership of messages and transfer it to the new owner
48 // when messages are fetched from the queue.
49 // Essentially, MessageQueue acts as a queue of OwnPtr<DataType>.
50 template<typename DataType>
51 class MessageQueue {
52 WTF_MAKE_NONCOPYABLE(MessageQueue);
53 public:
54 MessageQueue() : m_killed(false) { }
55 ~MessageQueue();
56
57 void append(PassOwnPtr<DataType>);
58 void appendAndKill(PassOwnPtr<DataType>);
59 bool appendAndCheckEmpty(PassOwnPtr<DataType>);
60 void prepend(PassOwnPtr<DataType>);
61
62 PassOwnPtr<DataType> waitForMessage();
63 PassOwnPtr<DataType> tryGetMessage();
64 PassOwnPtr<DataType> tryGetMessageIgnoringKilled();
65 template<typename Predicate>
66 PassOwnPtr<DataType> waitForMessageFilteredWithTimeout(MessageQueueWaitR esult&, Predicate&, double absoluteTime);
67
68 template<typename Predicate>
69 void removeIf(Predicate&);
70
71 void kill();
72 bool killed() const;
73
74 // The result of isEmpty() is only valid if no other thread is manipulat ing the queue at the same time.
75 bool isEmpty();
76
77 static double infiniteTime() { return std::numeric_limits<double>::max() ; }
78
79 private:
80 static bool alwaysTruePredicate(DataType*) { return true; }
81
82 mutable Mutex m_mutex;
83 ThreadCondition m_condition;
84 Deque<DataType*> m_queue;
85 bool m_killed;
86 };
87
88 template<typename DataType>
89 MessageQueue<DataType>::~MessageQueue()
90 {
91 deleteAllValues(m_queue);
92 }
93
94 template<typename DataType>
95 inline void MessageQueue<DataType>::append(PassOwnPtr<DataType> message)
96 {
97 MutexLocker lock(m_mutex);
98 m_queue.append(message.leakPtr());
99 m_condition.signal();
100 }
101
102 template<typename DataType>
103 inline void MessageQueue<DataType>::appendAndKill(PassOwnPtr<DataType> messa ge)
104 {
105 MutexLocker lock(m_mutex);
106 m_queue.append(message.leakPtr());
107 m_killed = true;
108 m_condition.broadcast();
109 }
110
111 // Returns true if the queue was empty before the item was added.
112 template<typename DataType>
113 inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message)
114 {
115 MutexLocker lock(m_mutex);
116 bool wasEmpty = m_queue.isEmpty();
117 m_queue.append(message.leakPtr());
118 m_condition.signal();
119 return wasEmpty;
120 }
121
122 template<typename DataType>
123 inline void MessageQueue<DataType>::prepend(PassOwnPtr<DataType> message)
124 {
125 MutexLocker lock(m_mutex);
126 m_queue.prepend(message.leakPtr());
127 m_condition.signal();
128 }
129
130 template<typename DataType>
131 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessage()
132 {
133 MessageQueueWaitResult exitReason;
134 OwnPtr<DataType> result = waitForMessageFilteredWithTimeout(exitReason, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
135 ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueu eMessageReceived);
136 return result.release();
137 }
138
139 template<typename DataType>
140 template<typename Predicate>
141 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessageFilteredWi thTimeout(MessageQueueWaitResult& result, Predicate& predicate, double absoluteT ime)
142 {
143 MutexLocker lock(m_mutex);
144 bool timedOut = false;
145
146 DequeConstIterator<DataType*> found = m_queue.end();
147 while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end())
148 timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
149
150 ASSERT(!timedOut || absoluteTime != infiniteTime());
151
152 if (m_killed) {
153 result = MessageQueueTerminated;
154 return nullptr;
155 }
156
157 if (timedOut) {
158 result = MessageQueueTimeout;
159 return nullptr;
160 }
161
162 ASSERT(found != m_queue.end());
163 OwnPtr<DataType> message = adoptPtr(*found);
164 m_queue.remove(found);
165 result = MessageQueueMessageReceived;
166 return message.release();
167 }
168
169 template<typename DataType>
170 inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessage()
171 {
172 MutexLocker lock(m_mutex);
173 if (m_killed)
174 return nullptr;
175 if (m_queue.isEmpty())
176 return nullptr;
177
178 return adoptPtr(m_queue.takeFirst());
179 }
180
181 template<typename DataType>
182 inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessageIgnoringKil led()
183 {
184 MutexLocker lock(m_mutex);
185 if (m_queue.isEmpty())
186 return nullptr;
187
188 return adoptPtr(m_queue.takeFirst());
189 }
190
191 template<typename DataType>
192 template<typename Predicate>
193 inline void MessageQueue<DataType>::removeIf(Predicate& predicate)
194 {
195 MutexLocker lock(m_mutex);
196 DequeConstIterator<DataType*> found = m_queue.end();
197 while ((found = m_queue.findIf(predicate)) != m_queue.end()) {
198 DataType* message = *found;
199 m_queue.remove(found);
200 delete message;
201 }
202 }
203
204 template<typename DataType>
205 inline bool MessageQueue<DataType>::isEmpty()
206 {
207 MutexLocker lock(m_mutex);
208 if (m_killed)
209 return true;
210 return m_queue.isEmpty();
211 }
212
213 template<typename DataType>
214 inline void MessageQueue<DataType>::kill()
215 {
216 MutexLocker lock(m_mutex);
217 m_killed = true;
218 m_condition.broadcast();
219 }
220
221 template<typename DataType>
222 inline bool MessageQueue<DataType>::killed() const
223 {
224 MutexLocker lock(m_mutex);
225 return m_killed;
226 }
227 } // namespace WTF
228
229 using WTF::MessageQueue;
230 // MessageQueueWaitResult enum and all its values.
231 using WTF::MessageQueueWaitResult;
232 using WTF::MessageQueueTerminated;
233 using WTF::MessageQueueTimeout;
234 using WTF::MessageQueueMessageReceived;
235
236 #endif // MessageQueue_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698