diff options
author | ochang <ochang@chromium.org> | 2016-01-12 19:42:10 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-13 03:43:46 +0000 |
commit | bd648ad6116ad3eb09356fb8c34fb006dbe86d4c (patch) | |
tree | 16ac668609a5e32a04e50990af810252357b864b /content/browser/media | |
parent | 245f6c4f3def6b1b8300f80caea7d41d8fafd5ad (diff) | |
download | chromium_src-bd648ad6116ad3eb09356fb8c34fb006dbe86d4c.zip chromium_src-bd648ad6116ad3eb09356fb8c34fb006dbe86d4c.tar.gz chromium_src-bd648ad6116ad3eb09356fb8c34fb006dbe86d4c.tar.bz2 |
Prevent a race condition with MidiHost IPC sending.
EndSession() is moved from MidiHost's destructor into OnChannelClosing() before
the destruction process starts (at which point it is unsafe to call any
functions on the MidiHost/MidiManagerClient).
Also moves a function call on a MidiManagerClient in MidiManager into the AutoLock
scope.
BUG=576383
R=toyoshim@chromium.org,agoode@chromium.org
Review URL: https://codereview.chromium.org/1576323002
Cr-Commit-Position: refs/heads/master@{#369091}
Diffstat (limited to 'content/browser/media')
-rw-r--r-- | content/browser/media/midi_host.cc | 15 | ||||
-rw-r--r-- | content/browser/media/midi_host.h | 1 |
2 files changed, 13 insertions, 3 deletions
diff --git a/content/browser/media/midi_host.cc b/content/browser/media/midi_host.cc index 1e6de1e..30261ef 100644 --- a/content/browser/media/midi_host.cc +++ b/content/browser/media/midi_host.cc @@ -59,10 +59,19 @@ MidiHost::MidiHost(int renderer_process_id, DCHECK(midi_manager_); } -MidiHost::~MidiHost() { - // Close an open session, or abort opening a session. - if (is_session_requested_ && midi_manager_) +MidiHost::~MidiHost() = default; + +void MidiHost::OnChannelClosing() { + // If we get here the MidiHost is going to be destroyed soon. Prevent any + // subsequent calls from MidiManager by closing our session. + // If Send() is called from a different thread (e.g. a separate thread owned + // by the MidiManager implementation), it will get posted to the IO thread. + // There is a race condition here if our refcount is 0 and we're about to or + // have already entered OnDestruct(). + if (is_session_requested_ && midi_manager_) { midi_manager_->EndSession(this); + is_session_requested_ = false; + } } void MidiHost::OnDestruct() const { diff --git a/content/browser/media/midi_host.h b/content/browser/media/midi_host.h index 671bd3c..ca3706c 100644 --- a/content/browser/media/midi_host.h +++ b/content/browser/media/midi_host.h @@ -38,6 +38,7 @@ class CONTENT_EXPORT MidiHost : public BrowserMessageFilter, MidiHost(int renderer_process_id, media::midi::MidiManager* midi_manager); // BrowserMessageFilter implementation. + void OnChannelClosing() override; void OnDestruct() const override; bool OnMessageReceived(const IPC::Message& message) override; |