| 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 |