| Index: ppapi/shared_impl/callback_tracker.cc
|
| diff --git a/ppapi/shared_impl/callback_tracker.cc b/ppapi/shared_impl/callback_tracker.cc
|
| index feefb0e117d70aa862553838656da09763927824..21702b1e5921a655c80f62bfd3dc925e1432471d 100644
|
| --- a/ppapi/shared_impl/callback_tracker.cc
|
| +++ b/ppapi/shared_impl/callback_tracker.cc
|
| @@ -11,18 +11,26 @@
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "ppapi/c/pp_completion_callback.h"
|
| +#include "ppapi/shared_impl/proxy_lock.h"
|
| #include "ppapi/shared_impl/tracked_callback.h"
|
|
|
| namespace ppapi {
|
|
|
| // CallbackTracker -------------------------------------------------------------
|
|
|
| -CallbackTracker::CallbackTracker() {}
|
| +CallbackTracker::CallbackTracker() : abort_all_called_(false) {
|
| +}
|
|
|
| void CallbackTracker::AbortAll() {
|
| - // Iterate over a copy since |Abort()| calls |Remove()| (indirectly).
|
| - // TODO(viettrungluu): This obviously isn't so efficient.
|
| - CallbackSetMap pending_callbacks_copy = pending_callbacks_;
|
| + // Iterate over a copy:
|
| + // 1) because |Abort()| calls |Remove()| (indirectly).
|
| + // 2) So we can drop the lock before calling in to TrackedCallback.
|
| + CallbackSetMap pending_callbacks_copy;
|
| + {
|
| + base::AutoLock acquire(lock_);
|
| + pending_callbacks_copy = pending_callbacks_;
|
| + abort_all_called_ = true;
|
| + }
|
| for (CallbackSetMap::iterator it1 = pending_callbacks_copy.begin();
|
| it1 != pending_callbacks_copy.end();
|
| ++it1) {
|
| @@ -35,15 +43,20 @@ void CallbackTracker::AbortAll() {
|
| }
|
|
|
| void CallbackTracker::PostAbortForResource(PP_Resource resource_id) {
|
| - CHECK(resource_id != 0);
|
| - CallbackSetMap::iterator it1 = pending_callbacks_.find(resource_id);
|
| - if (it1 == pending_callbacks_.end())
|
| - return;
|
| - for (CallbackSet::iterator it2 = it1->second.begin();
|
| - it2 != it1->second.end();
|
| - ++it2) {
|
| - // Post the abort.
|
| - (*it2)->PostAbort();
|
| + CHECK_NE(resource_id, 0);
|
| + CallbackSet callbacks_for_resource;
|
| + {
|
| + base::AutoLock acquire(lock_);
|
| + CallbackSetMap::iterator iter = pending_callbacks_.find(resource_id);
|
| + // The resource may have no callbacks, so it won't be found, and we're done.
|
| + if (iter == pending_callbacks_.end())
|
| + return;
|
| + // Copy the set so we can drop the lock before calling in to
|
| + // TrackedCallback.
|
| + callbacks_for_resource = iter->second;
|
| + }
|
| + for (const auto& iter : callbacks_for_resource) {
|
| + iter->PostAbort();
|
| }
|
| }
|
|
|
| @@ -54,6 +67,8 @@ CallbackTracker::~CallbackTracker() {
|
|
|
| void CallbackTracker::Add(
|
| const scoped_refptr<TrackedCallback>& tracked_callback) {
|
| + base::AutoLock acquire(lock_);
|
| + DCHECK(!abort_all_called_);
|
| PP_Resource resource_id = tracked_callback->resource_id();
|
| DCHECK(pending_callbacks_[resource_id].find(tracked_callback) ==
|
| pending_callbacks_[resource_id].end());
|
| @@ -62,6 +77,7 @@ void CallbackTracker::Add(
|
|
|
| void CallbackTracker::Remove(
|
| const scoped_refptr<TrackedCallback>& tracked_callback) {
|
| + base::AutoLock acquire(lock_);
|
| CallbackSetMap::iterator map_it =
|
| pending_callbacks_.find(tracked_callback->resource_id());
|
| DCHECK(map_it != pending_callbacks_.end());
|
|
|