Skip to content

Commit

Permalink
JackControlAPI: Jack threads to notify failure to jackd by posting an…
Browse files Browse the repository at this point in the history
… event

On failure, currently the jack thread exits without notifying the jackd.
So jackd is just waiting for the signals, unaware of the failure.
With this implementation, on error threads can post an event to jackd
notifying it to to exit.

(cherry picked from adit commit c430be1e337f52aba8312f7d29990e190cad204a)

Change-Id: Ib484bb1e126f6bff0db76d44e6e036f92f5d8806
Signed-off-by: Laxmi Devi <[email protected]>
Signed-off-by: Timo Wischer <[email protected]>
  • Loading branch information
DeviLaxmii authored and amiartus committed Jul 24, 2023
1 parent 58ab7ee commit 1335d72
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 17 deletions.
7 changes: 6 additions & 1 deletion common/JackAudioDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}

/*
Expand Down
81 changes: 65 additions & 16 deletions common/JackControlAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#ifdef __linux__
#include <poll.h>
#include <sys/signalfd.h>
#include <sys/eventfd.h>
#endif

#include "types.h"
Expand Down Expand Up @@ -147,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;
Expand Down Expand Up @@ -688,26 +718,35 @@ jackctl_wait_signals(jackctl_sigmask_t * sigmask)
bool waiting = true;
#ifdef __linux__
int err;
struct pollfd pfd;
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.fd = signalfd(-1, &sigmask->signals, 0);
if(pfd.fd == -1) {
fprintf(stderr, "Jack : signalfd() failed with errno %d\n", -errno);
pfd[JackSignalFD].fd = signalfd(-1, &sigmask->signals, 0);
if(pfd[JackSignalFD].fd == -1) {
fprintf(stderr, "signalfd() failed with errno %d\n", -errno);
return;
}
pfd.events = POLLIN;
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, 1, -1);
err = poll(pfd, JackFDCount, -1);
if (err < 0) {
if (errno == EINTR) {
continue;
Expand All @@ -716,19 +755,24 @@ jackctl_wait_signals(jackctl_sigmask_t * sigmask)
break;
}
} else {
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
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.revents & POLLIN) == 0) {
} 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;
}
err = read (pfd.fd, &si, sizeof(si));
if (err < 0) {
fprintf(stderr, "Jack : read() on signalfd failed with errno %d\n", -errno);
goto fail;
}
sig = si.ssi_signo;
fprintf(stderr, "Jack main caught signal %d\n", sig);
}
#else
sigwait(&sigmask->signals, &sig);
Expand Down Expand Up @@ -760,7 +804,11 @@ jackctl_wait_signals(jackctl_sigmask_t * sigmask)

#ifdef __linux__
fail:
close(pfd.fd);
for(int i = 0; i < JackFDCount; i++) {
if(pfd[i].fd != 0) {
close(pfd[i].fd);
}
}
#endif

}
Expand Down Expand Up @@ -982,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))
{
Expand Down
1 change: 1 addition & 0 deletions common/JackServerGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions common/JackServerGlobals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 1335d72

Please sign in to comment.