Fix blocking DBus device reservation, so it plays nice with others

This commit is contained in:
falkTX 2019-10-28 11:16:09 +01:00
parent 5286020560
commit f19176657c
11 changed files with 62 additions and 9 deletions

View File

@ -746,6 +746,14 @@ get_realtime_priority_constraint()
SERVER_EXPORT jackctl_server_t * jackctl_server_create( SERVER_EXPORT jackctl_server_t * jackctl_server_create(
bool (* on_device_acquire)(const char * device_name), bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(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; struct jackctl_server * server_ptr;
union jackctl_parameter_value value; 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_acquire = on_device_acquire;
JackServerGlobals::on_device_release = on_device_release; JackServerGlobals::on_device_release = on_device_release;
JackServerGlobals::on_device_reservation_loop = on_device_reservation_loop;
if (!jackctl_drivers_load(server_ptr)) if (!jackctl_drivers_load(server_ptr))
{ {

View File

@ -94,6 +94,12 @@ jackctl_server_create(
bool (* on_device_acquire)(const char * device_name), bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(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 SERVER_EXPORT void
jackctl_server_destroy( jackctl_server_destroy(
jackctl_server_t * server); jackctl_server_t * server);

View File

@ -36,6 +36,7 @@ std::map<std::string, int> JackServerGlobals::fInternalsList;
bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL;
void (* JackServerGlobals::on_device_release)(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, int JackServerGlobals::Start(const char* server_name,
jack_driver_desc_t* driver_desc, jack_driver_desc_t* driver_desc,

View File

@ -44,6 +44,7 @@ struct SERVER_EXPORT JackServerGlobals
static bool (* on_device_acquire)(const char* device_name); static bool (* on_device_acquire)(const char* device_name);
static void (* on_device_release)(const char* device_name); static void (* on_device_release)(const char* device_name);
static void (* on_device_reservation_loop)(void);
JackServerGlobals(); JackServerGlobals();
~JackServerGlobals(); ~JackServerGlobals();

View File

@ -328,11 +328,11 @@ int main(int argc, char** argv)
copyright(stdout); copyright(stdout);
#if defined(JACK_DBUS) && defined(__linux__) #if defined(JACK_DBUS) && defined(__linux__)
if (getenv("JACK_NO_AUDIO_RESERVATION")) if (getenv("JACK_NO_AUDIO_RESERVATION"))
server_ctl = jackctl_server_create(NULL, NULL); server_ctl = jackctl_server_create2(NULL, NULL, NULL);
else else
server_ctl = jackctl_server_create(audio_acquire, audio_release); server_ctl = jackctl_server_create2(audio_acquire, audio_release, audio_reserve_loop);
#else #else
server_ctl = jackctl_server_create(NULL, NULL); server_ctl = jackctl_server_create2(NULL, NULL, NULL);
#endif #endif
if (server_ctl == NULL) { if (server_ctl == NULL) {
fprintf(stderr, "Failed to create server object\n"); fprintf(stderr, "Failed to create server object\n");

View File

@ -119,20 +119,33 @@ void
jackctl_wait_signals( jackctl_wait_signals(
jackctl_sigmask_t * 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. * 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_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_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 * @return server object handle, NULL if creation of server object
* failed. Successfully created server object must be destroyed with * failed. Successfully created server object must be destroyed with
* paired call to ::jackctl_server_destroy * paired call to ::jackctl_server_destroy
*/ */
jackctl_server_t * jackctl_server_t *
jackctl_server_create( jackctl_server_create2(
bool (* on_device_acquire)(const char * device_name), 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. * Call this function to destroy server object.

View File

@ -128,8 +128,7 @@ SERVER_EXPORT void audio_release(const char * device_name)
SERVER_EXPORT void audio_reserve_loop() SERVER_EXPORT void audio_reserve_loop()
{ {
if (gConnection != NULL) { if (gConnection != NULL) {
while (dbus_connection_read_write_dispatch (gConnection, -1)) dbus_connection_read_write_dispatch (gConnection, 200);
; // empty loop body
} }
} }

View File

@ -548,7 +548,7 @@ jack_controller_create(
INIT_LIST_HEAD(&controller_ptr->session_pending_commands); 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) if (controller_ptr->server == NULL)
{ {
jack_error("Failed to create server object"); jack_error("Failed to create server object");

View File

@ -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); parameters = jackctl_server_get_parameters(server);
/* /*

View File

@ -67,6 +67,18 @@ static struct jack_constraint_enum_char_descriptor dither_constraint_descr_array
namespace Jack 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) int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size)
{ {
jack_log("JackAlsaDriver::SetBufferSize %ld", 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 // ALSA driver may have changed the in/out values
fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels;
fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_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; return 0;
} else { } else {
Close(); Close();
@ -360,6 +378,11 @@ int JackAlsaDriver::Close()
alsa_driver_delete((alsa_driver_t*)fDriver); 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) if (JackServerGlobals::on_device_release != NULL)
{ {
char audio_name[32]; char audio_name[32];

View File

@ -39,6 +39,7 @@ class JackAlsaDriver : public JackAudioDriver
private: private:
jack_driver_t* fDriver; jack_driver_t* fDriver;
jack_native_thread_t fReservationLoopThread;
void UpdateLatencies(); void UpdateLatencies();