Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
238c6578 by Steve Lhomme at 2026-02-10T15:10:36+00:00
mmdevice: fix deadlock on exit when starting with no device
Fixes #29555
- - - - -
e127fde3 by Steve Lhomme at 2026-02-10T15:10:36+00:00
mmdevice: return directly on init failure
- - - - -
84e6202e by Steve Lhomme at 2026-02-10T15:10:36+00:00
mmdevice: distinguish between initial init failure and device not acquired
So we can keep the module around waiting for a new device.
- - - - -
9a63b3e4 by Steve Lhomme at 2026-02-10T15:10:36+00:00
mmdevice: use a semaphore to signal the initial mmdevice queries are done
We don't need the lock for that.
However the semaphore will keep being signal after the initial phase as
we don't have a way in MMSession() to tell if DEVICE_PENDING means the initial
phase or a change of device.
- - - - -
1 changed file:
- modules/audio_output/mmdevice.c
Changes:
=====================================
modules/audio_output/mmdevice.c
=====================================
@@ -76,6 +76,7 @@ static char default_device_b[1] = "";
enum device_acquisition_status {
DEVICE_PENDING,
+ DEVICE_INITIALISATION_FAILED,
DEVICE_ACQUISITION_FAILED,
DEVICE_ACQUIRED,
};
@@ -101,6 +102,7 @@ typedef struct
wchar_t *device_name; /**< device identifier to use, NULL if default */
bool default_device_changed;
HANDLE work_event;
+ vlc_sem_t init_passed;
vlc_mutex_t lock;
vlc_cond_t ready;
vlc_thread_t thread; /**< Thread for audio session control */
@@ -937,33 +939,32 @@ static HRESULT MMSession(audio_output_t *aout,
IMMDeviceEnumerator *it)
}
vlc_cond_signal(&sys->ready);
+ vlc_sem_post(&sys->init_passed);
- if (SUCCEEDED(hr))
- { /* Report actual device */
- LPWSTR wdevid;
+ if (FAILED(hr))
+ {
+ msg_Err(aout, "cannot get device identifier (error 0x%lX)", hr);
+ return hr;
+ }
- if (sys->device_name == NULL)
- aout_DeviceReport(aout, default_device_b);
- else
+ /* Report actual device */
+ if (sys->device_name == NULL)
+ aout_DeviceReport(aout, default_device_b);
+ else
+ {
+ LPWSTR wdevid;
+ hr = IMMDevice_GetId(sys->dev, &wdevid);
+ if (SUCCEEDED(hr))
{
- hr = IMMDevice_GetId(sys->dev, &wdevid);
- if (SUCCEEDED(hr))
+ char *id = FromWide(wdevid);
+ CoTaskMemFree(wdevid);
+ if (likely(id != NULL))
{
- char *id = FromWide(wdevid);
- CoTaskMemFree(wdevid);
- if (likely(id != NULL))
- {
- aout_DeviceReport(aout, id);
- free(id);
- }
+ aout_DeviceReport(aout, id);
+ free(id);
}
}
}
- else
- {
- msg_Err(aout, "cannot get device identifier (error 0x%lX)", hr);
- return hr;
- }
/* Create session manager (for controls even w/o active audio client) */
hr = IMMDevice_Activate(sys->dev, &IID_IAudioSessionManager,
@@ -1153,10 +1154,8 @@ static void *MMThread(void *data)
return NULL;
error:
- vlc_mutex_lock(&sys->lock);
- sys->device_status = DEVICE_ACQUISITION_FAILED;
- vlc_cond_signal(&sys->ready);
- vlc_mutex_unlock(&sys->lock);
+ sys->device_status = DEVICE_INITIALISATION_FAILED;
+ vlc_sem_post(&sys->init_passed);
return NULL;
}
@@ -1320,6 +1319,8 @@ static void Stop(audio_output_t *aout)
sys->stream = NULL;
}
+static void Close(vlc_object_t *);
+
static int Open(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
@@ -1348,6 +1349,7 @@ static int Open(vlc_object_t *obj)
if (!var_CreateGetBool(aout, "volume-save"))
VolumeSetLocked(aout, var_InheritFloat(aout, "mmdevice-volume"));
+ vlc_sem_init(&sys->init_passed, 0);
vlc_mutex_init(&sys->lock);
vlc_cond_init(&sys->ready);
@@ -1376,15 +1378,12 @@ static int Open(vlc_object_t *obj)
if (vlc_clone(&sys->thread, MMThread, aout))
goto error;
- vlc_mutex_lock(&sys->lock);
- while (sys->device_status == DEVICE_PENDING)
- vlc_cond_wait(&sys->ready, &sys->lock);
- vlc_mutex_unlock(&sys->lock);
+ vlc_sem_wait(&sys->init_passed);
- if (sys->device_status == DEVICE_ACQUISITION_FAILED)
+ if (sys->device_status == DEVICE_INITIALISATION_FAILED)
{
- vlc_join(sys->thread, NULL);
- goto error;
+ Close(obj);
+ return VLC_EGENERIC;
}
aout->start = Start;
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/54a2017590ad1c42cd6238de931d3d4ac2f6aef2...9a63b3e461055694ea98942ee9696479903323c2
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/54a2017590ad1c42cd6238de931d3d4ac2f6aef2...9a63b3e461055694ea98942ee9696479903323c2
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits