source: webkit/trunk/JavaScriptCore/wtf/MessageQueue.h@ 65104

Last change on this file since 65104 was 62551, checked in by Darin Adler, 15 years ago

2010-07-06 Darin Adler <Darin Adler>

Reviewed by Adam Barth.

Add adoptPtr and leakPtr functions for OwnPtr and PassOwnPtr
https://bugs.webkit.org/show_bug.cgi?id=41320

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): Use assignment instead of set since the result of reparseExceptionInfo is now a PassOwnPtr.
  • bytecode/CodeBlock.h: Change extractExceptionInfo to return a PassOwnPtr instead of a raw pointer.
  • runtime/Executable.cpp: (JSC::FunctionExecutable::reparseExceptionInfo): Return a PassOwnPtr. (JSC::EvalExecutable::reparseExceptionInfo): Ditto. (JSC::ProgramExecutable::reparseExceptionInfo): Added. This was in the header before, but it's better to not have it there to reduce header dependencies. Return a PassOwnPtr.
  • runtime/Executable.h: Made reparseExceptionInfo return a PassOwnPtr, and put it in the private sections of classes other than the base class.
  • wtf/MessageQueue.h: (WTF::MessageQueue::append): Use leakPtr instead of release. (WTF::MessageQueue::appendAndCheckEmpty): Ditto. (WTF::MessageQueue::prepend): Ditto.
  • wtf/OwnPtr.h: Tweaked formatting. Changed the release function to return a PassOwnPtr rather than a raw pointer. Added a leakPtr function that returns a raw pointer. Put the constructor that takes a raw pointer and the set function into a section guarded by LOOSE_OWN_PTR. Adapted to the new adoptPtr function from PassOwnPtr.h.
  • wtf/PassOwnPtr.h: Tweaked formatting. Renamed the release function to leakPtr. Added an adoptPtr function that creates a new PassOwnPtr. Put the constructor and assignment operators that take a raw pointer into a section guarded by LOOSE_PASS_OWN_PTR.

2010-07-06 Darin Adler <Darin Adler>

Reviewed by Adam Barth.

Add adoptPtr and leakPtr functions for OwnPtr and PassOwnPtr
https://bugs.webkit.org/show_bug.cgi?id=41320

Made code changes required because of the change to the release function.
The equivalent to the old release function is now named leakPtr and
should be used sparingly. The new release function returns a PassOwnPtr.

  • css/CSSFontFaceSource.cpp: (WebCore::CSSFontFaceSource::getFontData): Changed code to call leakPtr instead of release.
  • css/CSSParser.cpp: (WebCore::CSSParser::addProperty): Ditto.
  • css/CSSSegmentedFontFace.cpp: (WebCore::CSSSegmentedFontFace::getFontData): Removed unneeded type casting. Not sure why this changed the type to FontData* and then casted back to SimpleFontData*.
  • css/MediaQuery.cpp: (WebCore::MediaQuery::MediaQuery): Removed call to release on a PassOwnPtr, since the data member is now an OwnPtr. (WebCore::MediaQuery::~MediaQuery): Removed now-unneeded delete.
  • css/MediaQuery.h: Changed m_expressions to be an OwnPtr.
  • html/HTMLToken.h: (WebCore::AtomicHTMLToken::AtomicHTMLToken): Use assignment instead of the set function since there are no raw pointers involved.
  • loader/CachedResource.cpp: (WebCore::CachedResource::makePurgeable): Ditto.
  • loader/CrossOriginPreflightResultCache.cpp: (WebCore::CrossOriginPreflightResultCache::appendEntry): Use leakPtr instead of release, and also add FIXME about deleting the old value if the original and URL are already in the map. I believe dealing with this FIXME may fix a storage leak.
  • loader/CrossOriginPreflightResultCache.h: Change the argument to be PassOwnPtr instead of a raw pointer, since this function does take ownership.
  • loader/DocumentThreadableLoader.cpp: (WebCore::DocumentThreadableLoader::DocumentThreadableLoader): Use assignment instead of the set function since there are no raw pointers involved.
  • loader/FrameLoader.cpp: (WebCore::FrameLoader::startIconLoader): Ditto.
  • loader/TextResourceDecoder.cpp: (WebCore::TextResourceDecoder::decode): Ditto. (WebCore::TextResourceDecoder::flush): Ditto.
  • page/DOMTimer.cpp: (WebCore::DOMTimer::fired): Use OwnPtr instead of an explicit delete.
  • platform/CrossThreadCopier.h: Removed explicit code that tried to copy PassOwnPtr in a complicated way. It did nothing different from just returning the PassOwnPtr. This presumably was done because PassRefPtr has issues when copied cross-thread, but there are no similar issues for PassOwnPtr. Someone with more experience than I might be able to remove the specialization altogether, because CrossThreadCopierPassThrough does the right thing in this case.
  • platform/SharedBuffer.cpp: (WebCore::SharedBuffer::adoptPurgeableBuffer): Changed argument to be a PassOwnPtr. (WebCore::SharedBuffer::releasePurgeableBuffer): Changed result to be a PassOwnPtr.
  • platform/SharedBuffer.h: Updated for changes above.
  • rendering/RenderSVGResourceFilter.cpp: (WebCore::RenderSVGResourceFilter::applyResource): Changed one site to use assignment instead of the set function since there are no raw pointers involved. Changed another site to use leakPtr instead of release.
  • rendering/RenderSVGResourceGradient.cpp: (WebCore::createMaskAndSwapContextForTextGradient): Use assignment instead of the set function since there are no raw pointers involved.
  • rendering/style/RenderStyle.cpp: (WebCore::RenderStyle::setContent): Use leakPtr instead of release. (WebCore::RenderStyle::setBoxShadow): Ditto.
  • workers/DefaultSharedWorkerRepository.cpp: (WebCore::DefaultSharedWorkerRepository::connectToWorker): Removed unneeded call to release function in a code path that passes a PassOwnPtr to a function that takes a PassOwnPtr.
  • workers/WorkerContext.cpp: (WebCore::WorkerContext::setTimeout): Changed argument type to PassOwnPtr. (WebCore::WorkerContext::setInterval): Ditto.
  • workers/WorkerContext.h: Updated for changes above.
  • workers/WorkerMessagingProxy.cpp: (WebCore::WorkerMessagingProxy::postMessageToWorkerObject): (WebCore::WorkerMessagingProxy::postMessageToWorkerContext): Removed unneeded call to release function in code paths that pass a PassOwnPtr to a function that takes a PassOwnPtr.
  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
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
39namespace WTF {
40
41 enum MessageQueueWaitResult {
42 MessageQueueTerminated, // Queue was destroyed while waiting for message.
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 : public Noncopyable {
52 public:
53 MessageQueue() : m_killed(false) { }
54 ~MessageQueue();
55
56 void append(PassOwnPtr<DataType>);
57 bool appendAndCheckEmpty(PassOwnPtr<DataType>);
58 void prepend(PassOwnPtr<DataType>);
59
60 PassOwnPtr<DataType> waitForMessage();
61 PassOwnPtr<DataType> tryGetMessage();
62 template<typename Predicate>
63 PassOwnPtr<DataType> waitForMessageFilteredWithTimeout(MessageQueueWaitResult&, Predicate&, double absoluteTime);
64
65 template<typename Predicate>
66 void removeIf(Predicate&);
67
68 void kill();
69 bool killed() const;
70
71 // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
72 bool isEmpty();
73
74 static double infiniteTime() { return std::numeric_limits<double>::max(); }
75
76 private:
77 static bool alwaysTruePredicate(DataType*) { return true; }
78
79 mutable Mutex m_mutex;
80 ThreadCondition m_condition;
81 Deque<DataType*> m_queue;
82 bool m_killed;
83 };
84
85 template<typename DataType>
86 MessageQueue<DataType>::~MessageQueue()
87 {
88 deleteAllValues(m_queue);
89 }
90
91 template<typename DataType>
92 inline void MessageQueue<DataType>::append(PassOwnPtr<DataType> message)
93 {
94 MutexLocker lock(m_mutex);
95 m_queue.append(message.leakPtr());
96 m_condition.signal();
97 }
98
99 // Returns true if the queue was empty before the item was added.
100 template<typename DataType>
101 inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message)
102 {
103 MutexLocker lock(m_mutex);
104 bool wasEmpty = m_queue.isEmpty();
105 m_queue.append(message.leakPtr());
106 m_condition.signal();
107 return wasEmpty;
108 }
109
110 template<typename DataType>
111 inline void MessageQueue<DataType>::prepend(PassOwnPtr<DataType> message)
112 {
113 MutexLocker lock(m_mutex);
114 m_queue.prepend(message.leakPtr());
115 m_condition.signal();
116 }
117
118 template<typename DataType>
119 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessage()
120 {
121 MessageQueueWaitResult exitReason;
122 PassOwnPtr<DataType> result = waitForMessageFilteredWithTimeout(exitReason, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
123 ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived);
124 return result;
125 }
126
127 template<typename DataType>
128 template<typename Predicate>
129 inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessageFilteredWithTimeout(MessageQueueWaitResult& result, Predicate& predicate, double absoluteTime)
130 {
131 MutexLocker lock(m_mutex);
132 bool timedOut = false;
133
134 DequeConstIterator<DataType*> found = m_queue.end();
135 while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end())
136 timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
137
138 ASSERT(!timedOut || absoluteTime != infiniteTime());
139
140 if (m_killed) {
141 result = MessageQueueTerminated;
142 return 0;
143 }
144
145 if (timedOut) {
146 result = MessageQueueTimeout;
147 return 0;
148 }
149
150 ASSERT(found != m_queue.end());
151 DataType* message = *found;
152 m_queue.remove(found);
153 result = MessageQueueMessageReceived;
154 return message;
155 }
156
157 template<typename DataType>
158 inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessage()
159 {
160 MutexLocker lock(m_mutex);
161 if (m_killed)
162 return 0;
163 if (m_queue.isEmpty())
164 return 0;
165
166 return m_queue.takeFirst();
167 }
168
169 template<typename DataType>
170 template<typename Predicate>
171 inline void MessageQueue<DataType>::removeIf(Predicate& predicate)
172 {
173 MutexLocker lock(m_mutex);
174 // See bug 31657 for why this loop looks so weird
175 while (true) {
176 DequeConstIterator<DataType*> found = m_queue.findIf(predicate);
177 if (found == m_queue.end())
178 break;
179
180 DataType* message = *found;
181 m_queue.remove(found);
182 delete message;
183 }
184 }
185
186 template<typename DataType>
187 inline bool MessageQueue<DataType>::isEmpty()
188 {
189 MutexLocker lock(m_mutex);
190 if (m_killed)
191 return true;
192 return m_queue.isEmpty();
193 }
194
195 template<typename DataType>
196 inline void MessageQueue<DataType>::kill()
197 {
198 MutexLocker lock(m_mutex);
199 m_killed = true;
200 m_condition.broadcast();
201 }
202
203 template<typename DataType>
204 inline bool MessageQueue<DataType>::killed() const
205 {
206 MutexLocker lock(m_mutex);
207 return m_killed;
208 }
209} // namespace WTF
210
211using WTF::MessageQueue;
212// MessageQueueWaitResult enum and all its values.
213using WTF::MessageQueueWaitResult;
214using WTF::MessageQueueTerminated;
215using WTF::MessageQueueTimeout;
216using WTF::MessageQueueMessageReceived;
217
218#endif // MessageQueue_h
Note: See TracBrowser for help on using the repository browser.