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 // Copy |callback_| now, since |MarkAsCompleted()| may delete us. | 131 |
| 132 // Copy callback fields now, since |MarkAsCompleted()| may delete us. |
132 PP_CompletionCallback callback = callback_; | 133 PP_CompletionCallback callback = callback_; |
| 134 CompletionTask completion_task = completion_task_; |
| 135 completion_task_.Reset(); |
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(); |
| 139 |
| 140 if (!completion_task.is_null()) |
| 141 result = completion_task.Run(result); |
| 142 |
136 // TODO(dmichael): Associate a message loop with the callback; if it's not | 143 // 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. | 144 // the same as the current thread's loop, then post it to the right loop. |
138 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); | 145 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); |
139 } | 146 } |
140 } | 147 } |
141 | 148 |
142 void TrackedCallback::PostRun(int32_t result) { | 149 void TrackedCallback::PostRun(int32_t result) { |
143 if (completed()) { | 150 if (completed()) { |
144 NOTREACHED(); | 151 NOTREACHED(); |
145 return; | 152 return; |
(...skipping 11 matching lines...) Expand all Loading... |
157 // classes protect against having a null target_loop_ otherwise). | 164 // classes protect against having a null target_loop_ otherwise). |
158 DCHECK(IsMainThread()); | 165 DCHECK(IsMainThread()); |
159 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); | 166 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); |
160 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); | 167 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); |
161 } else { | 168 } else { |
162 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); | 169 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); |
163 } | 170 } |
164 is_scheduled_ = true; | 171 is_scheduled_ = true; |
165 } | 172 } |
166 | 173 |
| 174 void TrackedCallback::set_completion_task( |
| 175 const CompletionTask& completion_task) { |
| 176 DCHECK(completion_task_.is_null()); |
| 177 completion_task_ = completion_task; |
| 178 } |
| 179 |
167 // static | 180 // static |
168 bool TrackedCallback::IsPending( | 181 bool TrackedCallback::IsPending( |
169 const scoped_refptr<TrackedCallback>& callback) { | 182 const scoped_refptr<TrackedCallback>& callback) { |
170 if (!callback.get()) | 183 if (!callback.get()) |
171 return false; | 184 return false; |
172 if (callback->aborted()) | 185 if (callback->aborted()) |
173 return false; | 186 return false; |
174 return !callback->completed(); | 187 return !callback->completed(); |
175 } | 188 } |
176 | 189 |
(...skipping 11 matching lines...) Expand all Loading... |
188 // BlockUntilComplete should never be called for in-process plugins, where | 201 // BlockUntilComplete should never be called for in-process plugins, where |
189 // blocking callbacks are not supported. | 202 // blocking callbacks are not supported. |
190 CHECK(operation_completed_condvar_.get()); | 203 CHECK(operation_completed_condvar_.get()); |
191 if (!is_blocking() || !operation_completed_condvar_.get()) { | 204 if (!is_blocking() || !operation_completed_condvar_.get()) { |
192 NOTREACHED(); | 205 NOTREACHED(); |
193 return PP_ERROR_FAILED; | 206 return PP_ERROR_FAILED; |
194 } | 207 } |
195 | 208 |
196 while (!completed()) | 209 while (!completed()) |
197 operation_completed_condvar_->Wait(); | 210 operation_completed_condvar_->Wait(); |
198 return result_for_blocked_callback_; | 211 |
| 212 int32_t result = result_for_blocked_callback_; |
| 213 if (!completion_task_.is_null()) { |
| 214 result = completion_task_.Run(result); |
| 215 completion_task_.Reset(); |
| 216 } |
| 217 return result; |
199 } | 218 } |
200 | 219 |
201 void TrackedCallback::MarkAsCompleted() { | 220 void TrackedCallback::MarkAsCompleted() { |
202 DCHECK(!completed()); | 221 DCHECK(!completed()); |
203 | 222 |
204 // We will be removed; maintain a reference to ensure we won't be deleted | 223 // We will be removed; maintain a reference to ensure we won't be deleted |
205 // until we're done. | 224 // until we're done. |
206 scoped_refptr<TrackedCallback> thiz = this; | 225 scoped_refptr<TrackedCallback> thiz = this; |
207 completed_ = true; | 226 completed_ = true; |
208 // We may not have a valid resource, in which case we're not in the tracker. | 227 // We may not have a valid resource, in which case we're not in the tracker. |
209 if (resource_id_) | 228 if (resource_id_) |
210 tracker_->Remove(thiz); | 229 tracker_->Remove(thiz); |
211 tracker_ = NULL; | 230 tracker_ = NULL; |
212 } | 231 } |
213 | 232 |
214 } // namespace ppapi | 233 } // namespace ppapi |
OLD | NEW |