X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9bcd318d5fa2a38139c9651d263a06c797529333..ba379fdc102753d6be2c4d937058fe40257329fe:/wtf/MessageQueue.h?ds=sidebyside diff --git a/wtf/MessageQueue.h b/wtf/MessageQueue.h index 19c5c10..7721dba 100644 --- a/wtf/MessageQueue.h +++ b/wtf/MessageQueue.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,6 +30,7 @@ #ifndef MessageQueue_h #define MessageQueue_h +#include <limits> #include <wtf/Assertions.h> #include <wtf/Deque.h> #include <wtf/Noncopyable.h> @@ -45,12 +47,14 @@ namespace WTF { template<typename DataType> class MessageQueue : Noncopyable { public: - MessageQueue() : m_killed(false) {} + MessageQueue() : m_killed(false) { } void append(const DataType&); + bool appendAndCheckEmpty(const DataType&); void prepend(const DataType&); bool waitForMessage(DataType&); - MessageQueueWaitResult waitForMessageTimed(DataType&, double absoluteTime); + template<typename Predicate> + MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime); void kill(); bool tryGetMessage(DataType&); @@ -59,7 +63,11 @@ namespace WTF { // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time. bool isEmpty(); + static double infiniteTime() { return std::numeric_limits<double>::max(); } + private: + static bool alwaysTruePredicate(DataType&) { return true; } + mutable Mutex m_mutex; ThreadCondition m_condition; Deque<DataType> m_queue; @@ -74,6 +82,17 @@ namespace WTF { m_condition.signal(); } + // Returns true if the queue was empty before the item was added. + template<typename DataType> + inline bool MessageQueue<DataType>::appendAndCheckEmpty(const DataType& message) + { + MutexLocker lock(m_mutex); + bool wasEmpty = m_queue.isEmpty(); + m_queue.append(message); + m_condition.signal(); + return wasEmpty; + } + template<typename DataType> inline void MessageQueue<DataType>::prepend(const DataType& message) { @@ -85,38 +104,33 @@ namespace WTF { template<typename DataType> inline bool MessageQueue<DataType>::waitForMessage(DataType& result) { - MutexLocker lock(m_mutex); - - while (!m_killed && m_queue.isEmpty()) - m_condition.wait(m_mutex); - - if (m_killed) - return false; - - ASSERT(!m_queue.isEmpty()); - result = m_queue.first(); - m_queue.removeFirst(); - return true; + MessageQueueWaitResult exitReason = waitForMessageFilteredWithTimeout(result, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime()); + ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived); + return exitReason == MessageQueueMessageReceived; } template<typename DataType> - inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageTimed(DataType& result, double absoluteTime) + template<typename Predicate> + inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFilteredWithTimeout(DataType& result, Predicate& predicate, double absoluteTime) { MutexLocker lock(m_mutex); bool timedOut = false; - while (!m_killed && !timedOut && m_queue.isEmpty()) + DequeConstIterator<DataType> found = m_queue.end(); + while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end()) timedOut = !m_condition.timedWait(m_mutex, absoluteTime); + ASSERT(!timedOut || absoluteTime != infiniteTime()); + if (m_killed) return MessageQueueTerminated; if (timedOut) return MessageQueueTimeout; - ASSERT(!m_queue.isEmpty()); - result = m_queue.first(); - m_queue.removeFirst(); + ASSERT(found != m_queue.end()); + result = *found; + m_queue.remove(found); return MessageQueueMessageReceived; } @@ -157,7 +171,7 @@ namespace WTF { MutexLocker lock(m_mutex); return m_killed; } -} +} // namespace WTF using WTF::MessageQueue; // MessageQueueWaitResult enum and all its values.