OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // TODO(satorux): | 5 // TODO(satorux): |
6 // - Handle "disconnected" signal. | 6 // - Handle "disconnected" signal. |
7 // - Collect metrics (ex. # of method calls, method call time, etc.) | 7 // - Collect metrics (ex. # of method calls, method call time, etc.) |
8 | 8 |
9 #include "dbus/bus.h" | 9 #include "dbus/bus.h" |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "base/message_loop_proxy.h" |
14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
16 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
17 #include "base/time.h" | 18 #include "base/time.h" |
18 #include "dbus/exported_object.h" | 19 #include "dbus/exported_object.h" |
19 #include "dbus/object_proxy.h" | 20 #include "dbus/object_proxy.h" |
20 #include "dbus/scoped_dbus_error.h" | 21 #include "dbus/scoped_dbus_error.h" |
21 | 22 |
22 namespace dbus { | 23 namespace dbus { |
23 | 24 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 162 |
162 DBusTimeout* raw_timeout_; | 163 DBusTimeout* raw_timeout_; |
163 bool monitoring_is_active_; | 164 bool monitoring_is_active_; |
164 bool is_completed; | 165 bool is_completed; |
165 }; | 166 }; |
166 | 167 |
167 } // namespace | 168 } // namespace |
168 | 169 |
169 Bus::Options::Options() | 170 Bus::Options::Options() |
170 : bus_type(SESSION), | 171 : bus_type(SESSION), |
171 connection_type(PRIVATE), | 172 connection_type(PRIVATE) { |
172 dbus_thread(NULL) { | |
173 } | 173 } |
174 | 174 |
175 Bus::Options::~Options() { | 175 Bus::Options::~Options() { |
176 } | 176 } |
177 | 177 |
178 Bus::Bus(const Options& options) | 178 Bus::Bus(const Options& options) |
179 : bus_type_(options.bus_type), | 179 : bus_type_(options.bus_type), |
180 connection_type_(options.connection_type), | 180 connection_type_(options.connection_type), |
181 dbus_thread_(options.dbus_thread), | 181 dbus_thread_message_loop_proxy_(options.dbus_thread_message_loop_proxy), |
182 on_shutdown_(false /* manual_reset */, false /* initially_signaled */), | 182 on_shutdown_(false /* manual_reset */, false /* initially_signaled */), |
183 connection_(NULL), | 183 connection_(NULL), |
184 origin_loop_(MessageLoop::current()), | 184 origin_loop_(MessageLoop::current()), |
185 origin_thread_id_(base::PlatformThread::CurrentId()), | 185 origin_thread_id_(base::PlatformThread::CurrentId()), |
186 dbus_thread_id_(base::kInvalidThreadId), | |
187 async_operations_set_up_(false), | 186 async_operations_set_up_(false), |
188 shutdown_completed_(false), | 187 shutdown_completed_(false), |
189 num_pending_watches_(0), | 188 num_pending_watches_(0), |
190 num_pending_timeouts_(0) { | 189 num_pending_timeouts_(0) { |
191 if (dbus_thread_) { | |
192 dbus_thread_id_ = dbus_thread_->thread_id(); | |
193 DCHECK(dbus_thread_->IsRunning()) | |
194 << "The D-Bus thread should be running"; | |
195 DCHECK_EQ(MessageLoop::TYPE_IO, | |
196 dbus_thread_->message_loop()->type()) | |
197 << "The D-Bus thread should have an MessageLoopForIO attached"; | |
198 } | |
199 | |
200 // This is safe to call multiple times. | 190 // This is safe to call multiple times. |
201 dbus_threads_init_default(); | 191 dbus_threads_init_default(); |
202 } | 192 } |
203 | 193 |
204 Bus::~Bus() { | 194 Bus::~Bus() { |
205 DCHECK(!connection_); | 195 DCHECK(!connection_); |
206 DCHECK(owned_service_names_.empty()); | 196 DCHECK(owned_service_names_.empty()); |
207 DCHECK(match_rules_added_.empty()); | 197 DCHECK(match_rules_added_.empty()); |
208 DCHECK(filter_functions_added_.empty()); | 198 DCHECK(filter_functions_added_.empty()); |
209 DCHECK(registered_object_paths_.empty()); | 199 DCHECK(registered_object_paths_.empty()); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 // dbus_connection_close() won't unref. | 298 // dbus_connection_close() won't unref. |
309 dbus_connection_unref(connection_); | 299 dbus_connection_unref(connection_); |
310 } | 300 } |
311 | 301 |
312 connection_ = NULL; | 302 connection_ = NULL; |
313 shutdown_completed_ = true; | 303 shutdown_completed_ = true; |
314 } | 304 } |
315 | 305 |
316 void Bus::ShutdownOnDBusThreadAndBlock() { | 306 void Bus::ShutdownOnDBusThreadAndBlock() { |
317 AssertOnOriginThread(); | 307 AssertOnOriginThread(); |
318 DCHECK(dbus_thread_); | 308 DCHECK(dbus_thread_message_loop_proxy_.get()); |
319 | 309 |
320 PostTaskToDBusThread(FROM_HERE, base::Bind( | 310 PostTaskToDBusThread(FROM_HERE, base::Bind( |
321 &Bus::ShutdownOnDBusThreadAndBlockInternal, | 311 &Bus::ShutdownOnDBusThreadAndBlockInternal, |
322 this)); | 312 this)); |
323 | 313 |
324 // Wait until the shutdown is complete on the D-Bus thread. | 314 // Wait until the shutdown is complete on the D-Bus thread. |
325 // The shutdown should not hang, but set timeout just in case. | 315 // The shutdown should not hang, but set timeout just in case. |
326 const int kTimeoutSecs = 3; | 316 const int kTimeoutSecs = 3; |
327 const base::TimeDelta timeout(base::TimeDelta::FromSeconds(kTimeoutSecs)); | 317 const base::TimeDelta timeout(base::TimeDelta::FromSeconds(kTimeoutSecs)); |
328 const bool signaled = on_shutdown_.TimedWait(timeout); | 318 const bool signaled = on_shutdown_.TimedWait(timeout); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 } | 559 } |
570 } | 560 } |
571 | 561 |
572 void Bus::PostTaskToOriginThread(const tracked_objects::Location& from_here, | 562 void Bus::PostTaskToOriginThread(const tracked_objects::Location& from_here, |
573 const base::Closure& task) { | 563 const base::Closure& task) { |
574 origin_loop_->PostTask(from_here, task); | 564 origin_loop_->PostTask(from_here, task); |
575 } | 565 } |
576 | 566 |
577 void Bus::PostTaskToDBusThread(const tracked_objects::Location& from_here, | 567 void Bus::PostTaskToDBusThread(const tracked_objects::Location& from_here, |
578 const base::Closure& task) { | 568 const base::Closure& task) { |
579 if (dbus_thread_) | 569 if (dbus_thread_message_loop_proxy_.get()) |
580 dbus_thread_->message_loop()->PostTask(from_here, task); | 570 dbus_thread_message_loop_proxy_->PostTask(from_here, task); |
581 else | 571 else |
582 origin_loop_->PostTask(from_here, task); | 572 origin_loop_->PostTask(from_here, task); |
583 } | 573 } |
584 | 574 |
585 void Bus::PostDelayedTaskToDBusThread( | 575 void Bus::PostDelayedTaskToDBusThread( |
586 const tracked_objects::Location& from_here, | 576 const tracked_objects::Location& from_here, |
587 const base::Closure& task, | 577 const base::Closure& task, |
588 int delay_ms) { | 578 int delay_ms) { |
589 if (dbus_thread_) | 579 if (dbus_thread_message_loop_proxy_.get()) |
590 dbus_thread_->message_loop()->PostDelayedTask(from_here, task, delay_ms); | 580 dbus_thread_message_loop_proxy_->PostDelayedTask(from_here, task, delay_ms); |
591 else | 581 else |
592 origin_loop_->PostDelayedTask(from_here, task, delay_ms); | 582 origin_loop_->PostDelayedTask(from_here, task, delay_ms); |
593 } | 583 } |
594 | 584 |
595 bool Bus::HasDBusThread() { | 585 bool Bus::HasDBusThread() { |
596 return dbus_thread_ != NULL; | 586 return dbus_thread_message_loop_proxy_.get() != NULL; |
597 } | 587 } |
598 | 588 |
599 void Bus::AssertOnOriginThread() { | 589 void Bus::AssertOnOriginThread() { |
600 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); | 590 DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); |
601 } | 591 } |
602 | 592 |
603 void Bus::AssertOnDBusThread() { | 593 void Bus::AssertOnDBusThread() { |
604 base::ThreadRestrictions::AssertIOAllowed(); | 594 base::ThreadRestrictions::AssertIOAllowed(); |
605 | 595 |
606 if (dbus_thread_) { | 596 if (dbus_thread_message_loop_proxy_.get()) { |
607 DCHECK_EQ(dbus_thread_id_, base::PlatformThread::CurrentId()); | 597 DCHECK(dbus_thread_message_loop_proxy_->BelongsToCurrentThread()); |
608 } else { | 598 } else { |
609 AssertOnOriginThread(); | 599 AssertOnOriginThread(); |
610 } | 600 } |
611 } | 601 } |
612 | 602 |
613 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) { | 603 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) { |
614 AssertOnDBusThread(); | 604 AssertOnDBusThread(); |
615 | 605 |
616 // watch will be deleted when raw_watch is removed in OnRemoveWatch(). | 606 // watch will be deleted when raw_watch is removed in OnRemoveWatch(). |
617 Watch* watch = new Watch(raw_watch); | 607 Watch* watch = new Watch(raw_watch); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 } | 713 } |
724 | 714 |
725 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection, | 715 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection, |
726 DBusDispatchStatus status, | 716 DBusDispatchStatus status, |
727 void* data) { | 717 void* data) { |
728 Bus* self = static_cast<Bus*>(data); | 718 Bus* self = static_cast<Bus*>(data); |
729 return self->OnDispatchStatusChanged(connection, status); | 719 return self->OnDispatchStatusChanged(connection, status); |
730 } | 720 } |
731 | 721 |
732 } // namespace dbus | 722 } // namespace dbus |
OLD | NEW |