diff options
author | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 15:30:20 +0000 |
---|---|---|
committer | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-27 15:30:20 +0000 |
commit | 783d5d78ebcfe0b87bc97f6c7b24fcd8e2c433e8 (patch) | |
tree | 874ea876e5d2e391306608b750375cdf36eb12d3 | |
parent | 232e09d18fa339b9dcb49f30d2e919fe673da1c5 (diff) | |
download | chromium_src-783d5d78ebcfe0b87bc97f6c7b24fcd8e2c433e8.zip chromium_src-783d5d78ebcfe0b87bc97f6c7b24fcd8e2c433e8.tar.gz chromium_src-783d5d78ebcfe0b87bc97f6c7b24fcd8e2c433e8.tar.bz2 |
Web MIDI: fix multi-threading problem around message buffer handling
Passing message buffer to another thread as const uint8* doesn't work
since it might be invalid before another thread reads it.
Keep on handling it as vector<uint8> from IPC to passing it to the OS.
TEST=manual
BUG=276810
Review URL: https://chromiumcodereview.appspot.com/23379002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@219796 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/renderer_host/media/midi_host.cc | 11 | ||||
-rw-r--r-- | content/browser/renderer_host/media/midi_host.h | 6 | ||||
-rw-r--r-- | content/common/media/midi_messages.h | 6 | ||||
-rw-r--r-- | content/renderer/media/midi_message_filter.cc | 8 | ||||
-rw-r--r-- | content/renderer/media/midi_message_filter.h | 9 | ||||
-rw-r--r-- | media/midi/midi_manager.cc | 14 | ||||
-rw-r--r-- | media/midi/midi_manager.h | 26 | ||||
-rw-r--r-- | media/midi/midi_manager_mac.cc | 36 | ||||
-rw-r--r-- | media/midi/midi_manager_mac.h | 12 |
9 files changed, 66 insertions, 62 deletions
diff --git a/content/browser/renderer_host/media/midi_host.cc b/content/browser/renderer_host/media/midi_host.cc index b0b0e76..9bf49a5 100644 --- a/content/browser/renderer_host/media/midi_host.cc +++ b/content/browser/renderer_host/media/midi_host.cc @@ -88,7 +88,7 @@ void MIDIHost::OnStartSession(int client_id) { output_ports)); } -void MIDIHost::OnSendData(int port, +void MIDIHost::OnSendData(uint32 port, const std::vector<uint8>& data, double timestamp) { if (!midi_manager_) @@ -111,20 +111,19 @@ void MIDIHost::OnSendData(int port, // this client access. We'll likely need to pass a GURL // here to compare against our permissions. if (data[0] >= kSysExMessage) - return; + return; midi_manager_->DispatchSendMIDIData( this, port, - &data[0], - data.size(), + data, timestamp); sent_bytes_in_flight_ += data.size(); } void MIDIHost::ReceiveMIDIData( - int port_index, + uint32 port, const uint8* data, size_t length, double timestamp) { @@ -140,7 +139,7 @@ void MIDIHost::ReceiveMIDIData( // Send to the renderer. std::vector<uint8> v(data, data + length); - Send(new MIDIMsg_DataReceived(port_index, v, timestamp)); + Send(new MIDIMsg_DataReceived(port, v, timestamp)); } void MIDIHost::AccumulateMIDIBytesSent(size_t n) { diff --git a/content/browser/renderer_host/media/midi_host.h b/content/browser/renderer_host/media/midi_host.h index f6b2813..1e08829 100644 --- a/content/browser/renderer_host/media/midi_host.h +++ b/content/browser/renderer_host/media/midi_host.h @@ -5,6 +5,8 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_HOST_H_ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MIDI_HOST_H_ +#include <vector> + #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" @@ -33,7 +35,7 @@ class CONTENT_EXPORT MIDIHost // MIDIManagerClient implementation. virtual void ReceiveMIDIData( - int port_index, + uint32 port, const uint8* data, size_t length, double timestamp) OVERRIDE; @@ -43,7 +45,7 @@ class CONTENT_EXPORT MIDIHost void OnStartSession(int client_id); // Data to be sent to a MIDI output port. - void OnSendData(int port, + void OnSendData(uint32 port, const std::vector<uint8>& data, double timestamp); diff --git a/content/common/media/midi_messages.h b/content/common/media/midi_messages.h index 86e5c16..bff0241 100644 --- a/content/common/media/midi_messages.h +++ b/content/common/media/midi_messages.h @@ -43,7 +43,7 @@ IPC_MESSAGE_CONTROL1(MIDIHostMsg_StartSession, int /* client id */) IPC_MESSAGE_CONTROL3(MIDIHostMsg_SendData, - int /* port */, + uint32 /* port */, std::vector<uint8> /* data */, double /* timestamp */) @@ -56,9 +56,9 @@ IPC_MESSAGE_CONTROL4(MIDIMsg_SessionStarted, media::MIDIPortInfoList /* output ports */) IPC_MESSAGE_CONTROL3(MIDIMsg_DataReceived, - int /* port */, + uint32 /* port */, std::vector<uint8> /* data */, double /* timestamp */) IPC_MESSAGE_CONTROL1(MIDIMsg_AcknowledgeSentData, - size_t /* bytes sent */) + uint32 /* bytes sent */) diff --git a/content/renderer/media/midi_message_filter.cc b/content/renderer/media/midi_message_filter.cc index 4ffddad..1b2e04a 100644 --- a/content/renderer/media/midi_message_filter.cc +++ b/content/renderer/media/midi_message_filter.cc @@ -153,7 +153,7 @@ MIDIMessageFilter::GetClientFromId(int client_id) { return NULL; } -void MIDIMessageFilter::OnDataReceived(int port, +void MIDIMessageFilter::OnDataReceived(uint32 port, const std::vector<uint8>& data, double timestamp) { TRACE_EVENT0("midi", "MIDIMessageFilter::OnDataReceived"); @@ -170,7 +170,7 @@ void MIDIMessageFilter::OnAcknowledgeSentData(size_t bytes_sent) { unacknowledged_bytes_sent_ -= bytes_sent; } -void MIDIMessageFilter::HandleDataReceived(int port, +void MIDIMessageFilter::HandleDataReceived(uint32 port, const std::vector<uint8>& data, double timestamp) { TRACE_EVENT0("midi", "MIDIMessageFilter::HandleDataReceived"); @@ -184,7 +184,7 @@ void MIDIMessageFilter::HandleDataReceived(int port, #endif } -void MIDIMessageFilter::SendMIDIData(int port, +void MIDIMessageFilter::SendMIDIData(uint32 port, const uint8* data, size_t length, double timestamp) { @@ -200,7 +200,7 @@ void MIDIMessageFilter::SendMIDIData(int port, port, v, timestamp)); } -void MIDIMessageFilter::SendMIDIDataOnIOThread(int port, +void MIDIMessageFilter::SendMIDIDataOnIOThread(uint32 port, const std::vector<uint8>& data, double timestamp) { size_t n = data.size(); diff --git a/content/renderer/media/midi_message_filter.h b/content/renderer/media/midi_message_filter.h index cf969e9..4b8481f 100644 --- a/content/renderer/media/midi_message_filter.h +++ b/content/renderer/media/midi_message_filter.h @@ -12,7 +12,6 @@ #include "content/common/content_export.h" #include "ipc/ipc_channel_proxy.h" #include "media/midi/midi_port_info.h" -#include "third_party/WebKit/public/platform/WebMIDIAccessor.h" #include "third_party/WebKit/public/platform/WebMIDIAccessorClient.h" namespace base { @@ -37,7 +36,7 @@ class CONTENT_EXPORT MIDIMessageFilter // A client will only be able to call this method if it has a suitable // output port (from addOutputPort()). - void SendMIDIData(int port, + void SendMIDIData(uint32 port, const uint8* data, size_t length, double timestamp); @@ -69,7 +68,7 @@ class CONTENT_EXPORT MIDIMessageFilter // Called when the browser process has sent MIDI data containing one or // more messages. - void OnDataReceived(int port, + void OnDataReceived(uint32 port, const std::vector<uint8>& data, double timestamp); @@ -83,13 +82,13 @@ class CONTENT_EXPORT MIDIMessageFilter media::MIDIPortInfoList inputs, media::MIDIPortInfoList outputs); - void HandleDataReceived(int port, + void HandleDataReceived(uint32 port, const std::vector<uint8>& data, double timestamp); void StartSessionOnIOThread(int client_id); - void SendMIDIDataOnIOThread(int port, + void SendMIDIDataOnIOThread(uint32 port, const std::vector<uint8>& data, double timestamp); diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc index 05fcfa4..b3262e4 100644 --- a/media/midi/midi_manager.cc +++ b/media/midi/midi_manager.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/message_loop/message_loop.h" #include "base/threading/thread.h" namespace media { @@ -52,7 +53,7 @@ void MIDIManager::AddOutputPort(const MIDIPortInfo& info) { } void MIDIManager::ReceiveMIDIData( - int port_index, + uint32 port_index, const uint8* data, size_t length, double timestamp) { @@ -62,10 +63,13 @@ void MIDIManager::ReceiveMIDIData( (*i)->ReceiveMIDIData(port_index, data, length, timestamp); } +bool MIDIManager::CurrentlyOnMIDISendThread() { + return send_thread_->message_loop() == base::MessageLoop::current(); +} + void MIDIManager::DispatchSendMIDIData(MIDIManagerClient* client, - int port_index, - const uint8* data, - size_t length, + uint32 port_index, + const std::vector<uint8>& data, double timestamp) { // Lazily create the thread when first needed. if (!send_thread_) { @@ -77,7 +81,7 @@ void MIDIManager::DispatchSendMIDIData(MIDIManagerClient* client, send_message_loop_->PostTask( FROM_HERE, base::Bind(&MIDIManager::SendMIDIData, base::Unretained(this), - client, port_index, data, length, timestamp)); + client, port_index, data, timestamp)); } } // namespace media diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h index c2b26ab..6a301a9 100644 --- a/media/midi/midi_manager.h +++ b/media/midi/midi_manager.h @@ -6,6 +6,7 @@ #define MEDIA_MIDI_MIDI_MANAGER_H_ #include <set> +#include <vector> #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" @@ -33,7 +34,7 @@ class MEDIA_EXPORT MIDIManagerClient { // |data| represents a series of bytes encoding one or more MIDI messages. // |length| is the number of bytes in |data|. // |timestamp| is the time the data was received, in seconds. - virtual void ReceiveMIDIData(int port_index, + virtual void ReceiveMIDIData(uint32 port_index, const uint8* data, size_t length, double timestamp) = 0; @@ -70,9 +71,8 @@ class MEDIA_EXPORT MIDIManager { // |timestamp| is the time to send the data, in seconds. A value of 0 // means send "now" or as soon as possible. void DispatchSendMIDIData(MIDIManagerClient* client, - int port_index, - const uint8* data, - size_t length, + uint32 port_index, + const std::vector<uint8>& data, double timestamp); // input_ports() is a list of MIDI ports for receiving MIDI data. @@ -90,21 +90,23 @@ class MEDIA_EXPORT MIDIManager { virtual bool Initialize() = 0; // Implements the platform-specific details of sending MIDI data. + // This function runs on MIDISendThread. virtual void SendMIDIData(MIDIManagerClient* client, - int port_index, - const uint8* data, - size_t length, + uint32 port_index, + const std::vector<uint8>& data, double timestamp) = 0; void AddInputPort(const MIDIPortInfo& info); void AddOutputPort(const MIDIPortInfo& info); // Dispatches to all clients. - void ReceiveMIDIData( - int port_index, - const uint8* data, - size_t length, - double timestamp); + void ReceiveMIDIData(uint32 port_index, + const uint8* data, + size_t length, + double timestamp); + + // Checks if current thread is MIDISendThread. + bool CurrentlyOnMIDISendThread(); bool initialized_; diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc index 7bc8f23..4477944 100644 --- a/media/midi/midi_manager_mac.cc +++ b/media/midi/midi_manager_mac.cc @@ -54,7 +54,7 @@ bool MIDIManagerMac::Initialize() { result = MIDIInputPortCreate( midi_client_, CFSTR("MIDI Input"), - ReadMidiDispatch, + ReadMIDIDispatch, this, &coremidi_input_); if (result != noErr) @@ -67,10 +67,10 @@ bool MIDIManagerMac::Initialize() { if (result != noErr) return false; - int destination_count = MIDIGetNumberOfDestinations(); + uint32 destination_count = MIDIGetNumberOfDestinations(); destinations_.resize(destination_count); - for (int i = 0; i < destination_count ; i++) { + for (uint32 i = 0; i < destination_count ; i++) { MIDIEndpointRef destination = MIDIGetDestination(i); // Keep track of all destinations (known as outputs by the Web MIDI API). @@ -82,9 +82,9 @@ bool MIDIManagerMac::Initialize() { } // Open connections from all sources. - int source_count = MIDIGetNumberOfSources(); + uint32 source_count = MIDIGetNumberOfSources(); - for (int i = 0; i < source_count; ++i) { + for (uint32 i = 0; i < source_count; ++i) { // Receive from all sources. MIDIEndpointRef src = MIDIGetSource(i); MIDIPortConnectSource(coremidi_input_, src, reinterpret_cast<void*>(src)); @@ -110,7 +110,7 @@ MIDIManagerMac::~MIDIManagerMac() { MIDIPortDispose(coremidi_output_); } -void MIDIManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, +void MIDIManagerMac::ReadMIDIDispatch(const MIDIPacketList* packet_list, void* read_proc_refcon, void* src_conn_refcon) { MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon); @@ -121,16 +121,16 @@ void MIDIManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, #endif // Dispatch to class method. - manager->ReadMidi(source, packet_list); + manager->ReadMIDI(source, packet_list); } -void MIDIManagerMac::ReadMidi(MIDIEndpointRef source, +void MIDIManagerMac::ReadMIDI(MIDIEndpointRef source, const MIDIPacketList* packet_list) { // Lookup the port index based on the source. SourceMap::iterator j = source_map_.find(source); if (j == source_map_.end()) return; - int port_index = source_map_[source]; + uint32 port_index = source_map_[source]; // Go through each packet and process separately. for(size_t i = 0; i < packet_list->numPackets; i++) { @@ -147,10 +147,11 @@ void MIDIManagerMac::ReadMidi(MIDIEndpointRef source, } void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, - int port_index, - const uint8* data, - size_t length, + uint32 port_index, + const std::vector<uint8>& data, double timestamp) { + DCHECK(CurrentlyOnMIDISendThread()); + // System Exclusive has already been filtered. MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); @@ -159,14 +160,11 @@ void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, kMaxPacketListSize, midi_packet_, coremidi_timestamp, - length, - data); + data.size(), + &data[0]); // Lookup the destination based on the port index. - // TODO(crogers): re-factor |port_index| to use unsigned - // to avoid the need for this check. - if (port_index < 0 || - static_cast<size_t>(port_index) >= destinations_.size()) + if (static_cast<size_t>(port_index) >= destinations_.size()) return; MIDIEndpointRef destination = destinations_[port_index]; @@ -176,7 +174,7 @@ void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, // Re-initialize for next time. midi_packet_ = MIDIPacketListInit(packet_list_); - client->AccumulateMIDIBytesSent(length); + client->AccumulateMIDIBytesSent(data.size()); } MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint( diff --git a/media/midi/midi_manager_mac.h b/media/midi/midi_manager_mac.h index ed7b524..2397b80 100644 --- a/media/midi/midi_manager_mac.h +++ b/media/midi/midi_manager_mac.h @@ -8,6 +8,7 @@ #include <CoreMIDI/MIDIServices.h> #include <map> #include <string> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -24,20 +25,19 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager { // MIDIManager implementation. virtual bool Initialize() OVERRIDE; virtual void SendMIDIData(MIDIManagerClient* client, - int port_index, - const uint8* data, - size_t length, + uint32 port_index, + const std::vector<uint8>& data, double timestamp) OVERRIDE; private: // CoreMIDI callback for MIDI data. // Each callback can contain multiple packets, each of which can contain // multiple MIDI messages. - static void ReadMidiDispatch( + static void ReadMIDIDispatch( const MIDIPacketList *pktlist, void *read_proc_refcon, void *src_conn_refcon); - virtual void ReadMidi(MIDIEndpointRef source, const MIDIPacketList *pktlist); + virtual void ReadMIDI(MIDIEndpointRef source, const MIDIPacketList *pktlist); // Helper static media::MIDIPortInfo GetPortInfoFromEndpoint(MIDIEndpointRef endpoint); @@ -54,7 +54,7 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager { MIDIPacketList* packet_list_; MIDIPacket* midi_packet_; - typedef std::map<MIDIEndpointRef, int> SourceMap; + typedef std::map<MIDIEndpointRef, uint32> SourceMap; // Keeps track of the index (0-based) for each of our sources. SourceMap source_map_; |