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

Side by Side Diff: chrome/browser/usb/usb_device_handle.h

Issue 22492003: Fixes leaking transfer objects due to improper USB handle closure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor fix Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/usb/usb_device.cc ('k') | chrome/browser/usb/usb_device_handle.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #ifndef CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 5 #ifndef CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_
6 #define CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 6 #define CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_
7 7
8 #include <map> 8 #include <map>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "base/threading/thread_checker.h" 14 #include "base/threading/thread_checker.h"
15 #include "chrome/browser/usb/usb_interface.h" 15 #include "chrome/browser/usb/usb_interface.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "net/base/completion_callback.h" 17 #include "net/base/completion_callback.h"
18 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
19 19
20 struct libusb_device_handle; 20 struct libusb_device_handle;
21 struct libusb_iso_packet_descriptor; 21 struct libusb_iso_packet_descriptor;
22 struct libusb_transfer; 22 struct libusb_transfer;
23 23
24 typedef libusb_device_handle* PlatformUsbDeviceHandle; 24 typedef libusb_device_handle* PlatformUsbDeviceHandle;
25 typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor; 25 typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor;
26 typedef libusb_transfer* PlatformUsbTransferHandle; 26 typedef libusb_transfer* PlatformUsbTransferHandle;
27 27
28 class UsbContext;
29 class UsbConfigDescriptor;
28 class UsbDevice; 30 class UsbDevice;
31 class UsbInterface;
32
33 namespace base {
34 class MessageLoopProxy;
35 } // namespace base
29 36
30 namespace net { 37 namespace net {
31 class IOBuffer; 38 class IOBuffer;
32 } // namespace net 39 } // namespace net
33 40
34 enum UsbTransferStatus { 41 enum UsbTransferStatus {
35 USB_TRANSFER_COMPLETED = 0, 42 USB_TRANSFER_COMPLETED = 0,
36 USB_TRANSFER_ERROR, 43 USB_TRANSFER_ERROR,
37 USB_TRANSFER_TIMEOUT, 44 USB_TRANSFER_TIMEOUT,
38 USB_TRANSFER_CANCELLED, 45 USB_TRANSFER_CANCELLED,
39 USB_TRANSFER_STALLED, 46 USB_TRANSFER_STALLED,
40 USB_TRANSFER_DISCONNECT, 47 USB_TRANSFER_DISCONNECT,
41 USB_TRANSFER_OVERFLOW, 48 USB_TRANSFER_OVERFLOW,
42 USB_TRANSFER_LENGTH_SHORT, 49 USB_TRANSFER_LENGTH_SHORT,
43 }; 50 };
44 51
45 typedef base::Callback<void(UsbTransferStatus, scoped_refptr<net::IOBuffer>, 52 typedef base::Callback<void(UsbTransferStatus, scoped_refptr<net::IOBuffer>,
46 size_t)> UsbTransferCallback; 53 size_t)> UsbTransferCallback;
47 54
48 // UsbDeviceHandle class provides basic I/O related functionalities. 55 // UsbDeviceHandle class provides basic I/O related functionalities.
49 class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> { 56 class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> {
50 public: 57 public:
51 enum TransferRequestType { STANDARD, CLASS, VENDOR, RESERVED }; 58 enum TransferRequestType { STANDARD, CLASS, VENDOR, RESERVED };
52 enum TransferRecipient { DEVICE, INTERFACE, ENDPOINT, OTHER }; 59 enum TransferRecipient { DEVICE, INTERFACE, ENDPOINT, OTHER };
53 60
54 scoped_refptr<UsbDevice> device() const; 61 scoped_refptr<UsbDevice> device() const;
55 PlatformUsbDeviceHandle handle() const { return handle_; } 62 PlatformUsbDeviceHandle handle() const { return handle_; }
56 63
57 // Close the USB device and release the underlying platform device. 64 // Notifies UsbDevice to drop the reference of this object; cancels all the
65 // flying transfers.
66 // It is possible that the object has no other reference after this call. So
67 // if it is called using a raw pointer, it could be invalidated.
68 // The platform device handle will be closed when UsbDeviceHandle destructs.
58 virtual void Close(); 69 virtual void Close();
59 70
60 // Device manipulation operations. These methods are blocking and must be 71 // Device manipulation operations. These methods are blocking and must be
61 // called on FILE thread. 72 // called on FILE thread.
62 virtual bool ClaimInterface(const int interface_number); 73 virtual bool ClaimInterface(const int interface_number);
63 virtual bool ReleaseInterface(const int interface_number); 74 virtual bool ReleaseInterface(const int interface_number);
64 virtual bool SetInterfaceAlternateSetting( 75 virtual bool SetInterfaceAlternateSetting(
65 const int interface_number, 76 const int interface_number,
66 const int alternate_setting); 77 const int alternate_setting);
67 virtual bool ResetDevice(); 78 virtual bool ResetDevice();
68 bool GetSerial(base::string16* serial); 79 virtual bool GetSerial(base::string16* serial);
69 80
70 // Async IO. Can be called on any thread. 81 // Async IO. Can be called on any thread.
71 virtual void ControlTransfer(const UsbEndpointDirection direction, 82 virtual void ControlTransfer(const UsbEndpointDirection direction,
72 const TransferRequestType request_type, 83 const TransferRequestType request_type,
73 const TransferRecipient recipient, 84 const TransferRecipient recipient,
74 const uint8 request, 85 const uint8 request,
75 const uint16 value, 86 const uint16 value,
76 const uint16 index, 87 const uint16 index,
77 net::IOBuffer* buffer, 88 net::IOBuffer* buffer,
78 const size_t length, 89 const size_t length,
(...skipping 16 matching lines...) Expand all
95 106
96 virtual void IsochronousTransfer(const UsbEndpointDirection direction, 107 virtual void IsochronousTransfer(const UsbEndpointDirection direction,
97 const uint8 endpoint, 108 const uint8 endpoint,
98 net::IOBuffer* buffer, 109 net::IOBuffer* buffer,
99 const size_t length, 110 const size_t length,
100 const unsigned int packets, 111 const unsigned int packets,
101 const unsigned int packet_length, 112 const unsigned int packet_length,
102 const unsigned int timeout, 113 const unsigned int timeout,
103 const UsbTransferCallback& callback); 114 const UsbTransferCallback& callback);
104 115
105 // Normal code should not call this function. It is called by the platform's
106 // callback mechanism in such a way that it cannot be made private. Invokes
107 // the callbacks associated with a given transfer, and removes it from the
108 // in-flight transfer set.
109 void TransferComplete(PlatformUsbTransferHandle transfer);
110
111 protected: 116 protected:
112 friend class base::RefCountedThreadSafe<UsbDeviceHandle>; 117 friend class base::RefCountedThreadSafe<UsbDeviceHandle>;
113 friend class UsbDevice; 118 friend class UsbDevice;
114 119
115 // This constructor is called by UsbDevice. 120 // This constructor is called by UsbDevice.
116 UsbDeviceHandle(UsbDevice* device, PlatformUsbDeviceHandle handle); 121 UsbDeviceHandle(scoped_refptr<UsbContext> context,
122 UsbDevice* device, PlatformUsbDeviceHandle handle);
117 123
118 // This constructor variant is for use in testing only. 124 // This constructor variant is for use in testing only.
119 UsbDeviceHandle(); 125 UsbDeviceHandle();
120 virtual ~UsbDeviceHandle(); 126 virtual ~UsbDeviceHandle();
121 127
122 UsbDevice* device_; 128 UsbDevice* device_;
123 129
124 private: 130 private:
125 struct Transfer { 131 friend void HandleTransferCompletion(PlatformUsbTransferHandle handle);
126 Transfer();
127 ~Transfer();
128 132
129 UsbTransferType transfer_type; 133 class InterfaceClaimer;
130 scoped_refptr<net::IOBuffer> buffer; 134 struct Transfer;
131 size_t length; 135
132 UsbTransferCallback callback; 136 // Refresh endpoint_map_ after ClaimInterface, ReleaseInterface and
133 }; 137 // SetInterfaceAlternateSetting.
138 void RefreshEndpointMap();
134 139
135 // Submits a transfer and starts tracking it. Retains the buffer and copies 140 // Submits a transfer and starts tracking it. Retains the buffer and copies
136 // the completion callback until the transfer finishes, whereupon it invokes 141 // the completion callback until the transfer finishes, whereupon it invokes
137 // the callback then releases the buffer. 142 // the callback then releases the buffer.
138 void SubmitTransfer(PlatformUsbTransferHandle handle, 143 void SubmitTransfer(PlatformUsbTransferHandle handle,
139 UsbTransferType transfer_type, 144 UsbTransferType transfer_type,
140 net::IOBuffer* buffer, 145 net::IOBuffer* buffer,
141 const size_t length, 146 const size_t length,
147 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
142 const UsbTransferCallback& callback); 148 const UsbTransferCallback& callback);
143 149
144 // Close the current device handle without inform the corresponding UsbDevice. 150 // Invokes the callbacks associated with a given transfer, and removes it from
151 // the in-flight transfer set.
152 void TransferComplete(PlatformUsbTransferHandle transfer);
153
154 // Informs the object to drop internal references.
145 void InternalClose(); 155 void InternalClose();
146 156
147 PlatformUsbDeviceHandle handle_; 157 PlatformUsbDeviceHandle handle_;
148 158
149 // transfers_ tracks all in-flight transfers associated with this device, 159 scoped_refptr<UsbConfigDescriptor> interfaces_;
150 // allowing the device to retain the buffer and callback associated with a 160
151 // transfer until such time that it completes. It is protected by lock_. 161 typedef std::map<int, scoped_refptr<InterfaceClaimer> > ClaimedInterfaceMap;
152 base::Lock lock_; 162 ClaimedInterfaceMap claimed_interfaces_;
153 std::map<PlatformUsbTransferHandle, Transfer> transfers_; 163
164 typedef std::map<PlatformUsbTransferHandle, Transfer> TransferMap;
165 TransferMap transfers_;
166
167 // A map from endpoints to interfaces
168 typedef std::map<int, int> EndpointMap;
169 EndpointMap endpoint_map_;
170
171 // Retain the UsbContext so that the platform context will not be destroyed
172 // before this handle.
173 scoped_refptr<UsbContext> context_;
154 174
155 base::ThreadChecker thread_checker_; 175 base::ThreadChecker thread_checker_;
156 176
157 DISALLOW_COPY_AND_ASSIGN(UsbDeviceHandle); 177 DISALLOW_COPY_AND_ASSIGN(UsbDeviceHandle);
158 }; 178 };
159 179
160 #endif // CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 180 #endif // CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_
OLDNEW
« no previous file with comments | « chrome/browser/usb/usb_device.cc ('k') | chrome/browser/usb/usb_device_handle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698