From 0feae4d437e805f0e5122b47d56eda229eb5db96 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 6 Dec 2014 01:28:17 +0100 Subject: [PATCH] Added patch to replace busyloop with condition variable in winepulse patchset. --- patches/Makefile | 2 + ...e-busyloop-with-condition-variable-a.patch | 229 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 patches/winepulse-PulseAudio_Support/0032-winepulse-Replace-busyloop-with-condition-variable-a.patch diff --git a/patches/Makefile b/patches/Makefile index 2c61f9d5..9672a1c0 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -1817,6 +1817,7 @@ winepulse-PulseAudio_Support.ok: $(call APPLY_FILE,winepulse-PulseAudio_Support/0029-winepulse-implement-exclusive-mode.patch) $(call APPLY_FILE,winepulse-PulseAudio_Support/0030-winepulse-fix-segfault-in-pulse_rd_loop.patch) $(call APPLY_FILE,winepulse-PulseAudio_Support/0031-winepulse-implement-GetPropValue.patch) + $(call APPLY_FILE,winepulse-PulseAudio_Support/0032-winepulse-Replace-busyloop-with-condition-variable-a.patch) @( \ echo '+ { "Maarten Lankhorst", "winmm: Load winealsa if winepulse is found.", 1 },'; \ echo '+ { "Maarten Lankhorst", "winepulse: Add initial stub for pulseaudio support.", 1 },'; \ @@ -1849,6 +1850,7 @@ winepulse-PulseAudio_Support.ok: echo '+ { "Mark Harmstone", "winepulse: implement exclusive mode.", 1 },'; \ echo '+ { "Mark Harmstone", "winepulse: fix segfault in pulse_rd_loop.", 1 },'; \ echo '+ { "Mark Harmstone", "winepulse: implement GetPropValue.", 1 },'; \ + echo '+ { "Sebastian Lackner", "winepulse: Replace busyloop with condition variable and minor style fixes.", 1 },'; \ ) > winepulse-PulseAudio_Support.ok # Patchset winex11-CandidateWindowPos diff --git a/patches/winepulse-PulseAudio_Support/0032-winepulse-Replace-busyloop-with-condition-variable-a.patch b/patches/winepulse-PulseAudio_Support/0032-winepulse-Replace-busyloop-with-condition-variable-a.patch new file mode 100644 index 00000000..06ab3088 --- /dev/null +++ b/patches/winepulse-PulseAudio_Support/0032-winepulse-Replace-busyloop-with-condition-variable-a.patch @@ -0,0 +1,229 @@ +From 50bcaa20cf33bd5518bdc90be72dd5dbc80fb2aa Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 6 Dec 2014 01:26:04 +0100 +Subject: winepulse: Replace busyloop with condition variable and minor style + fixes. + +--- + dlls/winepulse.drv/mmdevdrv.c | 108 +++++++++++++++++++++++------------------- + 1 file changed, 58 insertions(+), 50 deletions(-) + +diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c +index 146daad..986584c 100644 +--- a/dlls/winepulse.drv/mmdevdrv.c ++++ b/dlls/winepulse.drv/mmdevdrv.c +@@ -817,61 +817,65 @@ struct pulse_all_info_cb_data { + }; + + static void pulse_all_sink_info_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { +- struct pulse_all_info_cb_data *st = (struct pulse_all_info_cb_data*)userdata; ++ struct pulse_all_info_cb_data *st = userdata; + void *tmp; + DWORD len; + +- if (!i) +- return; ++ if (!i) goto out; + + tmp = HeapReAlloc(GetProcessHeap(), 0, st->ids, sizeof(WCHAR*) * (st->num + 1)); +- if (!tmp) return; ++ if (!tmp) goto out; + st->ids = tmp; + + tmp = HeapReAlloc(GetProcessHeap(), 0, st->keys, sizeof(GUID) * (st->num + 1)); +- if (!tmp) return; ++ if (!tmp) goto out; + st->keys = tmp; + + len = MultiByteToWideChar(CP_UTF8, 0, i->description, -1, NULL, 0); +- if (!len) return; ++ if (!len) goto out; + + st->ids[st->num] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); +- if (!st->ids[st->num]) return; ++ if (!st->ids[st->num]) goto out; + + MultiByteToWideChar(CP_UTF8, 0, i->description, -1, st->ids[st->num], len); + if (!get_device_guid(st->flow, i->name, &(st->keys[st->num]))) + CoCreateGuid(&(st->keys[st->num])); + + st->num++; ++ ++out: ++ pthread_cond_signal(&pulse_cond); + } + + static void pulse_all_source_info_cb(pa_context *c, const pa_source_info *i, int eol, void *userdata) { +- struct pulse_all_info_cb_data *st = (struct pulse_all_info_cb_data*)userdata; ++ struct pulse_all_info_cb_data *st = userdata; + void *tmp; + DWORD len; + +- if (!i) +- return; ++ if (!i) goto out; + + tmp = HeapReAlloc(GetProcessHeap(), 0, st->ids, sizeof(WCHAR*) * (st->num + 1)); +- if (!tmp) return; ++ if (!tmp) goto out; + st->ids = tmp; + + tmp = HeapReAlloc(GetProcessHeap(), 0, st->keys, sizeof(GUID) * (st->num + 1)); +- if (!tmp) return; ++ if (!tmp) goto out; + st->keys = tmp; + + len = MultiByteToWideChar(CP_UTF8, 0, i->description, -1, NULL, 0); +- if (!len) return; ++ if (!len) goto out; + + st->ids[st->num] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); +- if (!st->ids[st->num]) return; ++ if (!st->ids[st->num]) goto out; + + MultiByteToWideChar(CP_UTF8, 0, i->description, -1, st->ids[st->num], len); + if (!get_device_guid(st->flow, i->name, &(st->keys[st->num]))) + CoCreateGuid(&(st->keys[st->num])); + + st->num++; ++ ++out: ++ pthread_cond_signal(&pulse_cond); + } + + HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, GUID **keys, +@@ -919,15 +923,17 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, GUID **keys, + st.keys = *keys; + st.num = *num; + ++ pthread_mutex_lock(&pulse_lock); + if (flow == eRender) + o = pa_context_get_sink_info_list(pulse_ctx, &pulse_all_sink_info_cb, &st); + else + o = pa_context_get_source_info_list(pulse_ctx, &pulse_all_source_info_cb, &st); +- +- if (o){ +- while (pa_operation_get_state(o) == PA_OPERATION_RUNNING){ } ++ if (o) { ++ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) ++ pthread_cond_wait(&pulse_cond, &pulse_lock); + pa_operation_unref(o); + } ++ pthread_mutex_unlock(&pulse_lock); + + *ids = st.ids; + *keys = st.keys; +@@ -3497,12 +3503,12 @@ static HRESULT pulse_set_device_path(pa_proplist *p, int index, GUID *guid, PROP + return S_OK; + } + +-typedef struct { ++struct pulse_prop_values_info_cb_data { + const PROPERTYKEY *prop; + PROPVARIANT *pv; + GUID *guid; + HRESULT hr; +-} pulse_prop_values_info_cb_data; ++}; + + static const PROPERTYKEY devicepath_key = { /* undocumented? - {b3f8fa53-0004-438e-9003-51a46e139bfc},2 */ + {0xb3f8fa53, 0x0004, 0x438e, {0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc}}, 2 +@@ -3510,45 +3516,46 @@ static const PROPERTYKEY devicepath_key = { /* undocumented? - {b3f8fa53-0004-43 + + static void pulse_prop_values_sink_info_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata) + { +- pulse_prop_values_info_cb_data *st = (pulse_prop_values_info_cb_data*)userdata; ++ struct pulse_prop_values_info_cb_data *st = userdata; + +- if (!i) +- return; +- +- if (IsEqualPropertyKey(*st->prop, devicepath_key)) +- st->hr = pulse_set_device_path(i->proplist, i->index, st->guid, st->pv); +- else if (IsEqualPropertyKey(*st->prop, PKEY_AudioEndpoint_FormFactor)) { +- st->pv->vt = VT_UI4; +- st->pv->u.ulVal = Speakers; ++ if (i) { ++ if (IsEqualPropertyKey(*st->prop, devicepath_key)) ++ st->hr = pulse_set_device_path(i->proplist, i->index, st->guid, st->pv); ++ else if (IsEqualPropertyKey(*st->prop, PKEY_AudioEndpoint_FormFactor)) { ++ st->pv->vt = VT_UI4; ++ st->pv->u.ulVal = Speakers; ++ st->hr = S_OK; ++ } else ++ st->hr = E_NOTIMPL; ++ } + +- st->hr = S_OK; +- } else +- st->hr = E_NOTIMPL; ++ pthread_cond_signal(&pulse_cond); + } + + static void pulse_prop_values_source_info_cb(pa_context *c, const pa_source_info *i, int eol, void *userdata) + { +- pulse_prop_values_info_cb_data *st = (pulse_prop_values_info_cb_data*)userdata; ++ struct pulse_prop_values_info_cb_data *st = userdata; + +- if (!i) +- return; +- +- if (IsEqualPropertyKey(*st->prop, devicepath_key)) { +- st->hr = pulse_set_device_path(i->proplist, i->index, st->guid, st->pv); +- } else if (IsEqualPropertyKey(*st->prop, PKEY_AudioEndpoint_FormFactor)) { +- st->pv->vt = VT_UI4; +- st->pv->u.ulVal = (i->monitor_of_sink == PA_INVALID_INDEX) ? Microphone : LineLevel; ++ if (i) ++ { ++ if (IsEqualPropertyKey(*st->prop, devicepath_key)) ++ st->hr = pulse_set_device_path(i->proplist, i->index, st->guid, st->pv); ++ else if (IsEqualPropertyKey(*st->prop, PKEY_AudioEndpoint_FormFactor)) { ++ st->pv->vt = VT_UI4; ++ st->pv->u.ulVal = (i->monitor_of_sink == PA_INVALID_INDEX) ? Microphone : LineLevel; ++ st->hr = S_OK; ++ } else ++ st->hr = E_NOTIMPL; ++ } + +- st->hr = S_OK; +- } else +- st->hr = E_NOTIMPL; ++ pthread_cond_signal(&pulse_cond); + } + + HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARIANT *out) + { ++ struct pulse_prop_values_info_cb_data userdata; + char name[256]; + EDataFlow flow; +- pulse_prop_values_info_cb_data userdata; + pa_operation *o; + + TRACE("%s, (%s,%u), %p\n", wine_dbgstr_guid(guid), wine_dbgstr_guid(&prop->fmtid), prop->pid, out); +@@ -3571,16 +3578,17 @@ HRESULT WINAPI AUDDRV_GetPropValue(GUID *guid, const PROPERTYKEY *prop, PROPVARI + userdata.guid = guid; + userdata.hr = E_FAIL; + ++ pthread_mutex_lock(&pulse_lock); + if (flow == eRender) + o = pa_context_get_sink_info_by_name(pulse_ctx, name, &pulse_prop_values_sink_info_cb, &userdata); + else + o = pa_context_get_source_info_by_name(pulse_ctx, name, &pulse_prop_values_source_info_cb, &userdata); +- +- if (!o) +- return E_FAIL; +- +- while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) { } +- pa_operation_unref(o); ++ if (o) { ++ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) ++ pthread_cond_wait(&pulse_cond, &pulse_lock); ++ pa_operation_unref(o); ++ } ++ pthread_mutex_unlock(&pulse_lock); + + return userdata.hr; + } +-- +2.1.3 +