Merge miartad/adit-control-api-backports into LADI/jack2/main

https://github.com/jackaudio/jack2/pull/948
This commit is contained in:
Nedko Arnaudov 2023-07-25 20:53:38 +03:00
commit cf8d44743b
4 changed files with 110 additions and 3 deletions

View File

@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackLockedEngine.h"
#include "JackException.h"
#include <assert.h>
#include "JackServerGlobals.h"
using namespace std;
@ -199,7 +200,11 @@ int JackAudioDriver::Write()
int JackAudioDriver::Process()
{
return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
int err = (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
if(err && JackServerGlobals::on_failure != NULL) {
JackServerGlobals::on_failure();
}
return err;
}
/*

View File

@ -26,6 +26,12 @@
#include <pthread.h>
#endif
#ifdef __linux__
#include <poll.h>
#include <sys/signalfd.h>
#include <sys/eventfd.h>
#endif
#include "types.h"
#include <string.h>
#include <errno.h>
@ -142,6 +148,35 @@ struct jackctl_parameter
jack_driver_param_constraint_desc_t * constraint_ptr;
};
#ifdef __linux__
/** Jack file descriptors */
typedef enum
{
JackSignalFD, /**< @brief File descriptor to accept the signals */
JackEventFD, /**< @brief File descriptor to accept the events from threads */
JackFDCount /**< @brief FD count, ensure this is the last element */
} jackctl_fd;
static int eventFD;
#endif
static
void
on_failure()
{
#ifdef __linux__
int ret = 0;
const uint64_t ev = 1;
ret = write(eventFD, &ev, sizeof(ev));
if (ret < 0) {
fprintf(stderr, "JackServerGlobals::on_failure : write() failed with errno %d\n", -errno);
}
#else
fprintf(stderr, "JackServerGlobals::on_failure callback called from thread\n");
#endif
}
const char * jack_get_self_connect_mode_description(char mode)
{
struct jack_constraint_enum_char_descriptor * descr_ptr;
@ -679,16 +714,70 @@ jackctl_setup_signals(
SERVER_EXPORT void
jackctl_wait_signals(jackctl_sigmask_t * sigmask)
{
int sig;
int sig = 0;
bool waiting = true;
#ifdef __linux__
int err;
struct pollfd pfd[JackFDCount];
struct signalfd_siginfo si;
memset(pfd, 0, sizeof(pfd));
/* Block the signals in order for signalfd to receive them */
sigprocmask(SIG_BLOCK, &sigmask->signals, NULL);
pfd[JackSignalFD].fd = signalfd(-1, &sigmask->signals, 0);
if(pfd[JackSignalFD].fd == -1) {
fprintf(stderr, "signalfd() failed with errno %d\n", -errno);
return;
}
pfd[JackSignalFD].events = POLLIN;
pfd[JackEventFD].fd = eventfd(0, EFD_NONBLOCK);
if(pfd[JackEventFD].fd == -1) {
goto fail;
}
eventFD = pfd[JackEventFD].fd;
pfd[JackEventFD].events = POLLIN;
#endif
while (waiting) {
#if defined(sun) && !defined(__sun__) // SUN compiler only, to check
sigwait(&sigmask->signals);
fprintf(stderr, "Jack main caught signal\n");
#elif defined(__linux__)
err = poll(pfd, JackFDCount, -1);
if (err < 0) {
if (errno == EINTR) {
continue;
} else {
fprintf(stderr, "Jack : poll() failed with errno %d\n", -errno);
break;
}
} else {
if ((pfd[JackSignalFD].revents & (POLLERR | POLLHUP | POLLNVAL)) ||
pfd[JackEventFD].revents & (POLLERR | POLLHUP | POLLNVAL)) {
fprintf(stderr, "Jack : poll() exited with errno %d\n", -errno);
break;
} else if ((pfd[JackSignalFD].revents & POLLIN) != 0) {
err = read (pfd[JackSignalFD].fd, &si, sizeof(si));
if (err < 0) {
fprintf(stderr, "Jack : read() on signalfd failed with errno %d\n", -errno);
break;
}
sig = si.ssi_signo;
fprintf(stderr, "Jack main caught signal %d\n", sig);
} else if ((pfd[JackEventFD].revents & POLLIN) != 0) {
sig = 0; /* Received an event from one of the Jack thread */
fprintf(stderr, "Jack main received event from child thread, Exiting\n");
} else {
continue;
}
}
#else
sigwait(&sigmask->signals, &sig);
#endif
fprintf(stderr, "Jack main caught signal %d\n", sig);
#endif
switch (sig) {
case SIGUSR1:
@ -712,6 +801,16 @@ jackctl_wait_signals(jackctl_sigmask_t * sigmask)
// bugs that cause segfaults etc. during shutdown.
sigprocmask(SIG_UNBLOCK, &sigmask->signals, 0);
}
#ifdef __linux__
fail:
for(int i = 0; i < JackFDCount; i++) {
if(pfd[i].fd != 0) {
close(pfd[i].fd);
}
}
#endif
}
#endif
@ -931,6 +1030,7 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create2(
JackServerGlobals::on_device_acquire = on_device_acquire;
JackServerGlobals::on_device_release = on_device_release;
JackServerGlobals::on_device_reservation_loop = on_device_reservation_loop;
JackServerGlobals::on_failure = on_failure;
if (!jackctl_drivers_load(server_ptr))
{

View File

@ -37,6 +37,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;
void (* JackServerGlobals::on_failure)() = NULL;
int JackServerGlobals::Start(const char* server_name,
jack_driver_desc_t* driver_desc,

View File

@ -45,6 +45,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);
static void (* on_failure)(); /* Optional callback to be called from any thread on failure */
JackServerGlobals();
~JackServerGlobals();