2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 #ifndef MessageQueue_h
31 #define MessageQueue_h
34 #include "wtf/Assertions.h"
35 #include "wtf/Deque.h"
36 #include "wtf/Noncopyable.h"
37 #include "wtf/PassOwnPtr.h"
38 #include "wtf/ThreadingPrimitives.h"
42 enum MessageQueueWaitResult {
43 MessageQueueTerminated, // Queue was destroyed while waiting for message.
44 MessageQueueTimeout, // Timeout was specified and it expired.
45 MessageQueueMessageReceived // A message was successfully received and returned.
48 // The queue takes ownership of messages and transfer it to the new owner
49 // when messages are fetched from the queue.
50 // Essentially, MessageQueue acts as a queue of OwnPtr<DataType>.
51 template<typename DataType>
53 WTF_MAKE_NONCOPYABLE(MessageQueue);
55 MessageQueue() : m_killed(false) { }
58 // Returns true if the queue is still alive, false if the queue has been killed.
59 bool append(PassOwnPtr<DataType>);
60 void appendAndKill(PassOwnPtr<DataType>);
61 bool appendAndCheckEmpty(PassOwnPtr<DataType>);
62 void prepend(PassOwnPtr<DataType>);
64 PassOwnPtr<DataType> waitForMessage();
65 PassOwnPtr<DataType> tryGetMessage();
66 PassOwnPtr<DataType> tryGetMessageIgnoringKilled();
67 PassOwnPtr<DataType> waitForMessageWithTimeout(MessageQueueWaitResult&, double absoluteTime);
72 // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
75 static double infiniteTime() { return std::numeric_limits<double>::max(); }
78 mutable Mutex m_mutex;
79 ThreadCondition m_condition;
80 Deque<DataType*> m_queue;
84 template<typename DataType>
85 MessageQueue<DataType>::~MessageQueue()
87 deleteAllValues(m_queue);
90 template<typename DataType>
91 inline bool MessageQueue<DataType>::append(PassOwnPtr<DataType> message)
93 MutexLocker lock(m_mutex);
94 m_queue.append(message.leakPtr());
99 template<typename DataType>
100 inline void MessageQueue<DataType>::appendAndKill(PassOwnPtr<DataType> message)
102 MutexLocker lock(m_mutex);
103 m_queue.append(message.leakPtr());
105 m_condition.broadcast();
108 // Returns true if the queue was empty before the item was added.
109 template<typename DataType>
110 inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message)
112 MutexLocker lock(m_mutex);
113 bool wasEmpty = m_queue.isEmpty();
114 m_queue.append(message.leakPtr());
115 m_condition.signal();
119 template<typename DataType>
120 inline void MessageQueue<DataType>::prepend(PassOwnPtr<DataType> message)
122 MutexLocker lock(m_mutex);
123 m_queue.prepend(message.leakPtr());
124 m_condition.signal();
127 template<typename DataType>
128 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessage()
130 MessageQueueWaitResult exitReason;
131 OwnPtr<DataType> result = waitForMessageWithTimeout(exitReason, infiniteTime());
132 ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived);
133 return result.release();
136 template<typename DataType>
137 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessageWithTimeout(MessageQueueWaitResult& result, double absoluteTime)
139 MutexLocker lock(m_mutex);
140 bool timedOut = false;
142 while (!m_killed && !timedOut && m_queue.isEmpty())
143 timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
145 ASSERT(!timedOut || absoluteTime != infiniteTime());
148 result = MessageQueueTerminated;
153 result = MessageQueueTimeout;
157 DequeConstIterator<DataType*> found = m_queue.begin();
159 ASSERT_WITH_SECURITY_IMPLICATION(found != m_queue.end());
160 OwnPtr<DataType> message = adoptPtr(*found);
161 m_queue.remove(found);
162 result = MessageQueueMessageReceived;
163 return message.release();
166 template<typename DataType>
167 inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessage()
169 MutexLocker lock(m_mutex);
172 if (m_queue.isEmpty())
175 return adoptPtr(m_queue.takeFirst());
178 template<typename DataType>
179 inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessageIgnoringKilled()
181 MutexLocker lock(m_mutex);
182 if (m_queue.isEmpty())
185 return adoptPtr(m_queue.takeFirst());
188 template<typename DataType>
189 inline bool MessageQueue<DataType>::isEmpty()
191 MutexLocker lock(m_mutex);
194 return m_queue.isEmpty();
197 template<typename DataType>
198 inline void MessageQueue<DataType>::kill()
200 MutexLocker lock(m_mutex);
202 m_condition.broadcast();
205 template<typename DataType>
206 inline bool MessageQueue<DataType>::killed() const
208 MutexLocker lock(m_mutex);
213 using WTF::MessageQueue;
214 // MessageQueueWaitResult enum and all its values.
215 using WTF::MessageQueueWaitResult;
216 using WTF::MessageQueueTerminated;
217 using WTF::MessageQueueTimeout;
218 using WTF::MessageQueueMessageReceived;
220 #endif // MessageQueue_h