Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: tools/android/forwarder2/forwarders_manager.cc

Issue 60033002: Make HostController/DeviceListener deletion fully synchronous. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/android/forwarder2/forwarders_manager.h ('k') | tools/android/forwarder2/host_controller.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/android/forwarder2/forwarders_manager.cc
diff --git a/tools/android/forwarder2/forwarders_manager.cc b/tools/android/forwarder2/forwarders_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b3cd2c46ef1ecfc84449683afce233c585f702d
--- /dev/null
+++ b/tools/android/forwarder2/forwarders_manager.cc
@@ -0,0 +1,91 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/android/forwarder2/forwarders_manager.h"
+
+#include <algorithm>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "tools/android/forwarder2/forwarder.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+ForwardersManager::ForwardersManager() : delegate_(new Delegate()) {}
+
+ForwardersManager::~ForwardersManager() {
+ delegate_->Clear();
+}
+
+void ForwardersManager::CreateAndStartNewForwarder(scoped_ptr<Socket> socket1,
+ scoped_ptr<Socket> socket2) {
+ delegate_->CreateAndStartNewForwarder(socket1.Pass(), socket2.Pass());
+}
+
+ForwardersManager::Delegate::Delegate() {}
+
+ForwardersManager::Delegate::~Delegate() {
+ // The forwarder instances should already have been deleted on their
+ // construction thread. Deleting them here would be unsafe since we don't know
+ // which thread this destructor is called on.
+ DCHECK(forwarders_.empty());
+}
+
+void ForwardersManager::Delegate::Clear() {
+ if (!forwarders_constructor_runner_) {
+ DCHECK(forwarders_.empty());
+ return;
+ }
+ if (forwarders_constructor_runner_->RunsTasksOnCurrentThread()) {
+ ClearOnForwarderConstructorThread();
+ return;
+ }
+ forwarders_constructor_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &ForwardersManager::Delegate::ClearOnForwarderConstructorThread,
+ this));
+}
+
+void ForwardersManager::Delegate::CreateAndStartNewForwarder(
+ scoped_ptr<Socket> socket1,
+ scoped_ptr<Socket> socket2) {
+ const scoped_refptr<base::SingleThreadTaskRunner> current_task_runner(
+ base::MessageLoopProxy::current());
+ DCHECK(current_task_runner);
+ if (forwarders_constructor_runner_) {
+ DCHECK_EQ(current_task_runner, forwarders_constructor_runner_);
+ } else {
+ forwarders_constructor_runner_ = current_task_runner;
+ }
+ forwarders_.push_back(
+ new Forwarder(socket1.Pass(), socket2.Pass(),
+ &deletion_notifier_,
+ base::Bind(&ForwardersManager::Delegate::OnForwarderError,
+ this)));
+ forwarders_.back()->Start();
+}
+
+void ForwardersManager::Delegate::OnForwarderError(
+ scoped_ptr<Forwarder> forwarder) {
+ DCHECK(forwarders_constructor_runner_->RunsTasksOnCurrentThread());
+ const ScopedVector<Forwarder>::iterator it = std::find(
+ forwarders_.begin(), forwarders_.end(), forwarder.get());
+ DCHECK(it != forwarders_.end());
+ std::swap(*it, forwarders_.back());
+ forwarders_.pop_back();
+ ignore_result(forwarder.release()); // Deleted by the pop_back() above.
+}
+
+void ForwardersManager::Delegate::ClearOnForwarderConstructorThread() {
+ DCHECK(forwarders_constructor_runner_->RunsTasksOnCurrentThread());
+ deletion_notifier_.Notify();
+ forwarders_.clear();
+}
+
+} // namespace forwarder2
« no previous file with comments | « tools/android/forwarder2/forwarders_manager.h ('k') | tools/android/forwarder2/host_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698