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

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

Issue 1455063004: Mojo C++ bindings: introduce MultiplexRouter and related classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix mac compilation Created 5 years, 1 month 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/lib/connector.h" 5 #include "mojo/public/cpp/bindings/lib/connector.h"
6 6
7 #include "base/macros.h"
8 #include "base/synchronization/lock.h"
7 #include "mojo/public/cpp/environment/logging.h" 9 #include "mojo/public/cpp/environment/logging.h"
8 10
9 namespace mojo { 11 namespace mojo {
10 namespace internal { 12 namespace internal {
11 13
14 namespace {
15
16 // Similar to base::AutoLock, except that it does nothing if |lock| passed into
17 // the constructor is null.
18 class MayAutoLock {
19 public:
20 explicit MayAutoLock(base::Lock* lock) : lock_(lock) {
21 if (lock_)
22 lock_->Acquire();
23 }
24
25 ~MayAutoLock() {
26 if (lock_) {
27 lock_->AssertAcquired();
28 lock_->Release();
29 }
30 }
31
32 private:
33 base::Lock* lock_;
34 DISALLOW_COPY_AND_ASSIGN(MayAutoLock);
35 };
36
37 } // namespace
38
12 // ---------------------------------------------------------------------------- 39 // ----------------------------------------------------------------------------
13 40
14 Connector::Connector(ScopedMessagePipeHandle message_pipe, 41 Connector::Connector(ScopedMessagePipeHandle message_pipe,
42 SendingThreadSaftyType sending_thread_safty_type,
15 const MojoAsyncWaiter* waiter) 43 const MojoAsyncWaiter* waiter)
16 : waiter_(waiter), 44 : waiter_(waiter),
17 message_pipe_(message_pipe.Pass()), 45 message_pipe_(message_pipe.Pass()),
18 incoming_receiver_(nullptr), 46 incoming_receiver_(nullptr),
19 async_wait_id_(0), 47 async_wait_id_(0),
20 error_(false), 48 error_(false),
21 drop_writes_(false), 49 drop_writes_(false),
22 enforce_errors_from_incoming_receiver_(true), 50 enforce_errors_from_incoming_receiver_(true),
23 paused_(false), 51 paused_(false),
24 destroyed_flag_(nullptr) { 52 destroyed_flag_(nullptr),
53 lock_(sending_thread_safty_type == MULTI_THREADED_SEND ? new base::Lock
54 : nullptr) {
25 // Even though we don't have an incoming receiver, we still want to monitor 55 // Even though we don't have an incoming receiver, we still want to monitor
26 // the message pipe to know if is closed or encounters an error. 56 // the message pipe to know if is closed or encounters an error.
27 WaitToReadMore(); 57 WaitToReadMore();
28 } 58 }
29 59
30 Connector::~Connector() { 60 Connector::~Connector() {
31 if (destroyed_flag_) 61 if (destroyed_flag_)
32 *destroyed_flag_ = true; 62 *destroyed_flag_ = true;
33 63
34 CancelWait(); 64 CancelWait();
35 } 65 }
36 66
37 void Connector::CloseMessagePipe() { 67 void Connector::CloseMessagePipe() {
38 CancelWait(); 68 CancelWait();
69 MayAutoLock locker(lock_.get());
39 Close(message_pipe_.Pass()); 70 Close(message_pipe_.Pass());
40 } 71 }
41 72
42 ScopedMessagePipeHandle Connector::PassMessagePipe() { 73 ScopedMessagePipeHandle Connector::PassMessagePipe() {
43 CancelWait(); 74 CancelWait();
75 MayAutoLock locker(lock_.get());
44 return message_pipe_.Pass(); 76 return message_pipe_.Pass();
45 } 77 }
46 78
47 void Connector::RaiseError() { 79 void Connector::RaiseError() {
48 HandleError(true, true); 80 HandleError(true, true);
49 } 81 }
50 82
51 bool Connector::WaitForIncomingMessage(MojoDeadline deadline) { 83 bool Connector::WaitForIncomingMessage(MojoDeadline deadline) {
52 if (error_) 84 if (error_)
53 return false; 85 return false;
(...skipping 24 matching lines...) Expand all
78 110
79 void Connector::ResumeIncomingMethodCallProcessing() { 111 void Connector::ResumeIncomingMethodCallProcessing() {
80 if (!paused_) 112 if (!paused_)
81 return; 113 return;
82 114
83 paused_ = false; 115 paused_ = false;
84 WaitToReadMore(); 116 WaitToReadMore();
85 } 117 }
86 118
87 bool Connector::Accept(Message* message) { 119 bool Connector::Accept(Message* message) {
120 // It shouldn't hurt even if |error_| may be changed by a different thread at
121 // the same time. The outcome is that we may write into |message_pipe_| after
122 // encountering an error, which should be fine.
88 if (error_) 123 if (error_)
89 return false; 124 return false;
90 125
91 MOJO_CHECK(message_pipe_.is_valid()); 126 MayAutoLock locker(lock_.get());
92 if (drop_writes_) 127
128 if (!message_pipe_.is_valid() || drop_writes_)
93 return true; 129 return true;
94 130
95 MojoResult rv = 131 MojoResult rv =
96 WriteMessageRaw(message_pipe_.get(), 132 WriteMessageRaw(message_pipe_.get(),
97 message->data(), 133 message->data(),
98 message->data_num_bytes(), 134 message->data_num_bytes(),
99 message->mutable_handles()->empty() 135 message->mutable_handles()->empty()
100 ? nullptr 136 ? nullptr
101 : reinterpret_cast<const MojoHandle*>( 137 : reinterpret_cast<const MojoHandle*>(
102 &message->mutable_handles()->front()), 138 &message->mutable_handles()->front()),
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 force_pipe_reset = true; 266 force_pipe_reset = true;
231 267
232 if (paused_) { 268 if (paused_) {
233 // If the user has paused receiving messages, we shouldn't call the error 269 // If the user has paused receiving messages, we shouldn't call the error
234 // handler right away. We need to wait until the user starts receiving 270 // handler right away. We need to wait until the user starts receiving
235 // messages again. 271 // messages again.
236 force_async_handler = true; 272 force_async_handler = true;
237 } 273 }
238 274
239 if (force_pipe_reset) { 275 if (force_pipe_reset) {
240 CloseMessagePipe(); 276 CancelWait();
277 MayAutoLock locker(lock_.get());
278 Close(message_pipe_.Pass());
241 MessagePipe dummy_pipe; 279 MessagePipe dummy_pipe;
242 message_pipe_ = dummy_pipe.handle0.Pass(); 280 message_pipe_ = dummy_pipe.handle0.Pass();
243 } else { 281 } else {
244 CancelWait(); 282 CancelWait();
245 } 283 }
246 284
247 if (force_async_handler) { 285 if (force_async_handler) {
248 // |dummy_pipe.handle1| has been destructed. Reading the pipe will 286 // |dummy_pipe.handle1| has been destructed. Reading the pipe will
249 // eventually cause a read error on |message_pipe_| and set error state. 287 // eventually cause a read error on |message_pipe_| and set error state.
250 if (!paused_) 288 if (!paused_)
251 WaitToReadMore(); 289 WaitToReadMore();
252 } else { 290 } else {
253 error_ = true; 291 error_ = true;
254 connection_error_handler_.Run(); 292 connection_error_handler_.Run();
255 } 293 }
256 } 294 }
257 295
258 } // namespace internal 296 } // namespace internal
259 } // namespace mojo 297 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698