From f19176657cd8bf3d672554c97872b1f1bc0b7054 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 28 Oct 2019 11:16:09 +0100 Subject: [PATCH] Fix blocking DBus device reservation, so it plays nice with others --- common/JackControlAPI.cpp | 9 +++++++++ common/JackControlAPI.h | 6 ++++++ common/JackServerGlobals.cpp | 1 + common/JackServerGlobals.h | 1 + common/Jackdmp.cpp | 6 +++--- common/jack/control.h | 17 +++++++++++++++-- dbus/audio_reserve.c | 3 +-- dbus/controller.c | 2 +- example-clients/server_control.cpp | 2 +- linux/alsa/JackAlsaDriver.cpp | 23 +++++++++++++++++++++++ linux/alsa/JackAlsaDriver.h | 1 + 11 files changed, 62 insertions(+), 9 deletions(-) diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 11abb4e6..bbabbac1 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -746,6 +746,14 @@ get_realtime_priority_constraint() SERVER_EXPORT jackctl_server_t * jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)) +{ + return jackctl_server_create2(on_device_acquire, on_device_release, NULL); +} + +SERVER_EXPORT jackctl_server_t * jackctl_server_create2( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name), + void (* on_device_reservation_loop)(void)) { struct jackctl_server * server_ptr; union jackctl_parameter_value value; @@ -922,6 +930,7 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create( JackServerGlobals::on_device_acquire = on_device_acquire; JackServerGlobals::on_device_release = on_device_release; + JackServerGlobals::on_device_reservation_loop = on_device_reservation_loop; if (!jackctl_drivers_load(server_ptr)) { diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index 2de4451a..6eac65eb 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -94,6 +94,12 @@ jackctl_server_create( bool (* on_device_acquire)(const char * device_name), void (* on_device_release)(const char * device_name)); +SERVER_EXPORT jackctl_server_t * +jackctl_server_create2( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name), + void (* on_device_reservation_loop)(void)); + SERVER_EXPORT void jackctl_server_destroy( jackctl_server_t * server); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 43e0d440..3f08711a 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -36,6 +36,7 @@ std::map JackServerGlobals::fInternalsList; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; +void (* JackServerGlobals::on_device_reservation_loop)(void) = NULL; int JackServerGlobals::Start(const char* server_name, jack_driver_desc_t* driver_desc, diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index beb1880f..15fdfd97 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -44,6 +44,7 @@ struct SERVER_EXPORT JackServerGlobals static bool (* on_device_acquire)(const char* device_name); static void (* on_device_release)(const char* device_name); + static void (* on_device_reservation_loop)(void); JackServerGlobals(); ~JackServerGlobals(); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index e0b70c94..f7a1b270 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -328,11 +328,11 @@ int main(int argc, char** argv) copyright(stdout); #if defined(JACK_DBUS) && defined(__linux__) if (getenv("JACK_NO_AUDIO_RESERVATION")) - server_ctl = jackctl_server_create(NULL, NULL); + server_ctl = jackctl_server_create2(NULL, NULL, NULL); else - server_ctl = jackctl_server_create(audio_acquire, audio_release); + server_ctl = jackctl_server_create2(audio_acquire, audio_release, audio_reserve_loop); #else - server_ctl = jackctl_server_create(NULL, NULL); + server_ctl = jackctl_server_create2(NULL, NULL, NULL); #endif if (server_ctl == NULL) { fprintf(stderr, "Failed to create server object\n"); diff --git a/common/jack/control.h b/common/jack/control.h index 6696a669..e466abc3 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -119,20 +119,33 @@ void jackctl_wait_signals( jackctl_sigmask_t * signals); +/** + * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN + * NEW JACK PROJECTS + * + * @deprecated Please use jackctl_server_create2(). + */ +jackctl_server_t * +jackctl_server_create( + bool (* on_device_acquire)(const char * device_name), + void (* on_device_release)(const char * device_name)); + /** * Call this function to create server object. * * @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail * @param on_device_release - Optional callback to be called after device is released. + * @param on_device_reservation_loop - Optional callback to be called when looping/idling the reservation. * * @return server object handle, NULL if creation of server object * failed. Successfully created server object must be destroyed with * paired call to ::jackctl_server_destroy */ jackctl_server_t * -jackctl_server_create( +jackctl_server_create2( bool (* on_device_acquire)(const char * device_name), - void (* on_device_release)(const char * device_name)); + void (* on_device_release)(const char * device_name), + void (* on_device_reservation_loop)(void)); /** * Call this function to destroy server object. diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 6b42159d..69a6811f 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -128,8 +128,7 @@ SERVER_EXPORT void audio_release(const char * device_name) SERVER_EXPORT void audio_reserve_loop() { if (gConnection != NULL) { - while (dbus_connection_read_write_dispatch (gConnection, -1)) - ; // empty loop body + dbus_connection_read_write_dispatch (gConnection, 200); } } diff --git a/dbus/controller.c b/dbus/controller.c index 69180114..f1639b61 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -548,7 +548,7 @@ jack_controller_create( INIT_LIST_HEAD(&controller_ptr->session_pending_commands); - controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release); + controller_ptr->server = jackctl_server_create2(on_device_acquire, on_device_release, NULL); if (controller_ptr->server == NULL) { jack_error("Failed to create server object"); diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp index 7b7f57bc..9be7aea6 100644 --- a/example-clients/server_control.cpp +++ b/example-clients/server_control.cpp @@ -170,7 +170,7 @@ int main(int argc, char *argv[]) } } - server = jackctl_server_create(NULL, NULL); + server = jackctl_server_create2(NULL, NULL, NULL); parameters = jackctl_server_get_parameters(server); /* diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 529ec8d3..5349c13e 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -67,6 +67,18 @@ static struct jack_constraint_enum_char_descriptor dither_constraint_descr_array namespace Jack { +static volatile bool device_reservation_loop_running = false; + +static void* on_device_reservation_loop(void*) +{ + while (device_reservation_loop_running && JackServerGlobals::on_device_reservation_loop != NULL) { + JackServerGlobals::on_device_reservation_loop(); + usleep(50*1000); + } + + return NULL; +} + int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) { jack_log("JackAlsaDriver::SetBufferSize %ld", buffer_size); @@ -344,6 +356,12 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, // ALSA driver may have changed the in/out values fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels; + if (JackServerGlobals::on_device_reservation_loop != NULL) { + device_reservation_loop_running = true; + if (JackPosixThread::StartImp(&fReservationLoopThread, 0, 0, on_device_reservation_loop, NULL) != 0) { + device_reservation_loop_running = false; + } + } return 0; } else { Close(); @@ -360,6 +378,11 @@ int JackAlsaDriver::Close() alsa_driver_delete((alsa_driver_t*)fDriver); } + if (device_reservation_loop_running) { + device_reservation_loop_running = false; + JackPosixThread::StopImp(fReservationLoopThread); + } + if (JackServerGlobals::on_device_release != NULL) { char audio_name[32]; diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index b2f44afb..b7b14b33 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -39,6 +39,7 @@ class JackAlsaDriver : public JackAudioDriver private: jack_driver_t* fDriver; + jack_native_thread_t fReservationLoopThread; void UpdateLatencies();