From f9e91f09d2a836d981773f8a368ef1c416513081 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 27 Dec 2023 15:46:16 +0100 Subject: [PATCH] Start PCM thread manager after PCM initialization --- src/ba-transport.c | 40 ++++++++++++++++++++++++++++++---------- test/Makefile.am | 1 + test/test-ba.c | 9 +++++---- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/ba-transport.c b/src/ba-transport.c index a3ab65f9a..13114fda2 100644 --- a/src/ba-transport.c +++ b/src/ba-transport.c @@ -362,11 +362,6 @@ static struct ba_transport *transport_new( if (pipe(t->thread_manager_pipe) == -1) goto fail; - if ((errno = pthread_create(&t->thread_manager_thread_id, - NULL, PTHREAD_FUNC(transport_thread_manager), t)) != 0) { - t->thread_manager_thread_id = config.main_thread; - goto fail; - } if ((t->bluez_dbus_owner = strdup(dbus_owner)) == NULL) goto fail; @@ -510,6 +505,7 @@ struct ba_transport *ba_transport_new_a2dp( const bool is_sink = profile & BA_TRANSPORT_PROFILE_A2DP_SINK; struct ba_transport *t; + int err = 0; if ((t = transport_new(device, dbus_owner, dbus_path)) == NULL) return NULL; @@ -520,18 +516,27 @@ struct ba_transport *ba_transport_new_a2dp( memcpy(&t->a2dp.configuration, configuration, codec->capabilities_size); t->a2dp.state = BLUEZ_A2DP_TRANSPORT_STATE_IDLE; - transport_pcm_init(&t->a2dp.pcm, + err |= transport_pcm_init(&t->a2dp.pcm, is_sink ? BA_TRANSPORT_PCM_MODE_SOURCE : BA_TRANSPORT_PCM_MODE_SINK, is_sink ? &t->thread_dec : &t->thread_enc, true); t->a2dp.pcm.soft_volume = !config.a2dp.volume; - transport_pcm_init(&t->a2dp.pcm_bc, + err |= transport_pcm_init(&t->a2dp.pcm_bc, is_sink ? BA_TRANSPORT_PCM_MODE_SINK : BA_TRANSPORT_PCM_MODE_SOURCE, is_sink ? &t->thread_enc : &t->thread_dec, false); t->a2dp.pcm_bc.soft_volume = !config.a2dp.volume; + if (err != 0) + goto fail; + + if ((errno = pthread_create(&t->thread_manager_thread_id, + NULL, PTHREAD_FUNC(transport_thread_manager), t)) != 0) { + t->thread_manager_thread_id = config.main_thread; + goto fail; + } + t->acquire = transport_acquire_bt_a2dp; t->release = transport_release_bt_a2dp; @@ -546,6 +551,12 @@ struct ba_transport *ba_transport_new_a2dp( bluealsa_dbus_pcm_register(&t->a2dp.pcm_bc); return t; + +fail: + err = errno; + ba_transport_unref(t); + errno = err; + return NULL; } static int transport_acquire_bt_sco(struct ba_transport *t) { @@ -615,7 +626,7 @@ struct ba_transport *ba_transport_new_sco( const bool is_ag = profile & BA_TRANSPORT_PROFILE_MASK_AG; uint16_t codec_id = HFP_CODEC_UNDEFINED; struct ba_transport *t; - int err; + int err = 0; /* BlueALSA can only support one SCO transport per device, so we arbitrarily * accept only the first profile connection, with no preference for HFP. @@ -637,16 +648,25 @@ struct ba_transport *ba_transport_new_sco( t->profile = profile; - transport_pcm_init(&t->sco.pcm_spk, + err |= transport_pcm_init(&t->sco.pcm_spk, is_ag ? BA_TRANSPORT_PCM_MODE_SINK : BA_TRANSPORT_PCM_MODE_SOURCE, is_ag ? &t->thread_enc : &t->thread_dec, true); - transport_pcm_init(&t->sco.pcm_mic, + err |= transport_pcm_init(&t->sco.pcm_mic, is_ag ? BA_TRANSPORT_PCM_MODE_SOURCE : BA_TRANSPORT_PCM_MODE_SINK, is_ag ? &t->thread_dec : &t->thread_enc, false); + if (err != 0) + goto fail; + + if ((errno = pthread_create(&t->thread_manager_thread_id, + NULL, PTHREAD_FUNC(transport_thread_manager), t)) != 0) { + t->thread_manager_thread_id = config.main_thread; + goto fail; + } + t->acquire = transport_acquire_bt_sco; t->release = transport_release_bt_sco; diff --git a/test/Makefile.am b/test/Makefile.am index 44ea9fc7a..e29a434d8 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -93,6 +93,7 @@ test_ba_SOURCES = \ ../src/audio.c \ ../src/ba-adapter.c \ ../src/ba-device.c \ + ../src/ba-transport.c \ ../src/ba-transport-pcm.c \ ../src/bluealsa-config.c \ ../src/codec-sbc.c \ diff --git a/test/test-ba.c b/test/test-ba.c index afb548abb..a3dcc9252 100644 --- a/test/test-ba.c +++ b/test/test-ba.c @@ -44,7 +44,6 @@ #include "shared/a2dp-codecs.h" #include "shared/log.h" -#include "../src/ba-transport.c" #include "inc/check.inc" #define TEST_BLUEALSA_STORAGE_DIR "/tmp/bluealsa-test-ba-storage" @@ -130,13 +129,14 @@ CK_START_TEST(test_ba_transport) { ck_assert_ptr_ne(a = ba_adapter_new(0), NULL); ck_assert_ptr_ne(d = ba_device_new(a, &addr), NULL); - ck_assert_ptr_ne(t = transport_new(d, "/owner", "/path"), NULL); + ck_assert_ptr_ne(t = ba_transport_new_sco(d, + BA_TRANSPORT_PROFILE_HFP_AG, "/owner", "/path", -1), NULL); ba_adapter_unref(a); ba_device_unref(d); ck_assert_ptr_eq(t->d, d); - ck_assert_int_eq(t->profile, BA_TRANSPORT_PROFILE_NONE); + ck_assert_int_eq(t->profile, BA_TRANSPORT_PROFILE_HFP_AG); ck_assert_str_eq(t->bluez_dbus_owner, "/owner"); ck_assert_str_eq(t->bluez_dbus_path, "/path"); @@ -328,7 +328,8 @@ CK_START_TEST(test_cascade_free) { ck_assert_ptr_ne(a = ba_adapter_new(0), NULL); ck_assert_ptr_ne(d = ba_device_new(a, &addr), NULL); - ck_assert_ptr_ne(t = transport_new(d, "/owner", "/path"), NULL); + ck_assert_ptr_ne(t = ba_transport_new_sco(d, + BA_TRANSPORT_PROFILE_HFP_AG, "/owner", "/path", -1), NULL); t->bt_fd = 0; /* release() is called for acquired transport only */ t->release = test_cascade_free_transport_unref;