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

Side by Side Diff: device/base/device_monitor_linux.cc

Issue 2433933004: Leak DeviceMonitorLinux on shutdown. (Closed)
Patch Set: fix build error Created 4 years, 2 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698