OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "device/base/device_monitor_linux.h" | 5 #include "device/base/device_monitor_linux.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/threading/thread_restrictions.h" | 12 #include "base/threading/thread_restrictions.h" |
13 #include "device/udev_linux/udev.h" | 13 #include "device/udev_linux/udev.h" |
14 | 14 |
15 namespace device { | 15 namespace device { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 const char kUdevName[] = "udev"; | 19 const char kUdevName[] = "udev"; |
20 const char kUdevActionAdd[] = "add"; | 20 const char kUdevActionAdd[] = "add"; |
21 const char kUdevActionRemove[] = "remove"; | 21 const char kUdevActionRemove[] = "remove"; |
22 | 22 |
23 // The instance will be reset when message loop destroys. | 23 // The instance will be reset when message loop destroys. |
24 base::LazyInstance<std::unique_ptr<DeviceMonitorLinux>>::Leaky | 24 base::LazyInstance<DeviceMonitorLinux>::Leaky g_device_monitor_linux = |
25 g_device_monitor_linux_ptr = LAZY_INSTANCE_INITIALIZER; | 25 LAZY_INSTANCE_INITIALIZER; |
26 | 26 |
27 } // namespace | 27 } // namespace |
28 | 28 |
29 DeviceMonitorLinux::DeviceMonitorLinux() : monitor_fd_(-1) { | 29 DeviceMonitorLinux::DeviceMonitorLinux() : monitor_fd_(-1) { |
30 base::ThreadRestrictions::AssertIOAllowed(); | 30 base::ThreadRestrictions::AssertIOAllowed(); |
31 base::MessageLoop::current()->AddDestructionObserver(this); | 31 base::MessageLoop::current()->AddDestructionObserver(this); |
32 | 32 |
33 udev_.reset(udev_new()); | 33 udev_.reset(udev_new()); |
34 if (!udev_) { | 34 if (!udev_) { |
35 LOG(ERROR) << "Failed to create udev."; | 35 LOG(ERROR) << "Failed to create udev."; |
(...skipping 18 matching lines...) Expand all Loading... |
54 } | 54 } |
55 | 55 |
56 monitor_watch_controller_ = base::FileDescriptorWatcher::WatchReadable( | 56 monitor_watch_controller_ = base::FileDescriptorWatcher::WatchReadable( |
57 monitor_fd_, | 57 monitor_fd_, |
58 base::Bind(&DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking, | 58 base::Bind(&DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking, |
59 base::Unretained(this))); | 59 base::Unretained(this))); |
60 } | 60 } |
61 | 61 |
62 // static | 62 // static |
63 DeviceMonitorLinux* DeviceMonitorLinux::GetInstance() { | 63 DeviceMonitorLinux* DeviceMonitorLinux::GetInstance() { |
64 if (!g_device_monitor_linux_ptr.Get().get()) | 64 return g_device_monitor_linux.Pointer(); |
65 g_device_monitor_linux_ptr.Get().reset(new DeviceMonitorLinux()); | |
66 return g_device_monitor_linux_ptr.Get().get(); | |
67 } | 65 } |
68 | 66 |
69 void DeviceMonitorLinux::AddObserver(Observer* observer) { | 67 void DeviceMonitorLinux::AddObserver(Observer* observer) { |
70 DCHECK(thread_checker_.CalledOnValidThread()); | 68 DCHECK(thread_checker_.CalledOnValidThread()); |
71 observers_.AddObserver(observer); | 69 observers_.AddObserver(observer); |
72 } | 70 } |
73 | 71 |
74 void DeviceMonitorLinux::RemoveObserver(Observer* observer) { | 72 void DeviceMonitorLinux::RemoveObserver(Observer* observer) { |
75 DCHECK(thread_checker_.CalledOnValidThread()); | 73 DCHECK(thread_checker_.CalledOnValidThread()); |
76 observers_.RemoveObserver(observer); | 74 observers_.RemoveObserver(observer); |
(...skipping 29 matching lines...) Expand all Loading... |
106 udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i))); | 104 udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i))); |
107 if (device) | 105 if (device) |
108 callback.Run(device.get()); | 106 callback.Run(device.get()); |
109 } | 107 } |
110 } | 108 } |
111 | 109 |
112 void DeviceMonitorLinux::WillDestroyCurrentMessageLoop() { | 110 void DeviceMonitorLinux::WillDestroyCurrentMessageLoop() { |
113 DCHECK(thread_checker_.CalledOnValidThread()); | 111 DCHECK(thread_checker_.CalledOnValidThread()); |
114 for (auto& observer : observers_) | 112 for (auto& observer : observers_) |
115 observer.WillDestroyMonitorMessageLoop(); | 113 observer.WillDestroyMonitorMessageLoop(); |
116 g_device_monitor_linux_ptr.Get().reset(nullptr); | |
117 } | 114 } |
118 | 115 |
119 DeviceMonitorLinux::~DeviceMonitorLinux() { | 116 DeviceMonitorLinux::~DeviceMonitorLinux() { |
120 DCHECK(thread_checker_.CalledOnValidThread()); | 117 // A leaky LazyInstance is never destroyed. |
121 base::MessageLoop::current()->RemoveDestructionObserver(this); | 118 NOTREACHED(); |
122 close(monitor_fd_); | |
123 } | 119 } |
124 | 120 |
125 void DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking() { | 121 void DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking() { |
126 DCHECK(thread_checker_.CalledOnValidThread()); | 122 DCHECK(thread_checker_.CalledOnValidThread()); |
127 | 123 |
128 ScopedUdevDevicePtr device(udev_monitor_receive_device(monitor_.get())); | 124 ScopedUdevDevicePtr device(udev_monitor_receive_device(monitor_.get())); |
129 if (!device) | 125 if (!device) |
130 return; | 126 return; |
131 | 127 |
132 std::string action(udev_device_get_action(device.get())); | 128 std::string action(udev_device_get_action(device.get())); |
133 if (action == kUdevActionAdd) { | 129 if (action == kUdevActionAdd) { |
134 for (auto& observer : observers_) | 130 for (auto& observer : observers_) |
135 observer.OnDeviceAdded(device.get()); | 131 observer.OnDeviceAdded(device.get()); |
136 } else if (action == kUdevActionRemove) { | 132 } else if (action == kUdevActionRemove) { |
137 for (auto& observer : observers_) | 133 for (auto& observer : observers_) |
138 observer.OnDeviceRemoved(device.get()); | 134 observer.OnDeviceRemoved(device.get()); |
139 } | 135 } |
140 } | 136 } |
141 | 137 |
142 } // namespace device | 138 } // namespace device |
OLD | NEW |