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.h" | 10 #include "base/message_loop.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // tracker. Then MarkAsCompleted before waking up the blocked thread, | 116 // tracker. Then MarkAsCompleted before waking up the blocked thread, |
117 // which could potentially re-enter. | 117 // which could potentially re-enter. |
118 scoped_refptr<TrackedCallback> thiz(this); | 118 scoped_refptr<TrackedCallback> thiz(this); |
119 MarkAsCompleted(); | 119 MarkAsCompleted(); |
120 // Wake up the blocked thread. See BlockUntilComplete for where the thread | 120 // Wake up the blocked thread. See BlockUntilComplete for where the thread |
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_ && | 126 if (target_loop_.get() && |
127 target_loop_ != 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 // Copy |callback_| now, since |MarkAsCompleted()| may delete us. |
132 PP_CompletionCallback callback = callback_; | 132 PP_CompletionCallback callback = callback_; |
133 // Do this before running the callback in case of reentrancy (which | 133 // Do this before running the callback in case of reentrancy (which |
134 // shouldn't happen, but avoid strange failures). | 134 // shouldn't happen, but avoid strange failures). |
135 MarkAsCompleted(); | 135 MarkAsCompleted(); |
136 // TODO(dmichael): Associate a message loop with the callback; if it's not | 136 // 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. | 137 // the same as the current thread's loop, then post it to the right loop. |
138 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); | 138 CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 void TrackedCallback::PostRun(int32_t result) { | 142 void TrackedCallback::PostRun(int32_t result) { |
143 if (completed()) { | 143 if (completed()) { |
144 NOTREACHED(); | 144 NOTREACHED(); |
145 return; | 145 return; |
146 } | 146 } |
147 if (result == PP_ERROR_ABORTED) | 147 if (result == PP_ERROR_ABORTED) |
148 aborted_ = true; | 148 aborted_ = true; |
149 // We might abort when there's already a scheduled callback, but callers | 149 // We might abort when there's already a scheduled callback, but callers |
150 // should never try to PostRun more than once otherwise. | 150 // should never try to PostRun more than once otherwise. |
151 DCHECK(result == PP_ERROR_ABORTED || !is_scheduled_); | 151 DCHECK(result == PP_ERROR_ABORTED || !is_scheduled_); |
152 | 152 |
153 base::Closure callback_closure( | 153 base::Closure callback_closure( |
154 RunWhileLocked(base::Bind(&TrackedCallback::Run, this, result))); | 154 RunWhileLocked(base::Bind(&TrackedCallback::Run, this, result))); |
155 if (!target_loop_) { | 155 if (!target_loop_.get()) { |
156 // We must be running in-process and on the main thread (the Enter | 156 // We must be running in-process and on the main thread (the Enter |
157 // classes protect against having a null target_loop_ otherwise). | 157 // classes protect against having a null target_loop_ otherwise). |
158 DCHECK(IsMainThread()); | 158 DCHECK(IsMainThread()); |
159 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); | 159 DCHECK(PpapiGlobals::Get()->IsHostGlobals()); |
160 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); | 160 base::MessageLoop::current()->PostTask(FROM_HERE, callback_closure); |
161 } else { | 161 } else { |
162 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); | 162 target_loop_->PostClosure(FROM_HERE, callback_closure, 0); |
163 } | 163 } |
164 is_scheduled_ = true; | 164 is_scheduled_ = true; |
165 } | 165 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // until we're done. | 197 // until we're done. |
198 scoped_refptr<TrackedCallback> thiz = this; | 198 scoped_refptr<TrackedCallback> thiz = this; |
199 completed_ = true; | 199 completed_ = true; |
200 // We may not have a valid resource, in which case we're not in the tracker. | 200 // We may not have a valid resource, in which case we're not in the tracker. |
201 if (resource_id_) | 201 if (resource_id_) |
202 tracker_->Remove(thiz); | 202 tracker_->Remove(thiz); |
203 tracker_ = NULL; | 203 tracker_ = NULL; |
204 } | 204 } |
205 | 205 |
206 } // namespace ppapi | 206 } // namespace ppapi |
OLD | NEW |