2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef MessageQueue_h
30 #define MessageQueue_h
32 #include <wtf/Assertions.h>
33 #include <wtf/Deque.h>
34 #include <wtf/Noncopyable.h>
35 #include <wtf/Threading.h>
39 enum MessageQueueWaitResult
{
40 MessageQueueTerminated
, // Queue was destroyed while waiting for message.
41 MessageQueueTimeout
, // Timeout was specified and it expired.
42 MessageQueueMessageReceived
, // A message was successfully received and returned.
45 template<typename DataType
>
46 class MessageQueue
: Noncopyable
{
48 MessageQueue() : m_killed(false) {}
50 void append(const DataType
&);
51 void prepend(const DataType
&);
52 bool waitForMessage(DataType
&);
53 MessageQueueWaitResult
waitForMessageTimed(DataType
&, double absoluteTime
);
56 bool tryGetMessage(DataType
&);
59 // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
63 mutable Mutex m_mutex
;
64 ThreadCondition m_condition
;
65 Deque
<DataType
> m_queue
;
69 template<typename DataType
>
70 inline void MessageQueue
<DataType
>::append(const DataType
& message
)
72 MutexLocker
lock(m_mutex
);
73 m_queue
.append(message
);
77 template<typename DataType
>
78 inline void MessageQueue
<DataType
>::prepend(const DataType
& message
)
80 MutexLocker
lock(m_mutex
);
81 m_queue
.prepend(message
);
85 template<typename DataType
>
86 inline bool MessageQueue
<DataType
>::waitForMessage(DataType
& result
)
88 MutexLocker
lock(m_mutex
);
90 while (!m_killed
&& m_queue
.isEmpty())
91 m_condition
.wait(m_mutex
);
96 ASSERT(!m_queue
.isEmpty());
97 result
= m_queue
.first();
98 m_queue
.removeFirst();
102 template<typename DataType
>
103 inline MessageQueueWaitResult MessageQueue
<DataType
>::waitForMessageTimed(DataType
& result
, double absoluteTime
)
105 MutexLocker
lock(m_mutex
);
106 bool timedOut
= false;
108 while (!m_killed
&& !timedOut
&& m_queue
.isEmpty())
109 timedOut
= !m_condition
.timedWait(m_mutex
, absoluteTime
);
112 return MessageQueueTerminated
;
115 return MessageQueueTimeout
;
117 ASSERT(!m_queue
.isEmpty());
118 result
= m_queue
.first();
119 m_queue
.removeFirst();
120 return MessageQueueMessageReceived
;
123 template<typename DataType
>
124 inline bool MessageQueue
<DataType
>::tryGetMessage(DataType
& result
)
126 MutexLocker
lock(m_mutex
);
129 if (m_queue
.isEmpty())
132 result
= m_queue
.first();
133 m_queue
.removeFirst();
137 template<typename DataType
>
138 inline bool MessageQueue
<DataType
>::isEmpty()
140 MutexLocker
lock(m_mutex
);
143 return m_queue
.isEmpty();
146 template<typename DataType
>
147 inline void MessageQueue
<DataType
>::kill()
149 MutexLocker
lock(m_mutex
);
151 m_condition
.broadcast();
154 template<typename DataType
>
155 inline bool MessageQueue
<DataType
>::killed() const
157 MutexLocker
lock(m_mutex
);
162 using WTF::MessageQueue
;
163 // MessageQueueWaitResult enum and all its values.
164 using WTF::MessageQueueWaitResult
;
165 using WTF::MessageQueueTerminated
;
166 using WTF::MessageQueueTimeout
;
167 using WTF::MessageQueueMessageReceived
;
169 #endif // MessageQueue_h