Chromium Code Reviews| 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 |