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(
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))
{

View File

@ -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);

View File

@ -36,6 +36,7 @@ std::map<std::string, int> 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,

View File

@ -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();

View File

@ -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");

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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");

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);
/*

View File

@ -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];

View File

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