OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/shared_impl/tracked_callback.h" | 5 #include "ppapi/shared_impl/tracked_callback.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 // Wait()s. | 121 // Wait()s. |
122 operation_completed_condvar_->Signal(); | 122 operation_completed_condvar_->Signal(); |
123 } else { | 123 } else { |
124 // If there's a target_loop_, and we're not on the right thread, we need to | 124 // If there's a target_loop_, and we're not on the right thread, we need to |
125 // post to target_loop_. | 125 // post to target_loop_. |
126 if (target_loop_.get() && | 126 if (target_loop_.get() && |
127 target_loop_.get() != PpapiGlobals::Get()->GetCurrentMessageLoop()) { | 127 target_loop_.get() != PpapiGlobals::Get()->GetCurrentMessageLoop()) { |
128 PostRun(result); | 128 PostRun(result); |
129 return; | 129 return; |
130 } | 130 } |
131 | |
132 result = RunCompletionTask(result); | |
yzshen1
2013/08/07 21:09:10
One thing that may be tricky is that this completi
dmichael (off chromium)
2013/08/08 17:29:58
I think the answer is "don't do that". The complet
bbudge
2013/08/08 18:34:00
I moved the task invocation to after MarkAsComplet
| |
133 | |
131 // Copy |callback_| now, since |MarkAsCompleted()| may delete us. | 134 // Copy |callback_| now, since |MarkAsCompleted()| may delete us. |
132 PP_CompletionCallback callback = callback_; | 135 PP_CompletionCallback callback = callback_; |
133 // Do this before running the callback in case of reentrancy (which | 136 // Do this before running the callback in case of reentrancy (which |
134 // shouldn't happen, but avoid strange failures). | 137 // shouldn't happen, but avoid strange failures). |
135 MarkAsCompleted(); | 138 MarkAsCompleted(); |
136 // TODO(dmichael): Associate a message loop with the callback; if it's not | 139 // TODO(dmichael): Associate a message loop with the callback; if it's not |
137 // the same as the current thread's loop, then post it to the right loop. | 140 // the same as the current thread's loop, then post it to the right loop. |
138 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); | 141 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); |
139 } | 142 } |
140 } | 143 } |
(...skipping 16 matching lines...) Expand all Loading... | |
157 // classes protect against having a null target_loop_ otherwise). | 160 // classes protect against having a null target_loop_ otherwise). |
158 DCHECK(IsMainThread()); | 161 DCHECK(IsMainThread()); |
159 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); | 162 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); |
160 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); | 163 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); |
161 } else { | 164 } else { |
162 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); | 165 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); |
163 } | 166 } |
164 is_scheduled_ = true; | 167 is_scheduled_ = true; |
165 } | 168 } |
166 | 169 |
170 void TrackedCallback::SetCompletionTask(const CompletionTask& completion_task) { | |
171 DCHECK(completion_task_.is_null()); | |
172 completion_task_ = completion_task; | |
173 } | |
174 | |
167 // static | 175 // static |
168 bool TrackedCallback::IsPending( | 176 bool TrackedCallback::IsPending( |
169 const scoped_refptr<TrackedCallback>& callback) { | 177 const scoped_refptr<TrackedCallback>& callback) { |
170 if (!callback.get()) | 178 if (!callback.get()) |
171 return false; | 179 return false; |
172 if (callback->aborted()) | 180 if (callback->aborted()) |
173 return false; | 181 return false; |
174 return !callback->completed(); | 182 return !callback->completed(); |
175 } | 183 } |
176 | 184 |
(...skipping 11 matching lines...) Expand all Loading... | |
188 // BlockUntilComplete should never be called for in-process plugins, where | 196 // BlockUntilComplete should never be called for in-process plugins, where |
189 // blocking callbacks are not supported. | 197 // blocking callbacks are not supported. |
190 CHECK(operation_completed_condvar_.get()); | 198 CHECK(operation_completed_condvar_.get()); |
191 if (!is_blocking() || !operation_completed_condvar_.get()) { | 199 if (!is_blocking() || !operation_completed_condvar_.get()) { |
192 NOTREACHED(); | 200 NOTREACHED(); |
193 return PP_ERROR_FAILED; | 201 return PP_ERROR_FAILED; |
194 } | 202 } |
195 | 203 |
196 while (!completed()) | 204 while (!completed()) |
197 operation_completed_condvar_->Wait(); | 205 operation_completed_condvar_->Wait(); |
198 return result_for_blocked_callback_; | 206 |
207 return RunCompletionTask(result_for_blocked_callback_); | |
199 } | 208 } |
200 | 209 |
201 void TrackedCallback::MarkAsCompleted() { | 210 void TrackedCallback::MarkAsCompleted() { |
202 DCHECK(!completed()); | 211 DCHECK(!completed()); |
203 | 212 |
204 // We will be removed; maintain a reference to ensure we won't be deleted | 213 // We will be removed; maintain a reference to ensure we won't be deleted |
205 // until we're done. | 214 // until we're done. |
206 scoped_refptr<TrackedCallback> thiz = this; | 215 scoped_refptr<TrackedCallback> thiz = this; |
207 completed_ = true; | 216 completed_ = true; |
208 // We may not have a valid resource, in which case we're not in the tracker. | 217 // We may not have a valid resource, in which case we're not in the tracker. |
209 if (resource_id_) | 218 if (resource_id_) |
210 tracker_->Remove(thiz); | 219 tracker_->Remove(thiz); |
211 tracker_ = NULL; | 220 tracker_ = NULL; |
212 } | 221 } |
213 | 222 |
223 int32_t TrackedCallback::RunCompletionTask(int32_t result) { | |
224 if (!completion_task_.is_null()) | |
225 result = completion_task_.Run(result); | |
226 return result; | |
teravest
2013/08/08 16:49:52
nit: I think you want to call completion_task_.Res
bbudge
2013/08/08 18:34:00
Yes, good catch. Another danger is if the task bun
| |
227 } | |
228 | |
214 } // namespace ppapi | 229 } // namespace ppapi |
OLD | NEW |