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

Side by Side Diff: device/hid/hid_connection_linux.cc

Issue 2804313005: Make HidConnection::Read reentrancy safe (Closed)
Patch Set: Rebased. Created 3 years, 8 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 | « device/hid/hid_connection.cc ('k') | device/hid/hid_connection_mac.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) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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/hid/hid_connection_linux.h" 5 #include "device/hid/hid_connection_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/hidraw.h> 8 #include <linux/hidraw.h>
9 #include <sys/ioctl.h> 9 #include <sys/ioctl.h>
10 10
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 // buffer can be used directly. 235 // buffer can be used directly.
236 blocking_task_runner_->PostTask( 236 blocking_task_runner_->PostTask(
237 FROM_HERE, 237 FROM_HERE,
238 base::Bind(&FileThreadHelper::SendFeatureReport, 238 base::Bind(&FileThreadHelper::SendFeatureReport,
239 base::Unretained(helper_.get()), buffer, size, callback)); 239 base::Unretained(helper_.get()), buffer, size, callback));
240 } 240 }
241 241
242 void HidConnectionLinux::ProcessInputReport(scoped_refptr<net::IOBuffer> buffer, 242 void HidConnectionLinux::ProcessInputReport(scoped_refptr<net::IOBuffer> buffer,
243 size_t size) { 243 size_t size) {
244 DCHECK(thread_checker().CalledOnValidThread()); 244 DCHECK(thread_checker().CalledOnValidThread());
245 DCHECK_GE(size, 1u);
246
247 uint8_t report_id = buffer->data()[0];
248 if (IsReportIdProtected(report_id))
249 return;
250
245 PendingHidReport report; 251 PendingHidReport report;
246 report.buffer = buffer; 252 report.buffer = buffer;
247 report.size = size; 253 report.size = size;
248 pending_reports_.push(report); 254 pending_reports_.push(report);
249 ProcessReadQueue(); 255 ProcessReadQueue();
250 } 256 }
251 257
252 void HidConnectionLinux::ProcessReadQueue() { 258 void HidConnectionLinux::ProcessReadQueue() {
253 DCHECK(thread_checker().CalledOnValidThread()); 259 DCHECK(thread_checker().CalledOnValidThread());
260
261 // Hold a reference to |this| to prevent a callback from freeing this object
262 // during the loop.
263 scoped_refptr<HidConnectionLinux> self(this);
254 while (pending_reads_.size() && pending_reports_.size()) { 264 while (pending_reads_.size() && pending_reports_.size()) {
255 PendingHidRead read = pending_reads_.front(); 265 PendingHidRead read = pending_reads_.front();
256 PendingHidReport report = pending_reports_.front(); 266 PendingHidReport report = pending_reports_.front();
257 267
268 pending_reads_.pop();
258 pending_reports_.pop(); 269 pending_reports_.pop();
259 if (CompleteRead(report.buffer, report.size, read.callback)) 270 read.callback.Run(true, report.buffer, report.size);
260 pending_reads_.pop();
261 } 271 }
262 } 272 }
263 273
264 } // namespace device 274 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_connection.cc ('k') | device/hid/hid_connection_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698