winepulse: Use a critical section for PE-side locking.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b4c7823bbb
commit
a4149d53f7
|
@ -68,6 +68,15 @@ static GUID pulse_render_guid =
|
|||
static GUID pulse_capture_guid =
|
||||
{ 0x25da76d0, 0x033c, 0x4235, { 0x90, 0x02, 0x19, 0xf4, 0x88, 0x94, 0xac, 0x6f } };
|
||||
|
||||
static CRITICAL_SECTION session_cs;
|
||||
static CRITICAL_SECTION_DEBUG session_cs_debug = {
|
||||
0, 0, &session_cs,
|
||||
{ &session_cs_debug.ProcessLocksList,
|
||||
&session_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": session_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION session_cs = { &session_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
|
@ -367,9 +376,9 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
|
|||
if (This->pulse_stream) {
|
||||
pulse->release_stream(This->pulse_stream, This->timer);
|
||||
This->pulse_stream = NULL;
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
list_remove(&This->entry);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
}
|
||||
IUnknown_Release(This->marshal);
|
||||
IMMDevice_Release(This->parent);
|
||||
|
@ -549,10 +558,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
|
||||
if (This->pulse_stream) {
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return AUDCLNT_E_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -562,7 +571,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
|
|||
if (!(pulse_thread = CreateThread(NULL, 0, pulse_mainloop_thread, event, 0, NULL)))
|
||||
{
|
||||
ERR("Failed to create mainloop thread.\n");
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
CloseHandle(event);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -577,14 +586,14 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
|
|||
free(name);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!(This->vol = malloc(channel_count * sizeof(*This->vol))))
|
||||
{
|
||||
pulse->release_stream(stream, NULL);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
for (i = 0; i < channel_count; i++)
|
||||
|
@ -595,7 +604,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
|
|||
{
|
||||
free(This->vol);
|
||||
This->vol = NULL;
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
pulse->release_stream(stream, NULL);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
@ -605,7 +614,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
|
|||
list_add_tail(&This->session->clients, &This->entry);
|
||||
set_stream_volumes(This);
|
||||
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1445,12 +1454,12 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
|
|||
if (count != This->channel_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
for (i = 0; i < count; ++i)
|
||||
This->vol[i] = levels[i];
|
||||
|
||||
set_stream_volumes(This);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1470,10 +1479,10 @@ static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
|
|||
if (count != This->channel_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
for (i = 0; i < count; ++i)
|
||||
levels[i] = This->vol[i];
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1492,10 +1501,10 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
|
|||
if (index >= This->channel_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
This->vol[index] = level;
|
||||
set_stream_volumes(This);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1514,9 +1523,9 @@ static HRESULT WINAPI AudioStreamVolume_GetChannelVolume(
|
|||
if (index >= This->channel_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
*level = This->vol[index];
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1614,7 +1623,7 @@ static HRESULT WINAPI AudioSessionControl_GetState(IAudioSessionControl2 *iface,
|
|||
if (!state)
|
||||
return NULL_PTR_ERR;
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
if (list_empty(&This->session->clients)) {
|
||||
*state = AudioSessionStateExpired;
|
||||
goto out;
|
||||
|
@ -1628,7 +1637,7 @@ static HRESULT WINAPI AudioSessionControl_GetState(IAudioSessionControl2 *iface,
|
|||
*state = AudioSessionStateInactive;
|
||||
|
||||
out:
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2004,11 +2013,11 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
|
|||
|
||||
TRACE("PulseAudio does not support session volume control\n");
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
session->master_vol = level;
|
||||
LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
|
||||
set_stream_volumes(client);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -2041,11 +2050,11 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
|
|||
if (context)
|
||||
FIXME("Notifications not supported yet\n");
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
session->mute = mute;
|
||||
LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
|
||||
set_stream_volumes(client);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -2148,11 +2157,11 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
|
|||
|
||||
TRACE("PulseAudio does not support session volume control\n");
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
session->channel_vols[index] = level;
|
||||
LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
|
||||
set_stream_volumes(client);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -2199,12 +2208,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
|
|||
|
||||
TRACE("PulseAudio does not support session volume control\n");
|
||||
|
||||
pulse->lock();
|
||||
EnterCriticalSection(&session_cs);
|
||||
for(i = 0; i < count; ++i)
|
||||
session->channel_vols[i] = levels[i];
|
||||
LIST_FOR_EACH_ENTRY(client, &This->session->clients, ACImpl, entry)
|
||||
set_stream_volumes(client);
|
||||
pulse->unlock();
|
||||
LeaveCriticalSection(&session_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,12 +99,12 @@ static pthread_cond_t pulse_cond = PTHREAD_COND_INITIALIZER;
|
|||
UINT8 mult_alaw_sample(UINT8, float);
|
||||
UINT8 mult_ulaw_sample(UINT8, float);
|
||||
|
||||
static void WINAPI pulse_lock(void)
|
||||
static void pulse_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&pulse_mutex);
|
||||
}
|
||||
|
||||
static void WINAPI pulse_unlock(void)
|
||||
static void pulse_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&pulse_mutex);
|
||||
}
|
||||
|
@ -178,13 +178,13 @@ static int pulse_poll_func(struct pollfd *ufds, unsigned long nfds, int timeout,
|
|||
static void WINAPI pulse_main_loop(HANDLE event)
|
||||
{
|
||||
int ret;
|
||||
pulse_lock();
|
||||
pulse_ml = pa_mainloop_new();
|
||||
pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL);
|
||||
NtSetEvent(event, NULL);
|
||||
pulse_lock();
|
||||
pa_mainloop_run(pulse_ml, &ret);
|
||||
pulse_unlock();
|
||||
pa_mainloop_free(pulse_ml);
|
||||
pulse_unlock();
|
||||
}
|
||||
|
||||
static void pulse_contextcallback(pa_context *c, void *userdata)
|
||||
|
@ -799,11 +799,19 @@ static HRESULT WINAPI pulse_create_stream(const char *name, EDataFlow dataflow,
|
|||
unsigned int i, bufsize_bytes;
|
||||
HRESULT hr;
|
||||
|
||||
pulse_lock();
|
||||
|
||||
if (FAILED(hr = pulse_connect(name)))
|
||||
{
|
||||
pulse_unlock();
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!(stream = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*stream))))
|
||||
{
|
||||
pulse_unlock();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
stream->dataflow = dataflow;
|
||||
for (i = 0; i < ARRAY_SIZE(stream->vol); ++i)
|
||||
|
@ -867,6 +875,9 @@ static HRESULT WINAPI pulse_create_stream(const char *name, EDataFlow dataflow,
|
|||
}
|
||||
}
|
||||
|
||||
*channel_count = stream->ss.channels;
|
||||
*ret = stream;
|
||||
|
||||
exit:
|
||||
if (FAILED(hr)) {
|
||||
free(stream->local_buffer);
|
||||
|
@ -875,12 +886,10 @@ exit:
|
|||
pa_stream_unref(stream->stream);
|
||||
RtlFreeHeap(GetProcessHeap(), 0, stream);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
*channel_count = stream->ss.channels;
|
||||
*ret = stream;
|
||||
return S_OK;
|
||||
pulse_unlock();
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void WINAPI pulse_release_stream(struct pulse_stream *stream, HANDLE timer)
|
||||
|
@ -1802,13 +1811,15 @@ static HRESULT WINAPI pulse_set_event_handle(struct pulse_stream *stream, HANDLE
|
|||
|
||||
static BOOL WINAPI pulse_is_started(struct pulse_stream *stream)
|
||||
{
|
||||
return pulse_stream_valid(stream) && stream->started;
|
||||
BOOL ret;
|
||||
pulse_lock();
|
||||
ret = pulse_stream_valid(stream) && stream->started;
|
||||
pulse_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct unix_funcs unix_funcs =
|
||||
{
|
||||
pulse_lock,
|
||||
pulse_unlock,
|
||||
pulse_main_loop,
|
||||
pulse_create_stream,
|
||||
pulse_release_stream,
|
||||
|
|
|
@ -33,8 +33,6 @@ struct pulse_config
|
|||
|
||||
struct unix_funcs
|
||||
{
|
||||
void (WINAPI *lock)(void);
|
||||
void (WINAPI *unlock)(void);
|
||||
void (WINAPI *main_loop)(HANDLE event);
|
||||
HRESULT (WINAPI *create_stream)(const char *name, EDataFlow dataflow, AUDCLNT_SHAREMODE mode,
|
||||
DWORD flags, REFERENCE_TIME duration, REFERENCE_TIME period,
|
||||
|
|
Loading…
Reference in New Issue