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

Side by Side Diff: mojo/public/cpp/bindings/lib/connector.cc

Issue 2818533003: Make nesting/running states a RunLoop rather than a MessageLoop concept. (Closed)
Patch Set: need to RunUntilIdle for ConnectProfile with DoNothing callbacks -- how did this possibly not hang … Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "mojo/public/cpp/bindings/connector.h" 5 #include "mojo/public/cpp/bindings/connector.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
17 #include "base/synchronization/lock.h" 18 #include "base/synchronization/lock.h"
18 #include "base/threading/thread_local.h" 19 #include "base/threading/thread_local.h"
19 #include "mojo/public/cpp/bindings/lib/may_auto_lock.h" 20 #include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
20 #include "mojo/public/cpp/bindings/sync_handle_watcher.h" 21 #include "mojo/public/cpp/bindings/sync_handle_watcher.h"
21 #include "mojo/public/cpp/system/wait.h" 22 #include "mojo/public/cpp/system/wait.h"
22 23
23 namespace mojo { 24 namespace mojo {
24 25
25 namespace { 26 namespace {
26 27
27 // The NestingObserver for each thread. Note that this is always a 28 // The NestingObserver for each thread. Note that this is always a
28 // Connector::MessageLoopNestingObserver; we use the base type here because that 29 // Connector::RunLoopNestingObserver; we use the base type here because that
29 // subclass is private to Connector. 30 // subclass is private to Connector.
30 base::LazyInstance< 31 base::LazyInstance<base::ThreadLocalPointer<base::RunLoop::NestingObserver>>::
31 base::ThreadLocalPointer<base::MessageLoop::NestingObserver>>::Leaky 32 Leaky g_tls_nesting_observer = LAZY_INSTANCE_INITIALIZER;
32 g_tls_nesting_observer = LAZY_INSTANCE_INITIALIZER;
33 33
34 } // namespace 34 } // namespace
35 35
36 // Used to efficiently maintain a doubly-linked list of all Connectors 36 // Used to efficiently maintain a doubly-linked list of all Connectors
37 // currently dispatching on any given thread. 37 // currently dispatching on any given thread.
38 class Connector::ActiveDispatchTracker { 38 class Connector::ActiveDispatchTracker {
39 public: 39 public:
40 explicit ActiveDispatchTracker(const base::WeakPtr<Connector>& connector); 40 explicit ActiveDispatchTracker(const base::WeakPtr<Connector>& connector);
41 ~ActiveDispatchTracker(); 41 ~ActiveDispatchTracker();
42 42
43 void NotifyBeginNesting(); 43 void NotifyBeginNesting();
44 44
45 private: 45 private:
46 const base::WeakPtr<Connector> connector_; 46 const base::WeakPtr<Connector> connector_;
47 MessageLoopNestingObserver* const nesting_observer_; 47 RunLoopNestingObserver* const nesting_observer_;
48 ActiveDispatchTracker* outer_tracker_ = nullptr; 48 ActiveDispatchTracker* outer_tracker_ = nullptr;
49 ActiveDispatchTracker* inner_tracker_ = nullptr; 49 ActiveDispatchTracker* inner_tracker_ = nullptr;
50 50
51 DISALLOW_COPY_AND_ASSIGN(ActiveDispatchTracker); 51 DISALLOW_COPY_AND_ASSIGN(ActiveDispatchTracker);
52 }; 52 };
53 53
54 // Watches the MessageLoop on the current thread. Notifies the current chain of 54 // Watches the MessageLoop on the current thread. Notifies the current chain of
55 // ActiveDispatchTrackers when a nested message loop is started. 55 // ActiveDispatchTrackers when a nested message loop is started.
56 class Connector::MessageLoopNestingObserver 56 class Connector::RunLoopNestingObserver
57 : public base::MessageLoop::NestingObserver, 57 : public base::RunLoop::NestingObserver,
58 public base::MessageLoop::DestructionObserver { 58 public base::MessageLoop::DestructionObserver {
59 public: 59 public:
60 MessageLoopNestingObserver() { 60 RunLoopNestingObserver() {
61 base::MessageLoop::current()->AddNestingObserver(this); 61 base::RunLoop::AddNestingObserverOnCurrentThread(this);
62 base::MessageLoop::current()->AddDestructionObserver(this); 62 base::MessageLoop::current()->AddDestructionObserver(this);
63 } 63 }
64 64
65 ~MessageLoopNestingObserver() override {} 65 ~RunLoopNestingObserver() override {}
66 66
67 // base::MessageLoop::NestingObserver: 67 // base::RunLoop::NestingObserver:
68 void OnBeginNestedMessageLoop() override { 68 void OnBeginNestedRunLoop() override {
69 if (top_tracker_) 69 if (top_tracker_)
70 top_tracker_->NotifyBeginNesting(); 70 top_tracker_->NotifyBeginNesting();
71 } 71 }
72 72
73 // base::MessageLoop::DestructionObserver: 73 // base::MessageLoop::DestructionObserver:
74 void WillDestroyCurrentMessageLoop() override { 74 void WillDestroyCurrentMessageLoop() override {
75 base::MessageLoop::current()->RemoveNestingObserver(this); 75 base::RunLoop::RemoveNestingObserverOnCurrentThread(this);
76 base::MessageLoop::current()->RemoveDestructionObserver(this); 76 base::MessageLoop::current()->RemoveDestructionObserver(this);
77 DCHECK_EQ(this, g_tls_nesting_observer.Get().Get()); 77 DCHECK_EQ(this, g_tls_nesting_observer.Get().Get());
78 g_tls_nesting_observer.Get().Set(nullptr); 78 g_tls_nesting_observer.Get().Set(nullptr);
79 delete this; 79 delete this;
80 } 80 }
81 81
82 static MessageLoopNestingObserver* GetForThread() { 82 static RunLoopNestingObserver* GetForThread() {
83 if (!base::MessageLoop::current() || 83 if (!base::RunLoop::IsNestingAllowedOnCurrentThread())
84 !base::MessageLoop::current()->nesting_allowed())
85 return nullptr; 84 return nullptr;
86 auto* observer = static_cast<MessageLoopNestingObserver*>( 85 auto* observer = static_cast<RunLoopNestingObserver*>(
87 g_tls_nesting_observer.Get().Get()); 86 g_tls_nesting_observer.Get().Get());
88 if (!observer) { 87 if (!observer) {
89 observer = new MessageLoopNestingObserver; 88 observer = new RunLoopNestingObserver;
90 g_tls_nesting_observer.Get().Set(observer); 89 g_tls_nesting_observer.Get().Set(observer);
91 } 90 }
92 return observer; 91 return observer;
93 } 92 }
94 93
95 private: 94 private:
96 friend class ActiveDispatchTracker; 95 friend class ActiveDispatchTracker;
97 96
98 ActiveDispatchTracker* top_tracker_ = nullptr; 97 ActiveDispatchTracker* top_tracker_ = nullptr;
99 98
100 DISALLOW_COPY_AND_ASSIGN(MessageLoopNestingObserver); 99 DISALLOW_COPY_AND_ASSIGN(RunLoopNestingObserver);
101 }; 100 };
102 101
103 Connector::ActiveDispatchTracker::ActiveDispatchTracker( 102 Connector::ActiveDispatchTracker::ActiveDispatchTracker(
104 const base::WeakPtr<Connector>& connector) 103 const base::WeakPtr<Connector>& connector)
105 : connector_(connector), nesting_observer_(connector_->nesting_observer_) { 104 : connector_(connector), nesting_observer_(connector_->nesting_observer_) {
106 DCHECK(nesting_observer_); 105 DCHECK(nesting_observer_);
107 if (nesting_observer_->top_tracker_) { 106 if (nesting_observer_->top_tracker_) {
108 outer_tracker_ = nesting_observer_->top_tracker_; 107 outer_tracker_ = nesting_observer_->top_tracker_;
109 outer_tracker_->inner_tracker_ = this; 108 outer_tracker_->inner_tracker_ = this;
110 } 109 }
(...skipping 14 matching lines...) Expand all
125 connector_->handle_watcher_->ArmOrNotify(); 124 connector_->handle_watcher_->ArmOrNotify();
126 if (outer_tracker_) 125 if (outer_tracker_)
127 outer_tracker_->NotifyBeginNesting(); 126 outer_tracker_->NotifyBeginNesting();
128 } 127 }
129 128
130 Connector::Connector(ScopedMessagePipeHandle message_pipe, 129 Connector::Connector(ScopedMessagePipeHandle message_pipe,
131 ConnectorConfig config, 130 ConnectorConfig config,
132 scoped_refptr<base::SingleThreadTaskRunner> runner) 131 scoped_refptr<base::SingleThreadTaskRunner> runner)
133 : message_pipe_(std::move(message_pipe)), 132 : message_pipe_(std::move(message_pipe)),
134 task_runner_(std::move(runner)), 133 task_runner_(std::move(runner)),
135 nesting_observer_(MessageLoopNestingObserver::GetForThread()), 134 nesting_observer_(RunLoopNestingObserver::GetForThread()),
136 weak_factory_(this) { 135 weak_factory_(this) {
137 if (config == MULTI_THREADED_SEND) 136 if (config == MULTI_THREADED_SEND)
138 lock_.emplace(); 137 lock_.emplace();
139 138
140 weak_self_ = weak_factory_.GetWeakPtr(); 139 weak_self_ = weak_factory_.GetWeakPtr();
141 // Even though we don't have an incoming receiver, we still want to monitor 140 // Even though we don't have an incoming receiver, we still want to monitor
142 // the message pipe to know if is closed or encounters an error. 141 // the message pipe to know if is closed or encounters an error.
143 WaitToReadMore(); 142 WaitToReadMore();
144 } 143 }
145 144
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 void Connector::EnsureSyncWatcherExists() { 483 void Connector::EnsureSyncWatcherExists() {
485 if (sync_watcher_) 484 if (sync_watcher_)
486 return; 485 return;
487 sync_watcher_.reset(new SyncHandleWatcher( 486 sync_watcher_.reset(new SyncHandleWatcher(
488 message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE, 487 message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
489 base::Bind(&Connector::OnSyncHandleWatcherHandleReady, 488 base::Bind(&Connector::OnSyncHandleWatcherHandleReady,
490 base::Unretained(this)))); 489 base::Unretained(this))));
491 } 490 }
492 491
493 } // namespace mojo 492 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698