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

Side by Side Diff: content/browser/media/midi_host.cc

Issue 1576323002: Prevent a race condition with MidiHost IPC sending. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor comment nit Created 4 years, 11 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 | « content/browser/media/midi_host.h ('k') | 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 (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 #include "content/browser/media/midi_host.h" 5 #include "content/browser/media/midi_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/process/process.h" 9 #include "base/process/process.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 48
49 MidiHost::MidiHost(int renderer_process_id, 49 MidiHost::MidiHost(int renderer_process_id,
50 media::midi::MidiManager* midi_manager) 50 media::midi::MidiManager* midi_manager)
51 : BrowserMessageFilter(MidiMsgStart), 51 : BrowserMessageFilter(MidiMsgStart),
52 renderer_process_id_(renderer_process_id), 52 renderer_process_id_(renderer_process_id),
53 has_sys_ex_permission_(false), 53 has_sys_ex_permission_(false),
54 is_session_requested_(false), 54 is_session_requested_(false),
55 midi_manager_(midi_manager), 55 midi_manager_(midi_manager),
56 sent_bytes_in_flight_(0), 56 sent_bytes_in_flight_(0),
57 bytes_sent_since_last_acknowledgement_(0), 57 bytes_sent_since_last_acknowledgement_(0),
58 output_port_count_(0) { 58 output_port_count_(0),
59 is_channel_closing_(false) {
59 DCHECK(midi_manager_); 60 DCHECK(midi_manager_);
60 } 61 }
61 62
62 MidiHost::~MidiHost() { 63 MidiHost::~MidiHost() {
63 // Close an open session, or abort opening a session. 64 // Close an open session, or abort opening a session.
64 if (is_session_requested_ && midi_manager_) 65 if (is_session_requested_ && midi_manager_)
65 midi_manager_->EndSession(this); 66 midi_manager_->EndSession(this);
66 } 67 }
67 68
69 void MidiHost::OnChannelClosing() {
70 // If we get here the MidiHost is going to be destroyed soon. Prevent any
Takashi Toyoshima 2016/01/12 10:20:51 Can we fix the problem by just calling midi_manage
Oliver Chang 2016/01/12 16:38:11 Good point, I changed this to EndSession instead.
71 // subsequent Send() calls.
72 // If Send() is called from a different thread (e.g. a separate thread owned
73 // by the MidiManager implementation), it will get posted to the IO thread.
74 // There is a race condition here if our refcount is 0 and we're about to or
75 // have already entered OnDestruct().
76 base::AutoLock auto_lock(is_channel_closing_lock_);
77 is_channel_closing_ = true;
78 }
79
68 void MidiHost::OnDestruct() const { 80 void MidiHost::OnDestruct() const {
69 BrowserThread::DeleteOnIOThread::Destruct(this); 81 BrowserThread::DeleteOnIOThread::Destruct(this);
70 } 82 }
71 83
72 // IPC Messages handler 84 // IPC Messages handler
73 bool MidiHost::OnMessageReceived(const IPC::Message& message) { 85 bool MidiHost::OnMessageReceived(const IPC::Message& message) {
74 bool handled = true; 86 bool handled = true;
75 IPC_BEGIN_MESSAGE_MAP(MidiHost, message) 87 IPC_BEGIN_MESSAGE_MAP(MidiHost, message)
76 IPC_MESSAGE_HANDLER(MidiHostMsg_StartSession, OnStartSession) 88 IPC_MESSAGE_HANDLER(MidiHostMsg_StartSession, OnStartSession)
77 IPC_MESSAGE_HANDLER(MidiHostMsg_SendData, OnSendData) 89 IPC_MESSAGE_HANDLER(MidiHostMsg_SendData, OnSendData)
78 IPC_MESSAGE_HANDLER(MidiHostMsg_EndSession, OnEndSession) 90 IPC_MESSAGE_HANDLER(MidiHostMsg_EndSession, OnEndSession)
79 IPC_MESSAGE_UNHANDLED(handled = false) 91 IPC_MESSAGE_UNHANDLED(handled = false)
80 IPC_END_MESSAGE_MAP() 92 IPC_END_MESSAGE_MAP()
81 93
82 return handled; 94 return handled;
83 } 95 }
84 96
97 bool MidiHost::Send(IPC::Message* msg) {
98 base::AutoLock auto_lock(is_channel_closing_lock_);
99 if (!is_channel_closing_)
100 return BrowserMessageFilter::Send(msg);
101
102 return false;
103 }
104
85 void MidiHost::OnStartSession() { 105 void MidiHost::OnStartSession() {
86 is_session_requested_ = true; 106 is_session_requested_ = true;
87 if (midi_manager_) 107 if (midi_manager_)
88 midi_manager_->StartSession(this); 108 midi_manager_->StartSession(this);
89 } 109 }
90 110
91 void MidiHost::OnSendData(uint32_t port, 111 void MidiHost::OnSendData(uint32_t port,
92 const std::vector<uint8_t>& data, 112 const std::vector<uint8_t>& data,
93 double timestamp) { 113 double timestamp) {
94 { 114 {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 269 }
250 waiting_data_length = media::midi::GetMidiMessageLength(current); 270 waiting_data_length = media::midi::GetMidiMessageLength(current);
251 if (waiting_data_length == 0) 271 if (waiting_data_length == 0)
252 return false; // Error: |current| should have been a valid status byte. 272 return false; // Error: |current| should have been a valid status byte.
253 --waiting_data_length; // Found status byte 273 --waiting_data_length; // Found status byte
254 } 274 }
255 return waiting_data_length == 0 && !in_sysex; 275 return waiting_data_length == 0 && !in_sysex;
256 } 276 }
257 277
258 } // namespace content 278 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/midi_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698