Currently the thread just blocks until told to quit by midi_release. Eventually, this thread will dispatch the MIM_DATA and MIM_LONGDATA notifications and essentially replace the existing RunLoop-based mechanism.
Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winecoreaudio.drv/coreaudio.c | 1 + dlls/winecoreaudio.drv/coremidi.c | 42 ++++++++++++++++++++++++++++++ dlls/winecoreaudio.drv/midi.c | 16 ++++++++++++ dlls/winecoreaudio.drv/unixlib.h | 7 +++++ 4 files changed, 66 insertions(+)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 420021a53ea..1efcfdba3f4 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1633,6 +1633,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = midi_release, midi_out_message, midi_in_message, + midi_notify_wait,
midi_in_lock, /* temporary */ }; diff --git a/dlls/winecoreaudio.drv/coremidi.c b/dlls/winecoreaudio.drv/coremidi.c index 2e92d9ac2cb..bb8cb23f83b 100644 --- a/dlls/winecoreaudio.drv/coremidi.c +++ b/dlls/winecoreaudio.drv/coremidi.c @@ -116,6 +116,13 @@ static CFStringRef midi_in_thread_port_name;
static pthread_mutex_t midi_in_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define NOTIFY_BUFFER_SIZE 64 + 1 /* + 1 for the sentinel */ +static pthread_mutex_t notify_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t notify_cond = PTHREAD_COND_INITIALIZER; +static BOOL notify_quit; +static struct notify_context notify_buffer[NOTIFY_BUFFER_SIZE]; +static struct notify_context *notify_read, *notify_write; + NTSTATUS midi_in_lock(void *args) { BOOL lock = !!args; @@ -139,6 +146,17 @@ static void set_in_notify(struct notify_context *notify, struct midi_src *src, W notify->instance = src->midiDesc.dwInstance; }
+static void notify_post(struct notify_context *notify) +{ + pthread_mutex_lock(¬ify_mutex); + + if (notify) FIXME("Not yet handled\n"); + else notify_quit = TRUE; + pthread_cond_signal(¬ify_cond); + + pthread_mutex_unlock(¬ify_mutex); +} + /* * CoreMIDI IO threaded callback, * we can't call Wine debug channels, critical section or anything using NtCurrentTeb here. @@ -183,6 +201,11 @@ NTSTATUS midi_init(void *args) OSStatus sc; UINT i;
+ pthread_mutex_lock(¬ify_mutex); + notify_quit = FALSE; + notify_read = notify_write = notify_buffer; + pthread_mutex_unlock(¬ify_mutex); + sc = MIDIClientCreate(name, NULL /* FIXME use notify proc */, NULL, &midi_client); CFRelease(name); if (sc) @@ -300,6 +323,9 @@ NTSTATUS midi_release(void *args) msg_port = CFMessagePortCreateRemote(kCFAllocatorDefault, midi_in_thread_port_name); CFMessagePortSendRequest(msg_port, 1, NULL, 0.0, 0.0, NULL, NULL); CFRelease(msg_port); + + /* stop the notify_wait thread */ + notify_post(NULL); }
if (midi_client) MIDIClientDispose(midi_client); /* MIDIClientDispose will close all ports */ @@ -1081,3 +1107,19 @@ NTSTATUS midi_in_message(void *args)
return STATUS_SUCCESS; } + +NTSTATUS midi_notify_wait(void *args) +{ + struct midi_notify_wait_params *params = args; + + pthread_mutex_lock(¬ify_mutex); + + while (!notify_quit) + pthread_cond_wait(¬ify_cond, ¬ify_mutex); + + *params->quit = notify_quit; + + pthread_mutex_unlock(¬ify_mutex); + + return STATUS_SUCCESS; +} diff --git a/dlls/winecoreaudio.drv/midi.c b/dlls/winecoreaudio.drv/midi.c index b3adb09886d..e9cdb2a8ec4 100644 --- a/dlls/winecoreaudio.drv/midi.c +++ b/dlls/winecoreaudio.drv/midi.c @@ -78,6 +78,21 @@ static void notify_client(struct notify_context *notify) notify->instance, notify->param_1, notify->param_2); }
+static DWORD WINAPI notify_thread(void *p) +{ + struct midi_notify_wait_params params; + BOOL quit; + + params.quit = &quit; + + while (1) + { + UNIX_CALL(midi_notify_wait, ¶ms); + if (quit) break; + } + return 0; +} + static LONG CoreAudio_MIDIInit(void) { struct midi_init_params params; @@ -100,6 +115,7 @@ static LONG CoreAudio_MIDIInit(void) { MIDIInThreadPortName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("MIDIInThreadPortName.%u"), getpid()); CloseHandle( CreateThread(NULL, 0, MIDIIn_MessageThread, NULL, 0, NULL)); + CloseHandle(CreateThread(NULL, 0, notify_thread, NULL, 0, NULL)); } return err; } diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h index 2f0464ad322..67fcc35ce4c 100644 --- a/dlls/winecoreaudio.drv/unixlib.h +++ b/dlls/winecoreaudio.drv/unixlib.h @@ -226,6 +226,11 @@ struct midi_in_message_params struct notify_context *notify; };
+struct midi_notify_wait_params +{ + BOOL *quit; +}; + enum unix_funcs { unix_get_endpoint_ids, @@ -252,6 +257,7 @@ enum unix_funcs unix_midi_release, unix_midi_out_message, unix_midi_in_message, + unix_midi_notify_wait,
unix_midi_in_lock, /* temporary */ }; @@ -260,6 +266,7 @@ NTSTATUS midi_init( void * ) DECLSPEC_HIDDEN; NTSTATUS midi_release( void * ) DECLSPEC_HIDDEN; NTSTATUS midi_out_message( void * ) DECLSPEC_HIDDEN; NTSTATUS midi_in_message( void * ) DECLSPEC_HIDDEN; +NTSTATUS midi_notify_wait( void * ) DECLSPEC_HIDDEN; NTSTATUS midi_in_lock( void * ) DECLSPEC_HIDDEN;
extern unixlib_handle_t coreaudio_handle;