summaryrefslogtreecommitdiffstats
path: root/media/midi
diff options
context:
space:
mode:
authoryukawa@chromium.org <yukawa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 15:42:41 +0000
committeryukawa@chromium.org <yukawa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 15:42:41 +0000
commitc395a3a6a87f4096cbb11df7833336389b041e5b (patch)
tree5833d5a20b5c9a3b3ccc942ff8fc9ee33e45295b /media/midi
parent3ef32f15ca6c87b6375dd9b96f4adfa07e844361 (diff)
downloadchromium_src-c395a3a6a87f4096cbb11df7833336389b041e5b.zip
chromium_src-c395a3a6a87f4096cbb11df7833336389b041e5b.tar.gz
chromium_src-c395a3a6a87f4096cbb11df7833336389b041e5b.tar.bz2
Make MIDIManager::DispatchSendMIDIData pure virtual.
With this CL, each OS-specific implementation of MIDIManager is responsible for implementing DispatchSendMIDIData() as a non-blocking function. Main motivations of this change are: - Whether non-blocking implementation of DispatchSendMIDIData() requires a background thread or not depends on MIDI APIs on each platform. - If the base class owns a background thread and the actual dispatch method is overridden by each implementation class, such background thread must be terminated *before* the subclass destructor() is finished to avoid pure virtual function call. This is a trick requirement in resource cleanup order that we'd like to avoid. BUG=303599 TEST=manually done on Mac Review URL: https://codereview.chromium.org/97583002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238703 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/midi')
-rw-r--r--media/midi/midi_manager.cc26
-rw-r--r--media/midi/midi_manager.h34
-rw-r--r--media/midi/midi_manager_mac.cc24
-rw-r--r--media/midi/midi_manager_mac.h18
4 files changed, 45 insertions, 57 deletions
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index b3262e4..ef9f473 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -6,8 +6,6 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread.h"
namespace media {
@@ -22,7 +20,8 @@ MIDIManager::MIDIManager()
: initialized_(false) {
}
-MIDIManager::~MIDIManager() {}
+MIDIManager::~MIDIManager() {
+}
bool MIDIManager::StartSession(MIDIManagerClient* client) {
// Lazily initialize the MIDI back-end.
@@ -63,25 +62,4 @@ 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,
- uint32 port_index,
- const std::vector<uint8>& data,
- double timestamp) {
- // Lazily create the thread when first needed.
- if (!send_thread_) {
- send_thread_.reset(new base::Thread("MIDISendThread"));
- send_thread_->Start();
- send_message_loop_ = send_thread_->message_loop_proxy();
- }
-
- send_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&MIDIManager::SendMIDIData, base::Unretained(this),
- client, port_index, data, timestamp));
-}
-
} // namespace media
diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h
index 6a301a9..f42a40d 100644
--- a/media/midi/midi_manager.h
+++ b/media/midi/midi_manager.h
@@ -9,16 +9,10 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "media/base/media_export.h"
#include "media/midi/midi_port_info.h"
-namespace base {
-class Thread;
-}
-
namespace media {
// A MIDIManagerClient registers with the MIDIManager to receive MIDI data.
@@ -63,17 +57,18 @@ class MEDIA_EXPORT MIDIManager {
// A client calls ReleaseSession() to stop receiving MIDI data.
void EndSession(MIDIManagerClient* client);
- // DispatchSendMIDIData() schedules one or more messages to be sent
- // at the given time on a dedicated thread.
+ // DispatchSendMIDIData() is called when MIDI data should be sent to the MIDI
+ // system.
+ // This method is supposed to return immediately and should not block.
// |port_index| represents the specific output port from output_ports().
// |data| represents a series of bytes encoding one or more MIDI messages.
// |length| is the number of bytes in |data|.
// |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,
- uint32 port_index,
- const std::vector<uint8>& data,
- double timestamp);
+ virtual void DispatchSendMIDIData(MIDIManagerClient* client,
+ uint32 port_index,
+ const std::vector<uint8>& data,
+ double timestamp) = 0;
// input_ports() is a list of MIDI ports for receiving MIDI data.
// Each individual port in this list can be identified by its
@@ -89,13 +84,6 @@ class MEDIA_EXPORT MIDIManager {
// Initializes the MIDI system, returning |true| on success.
virtual bool Initialize() = 0;
- // Implements the platform-specific details of sending MIDI data.
- // This function runs on MIDISendThread.
- virtual void SendMIDIData(MIDIManagerClient* client,
- uint32 port_index,
- const std::vector<uint8>& data,
- double timestamp) = 0;
-
void AddInputPort(const MIDIPortInfo& info);
void AddOutputPort(const MIDIPortInfo& info);
@@ -105,9 +93,6 @@ class MEDIA_EXPORT MIDIManager {
size_t length,
double timestamp);
- // Checks if current thread is MIDISendThread.
- bool CurrentlyOnMIDISendThread();
-
bool initialized_;
// Keeps track of all clients who wish to receive MIDI data.
@@ -120,11 +105,6 @@ class MEDIA_EXPORT MIDIManager {
MIDIPortInfoList input_ports_;
MIDIPortInfoList output_ports_;
- // |send_thread_| is used to send MIDI data by calling the platform-specific
- // API.
- scoped_ptr<base::Thread> send_thread_;
- scoped_refptr<base::MessageLoopProxy> send_message_loop_;
-
DISALLOW_COPY_AND_ASSIGN(MIDIManager);
};
diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc
index 0294024..8fd0065 100644
--- a/media/midi/midi_manager_mac.cc
+++ b/media/midi/midi_manager_mac.cc
@@ -7,8 +7,10 @@
#include <string>
#include "base/debug/trace_event.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
+
#include <CoreAudio/HostTime.h>
using base::IntToString;
@@ -30,7 +32,8 @@ MIDIManagerMac::MIDIManagerMac()
coremidi_input_(0),
coremidi_output_(0),
packet_list_(NULL),
- midi_packet_(NULL) {
+ midi_packet_(NULL),
+ send_thread_("MIDISendThread") {
}
bool MIDIManagerMac::Initialize() {
@@ -102,7 +105,24 @@ bool MIDIManagerMac::Initialize() {
return true;
}
+void MIDIManagerMac::DispatchSendMIDIData(MIDIManagerClient* client,
+ uint32 port_index,
+ const std::vector<uint8>& data,
+ double timestamp) {
+ if (send_thread_.IsRunning())
+ send_thread_.Start();
+
+ // OK to use base::Unretained(this) since we join to thread in dtor().
+ send_thread_.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&MIDIManagerMac::SendMIDIData, base::Unretained(this),
+ client, port_index, data, timestamp));
+}
+
MIDIManagerMac::~MIDIManagerMac() {
+ // Wait for the termination of |send_thread_| before disposing MIDI ports.
+ send_thread_.Stop();
+
if (coremidi_input_)
MIDIPortDispose(coremidi_input_);
if (coremidi_output_)
@@ -150,7 +170,7 @@ void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client,
uint32 port_index,
const std::vector<uint8>& data,
double timestamp) {
- DCHECK(CurrentlyOnMIDISendThread());
+ DCHECK(send_thread_.message_loop_proxy()->BelongsToCurrentThread());
// System Exclusive has already been filtered.
MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp);
diff --git a/media/midi/midi_manager_mac.h b/media/midi/midi_manager_mac.h
index 2397b80..cc8bf74 100644
--- a/media/midi/midi_manager_mac.h
+++ b/media/midi/midi_manager_mac.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/threading/thread.h"
#include "media/midi/midi_manager.h"
#include "media/midi/midi_port_info.h"
@@ -24,10 +25,10 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager {
// MIDIManager implementation.
virtual bool Initialize() OVERRIDE;
- virtual void SendMIDIData(MIDIManagerClient* client,
- uint32 port_index,
- const std::vector<uint8>& data,
- double timestamp) OVERRIDE;
+ virtual void DispatchSendMIDIData(MIDIManagerClient* client,
+ uint32 port_index,
+ const std::vector<uint8>& data,
+ double timestamp) OVERRIDE;
private:
// CoreMIDI callback for MIDI data.
@@ -39,6 +40,12 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager {
void *src_conn_refcon);
virtual void ReadMIDI(MIDIEndpointRef source, const MIDIPacketList *pktlist);
+ // An internal callback that runs on MIDISendThread.
+ void SendMIDIData(MIDIManagerClient* client,
+ uint32 port_index,
+ const std::vector<uint8>& data,
+ double timestamp);
+
// Helper
static media::MIDIPortInfo GetPortInfoFromEndpoint(MIDIEndpointRef endpoint);
static double MIDITimeStampToSeconds(MIDITimeStamp timestamp);
@@ -62,6 +69,9 @@ class MEDIA_EXPORT MIDIManagerMac : public MIDIManager {
// Keeps track of all destinations.
std::vector<MIDIEndpointRef> destinations_;
+ // |send_thread_| is used to send MIDI data.
+ base::Thread send_thread_;
+
DISALLOW_COPY_AND_ASSIGN(MIDIManagerMac);
};