Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "dbus/bus.h" | 5 #include "dbus/bus.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | |
| 10 | |
| 9 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/files/file_descriptor_watcher_posix.h" | |
| 10 #include "base/logging.h" | 13 #include "base/logging.h" |
| 11 #include "base/message_loop/message_loop.h" | |
| 12 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 13 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 14 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 15 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 16 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 17 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 18 #include "dbus/exported_object.h" | 20 #include "dbus/exported_object.h" |
| 19 #include "dbus/message.h" | 21 #include "dbus/message.h" |
| 20 #include "dbus/object_manager.h" | 22 #include "dbus/object_manager.h" |
| 21 #include "dbus/object_path.h" | 23 #include "dbus/object_path.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 35 const char kNameOwnerChangedSignal[] = "NameOwnerChanged"; | 37 const char kNameOwnerChangedSignal[] = "NameOwnerChanged"; |
| 36 | 38 |
| 37 // The match rule used to filter for changes to a given service name owner. | 39 // The match rule used to filter for changes to a given service name owner. |
| 38 const char kServiceNameOwnerChangeMatchRule[] = | 40 const char kServiceNameOwnerChangeMatchRule[] = |
| 39 "type='signal',interface='org.freedesktop.DBus'," | 41 "type='signal',interface='org.freedesktop.DBus'," |
| 40 "member='NameOwnerChanged',path='/org/freedesktop/DBus'," | 42 "member='NameOwnerChanged',path='/org/freedesktop/DBus'," |
| 41 "sender='org.freedesktop.DBus',arg0='%s'"; | 43 "sender='org.freedesktop.DBus',arg0='%s'"; |
| 42 | 44 |
| 43 // The class is used for watching the file descriptor used for D-Bus | 45 // The class is used for watching the file descriptor used for D-Bus |
| 44 // communication. | 46 // communication. |
| 45 class Watch : public base::MessagePumpLibevent::Watcher { | 47 class Watch { |
| 46 public: | 48 public: |
| 47 explicit Watch(DBusWatch* watch) | 49 explicit Watch(DBusWatch* watch) : raw_watch_(watch) { |
| 48 : raw_watch_(watch), file_descriptor_watcher_(FROM_HERE) { | |
| 49 dbus_watch_set_data(raw_watch_, this, NULL); | 50 dbus_watch_set_data(raw_watch_, this, NULL); |
| 50 } | 51 } |
| 51 | 52 |
| 52 ~Watch() override { dbus_watch_set_data(raw_watch_, NULL, NULL); } | 53 ~Watch() { dbus_watch_set_data(raw_watch_, NULL, NULL); } |
| 53 | 54 |
| 54 // Returns true if the underlying file descriptor is ready to be watched. | 55 // Returns true if the underlying file descriptor is ready to be watched. |
| 55 bool IsReadyToBeWatched() { | 56 bool IsReadyToBeWatched() { |
| 56 return dbus_watch_get_enabled(raw_watch_); | 57 return dbus_watch_get_enabled(raw_watch_); |
| 57 } | 58 } |
| 58 | 59 |
| 59 // Starts watching the underlying file descriptor. | 60 // Starts watching the underlying file descriptor. |
| 60 void StartWatching() { | 61 void StartWatching() { |
| 61 const int file_descriptor = dbus_watch_get_unix_fd(raw_watch_); | 62 const int file_descriptor = dbus_watch_get_unix_fd(raw_watch_); |
| 62 const int flags = dbus_watch_get_flags(raw_watch_); | 63 const unsigned int flags = dbus_watch_get_flags(raw_watch_); |
| 63 | 64 |
| 64 base::MessageLoopForIO::Mode mode = base::MessageLoopForIO::WATCH_READ; | 65 // Using base::Unretained(this) is safe because watches are automatically |
| 65 if ((flags & DBUS_WATCH_READABLE) && (flags & DBUS_WATCH_WRITABLE)) | 66 // canceled when |read_watcher_| and |write_watcher_| are destroyed. |
| 66 mode = base::MessageLoopForIO::WATCH_READ_WRITE; | 67 if (flags & DBUS_WATCH_READABLE) { |
| 67 else if (flags & DBUS_WATCH_READABLE) | 68 read_watcher_ = base::FileDescriptorWatcher::WatchReadable( |
|
satorux1
2017/04/12 01:02:30
The function comment for WatchReadable() says:
fdoray
2017/04/12 12:39:47
MessageLoopForIO and TaskScheduler threads instant
| |
| 68 mode = base::MessageLoopForIO::WATCH_READ; | 69 file_descriptor, |
| 69 else if (flags & DBUS_WATCH_WRITABLE) | 70 base::Bind(&Watch::OnFileReady, base::Unretained(this), |
| 70 mode = base::MessageLoopForIO::WATCH_WRITE; | 71 DBUS_WATCH_READABLE)); |
| 71 else | 72 } |
| 72 NOTREACHED(); | 73 if (flags & DBUS_WATCH_WRITABLE) { |
| 73 | 74 write_watcher_ = base::FileDescriptorWatcher::WatchWritable( |
| 74 const bool persistent = true; // Watch persistently. | 75 file_descriptor, |
| 75 const bool success = base::MessageLoopForIO::current()->WatchFileDescriptor( | 76 base::Bind(&Watch::OnFileReady, base::Unretained(this), |
| 76 file_descriptor, persistent, mode, &file_descriptor_watcher_, this); | 77 DBUS_WATCH_WRITABLE)); |
| 77 CHECK(success) << "Unable to allocate memory"; | 78 } |
| 78 } | 79 } |
| 79 | 80 |
| 80 // Stops watching the underlying file descriptor. | 81 // Stops watching the underlying file descriptor. |
| 81 void StopWatching() { | 82 void StopWatching() { |
| 82 file_descriptor_watcher_.StopWatchingFileDescriptor(); | 83 read_watcher_.reset(); |
| 84 write_watcher_.reset(); | |
| 83 } | 85 } |
| 84 | 86 |
| 85 private: | 87 private: |
| 86 // Implement MessagePumpLibevent::Watcher. | 88 void OnFileReady(unsigned int flags) { |
| 87 void OnFileCanReadWithoutBlocking(int file_descriptor) override { | 89 CHECK(dbus_watch_handle(raw_watch_, flags)) << "Unable to allocate memory"; |
| 88 const bool success = dbus_watch_handle(raw_watch_, DBUS_WATCH_READABLE); | |
| 89 CHECK(success) << "Unable to allocate memory"; | |
| 90 } | |
| 91 | |
| 92 // Implement MessagePumpLibevent::Watcher. | |
| 93 void OnFileCanWriteWithoutBlocking(int file_descriptor) override { | |
| 94 const bool success = dbus_watch_handle(raw_watch_, DBUS_WATCH_WRITABLE); | |
| 95 CHECK(success) << "Unable to allocate memory"; | |
| 96 } | 90 } |
| 97 | 91 |
| 98 DBusWatch* raw_watch_; | 92 DBusWatch* raw_watch_; |
| 99 base::MessagePumpLibevent::FileDescriptorWatcher file_descriptor_watcher_; | 93 std::unique_ptr<base::FileDescriptorWatcher::Controller> read_watcher_; |
| 94 std::unique_ptr<base::FileDescriptorWatcher::Controller> write_watcher_; | |
| 100 }; | 95 }; |
| 101 | 96 |
| 102 // The class is used for monitoring the timeout used for D-Bus method | 97 // The class is used for monitoring the timeout used for D-Bus method |
| 103 // calls. | 98 // calls. |
| 104 // | 99 // |
| 105 // Unlike Watch, Timeout is a ref counted object, to ensure that |this| of | 100 // Unlike Watch, Timeout is a ref counted object, to ensure that |this| of |
| 106 // the object is is alive when HandleTimeout() is called. It's unlikely | 101 // the object is is alive when HandleTimeout() is called. It's unlikely |
| 107 // but it may be possible that HandleTimeout() is called after | 102 // but it may be possible that HandleTimeout() is called after |
| 108 // Bus::OnRemoveTimeout(). That's why we don't simply delete the object in | 103 // Bus::OnRemoveTimeout(). That's why we don't simply delete the object in |
| 109 // Bus::OnRemoveTimeout(). | 104 // Bus::OnRemoveTimeout(). |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1045 } | 1040 } |
| 1046 | 1041 |
| 1047 void Bus::OnToggleWatch(DBusWatch* raw_watch) { | 1042 void Bus::OnToggleWatch(DBusWatch* raw_watch) { |
| 1048 AssertOnDBusThread(); | 1043 AssertOnDBusThread(); |
| 1049 | 1044 |
| 1050 Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch)); | 1045 Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch)); |
| 1051 if (watch->IsReadyToBeWatched()) { | 1046 if (watch->IsReadyToBeWatched()) { |
| 1052 watch->StartWatching(); | 1047 watch->StartWatching(); |
| 1053 } else { | 1048 } else { |
| 1054 // It's safe to call this if StartWatching() wasn't called, per | 1049 // It's safe to call this if StartWatching() wasn't called, per |
| 1055 // message_pump_libevent.h. | 1050 // message_pump_libevent.h. |
|
satorux1
2017/04/14 01:25:33
update this comment?
fdoray
2017/04/18 12:43:16
Done.
| |
| 1056 watch->StopWatching(); | 1051 watch->StopWatching(); |
| 1057 } | 1052 } |
| 1058 } | 1053 } |
| 1059 | 1054 |
| 1060 dbus_bool_t Bus::OnAddTimeout(DBusTimeout* raw_timeout) { | 1055 dbus_bool_t Bus::OnAddTimeout(DBusTimeout* raw_timeout) { |
| 1061 AssertOnDBusThread(); | 1056 AssertOnDBusThread(); |
| 1062 | 1057 |
| 1063 // timeout will be deleted when raw_timeout is removed in | 1058 // timeout will be deleted when raw_timeout is removed in |
| 1064 // OnRemoveTimeoutThunk(). | 1059 // OnRemoveTimeoutThunk(). |
| 1065 Timeout* timeout = new Timeout(raw_timeout); | 1060 Timeout* timeout = new Timeout(raw_timeout); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 kNameOwnerChangedSignal)) { | 1204 kNameOwnerChangedSignal)) { |
| 1210 Bus* self = static_cast<Bus*>(data); | 1205 Bus* self = static_cast<Bus*>(data); |
| 1211 self->OnServiceOwnerChanged(message); | 1206 self->OnServiceOwnerChanged(message); |
| 1212 } | 1207 } |
| 1213 // Always return unhandled to let others, e.g. ObjectProxies, handle the same | 1208 // Always return unhandled to let others, e.g. ObjectProxies, handle the same |
| 1214 // signal. | 1209 // signal. |
| 1215 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 1210 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 1216 } | 1211 } |
| 1217 | 1212 |
| 1218 } // namespace dbus | 1213 } // namespace dbus |
| OLD | NEW |