| 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 |