Browse Source

JackControlAPI: Jack threads to notify failure to jackd by posting an 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 c430be1e33)

Change-Id: Ib484bb1e126f6bff0db76d44e6e036f92f5d8806
Signed-off-by: Laxmi Devi <Laxmi.Devi@in.bosch.com>
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
pull/948/head
Laxmi Devi Adam Miartus 6 years ago
parent
commit
1335d72497
4 changed files with 73 additions and 17 deletions
  1. +6
    -1
      common/JackAudioDriver.cpp
  2. +65
    -16
      common/JackControlAPI.cpp
  3. +1
    -0
      common/JackServerGlobals.cpp
  4. +1
    -0
      common/JackServerGlobals.h

+ 6
- 1
common/JackAudioDriver.cpp 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;
}

/*


+ 65
- 16
common/JackControlAPI.cpp View File

@@ -29,6 +29,7 @@
#ifdef __linux__
#include <poll.h>
#include <sys/signalfd.h>
#include <sys/eventfd.h>
#endif

#include "types.h"
@@ -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;
@@ -688,18 +718,27 @@ 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) {
@@ -707,7 +746,7 @@ jackctl_wait_signals(jackctl_sigmask_t * sigmask)
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;
@@ -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);
@@ -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

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


+ 1
- 0
common/JackServerGlobals.cpp 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,


+ 1
- 0
common/JackServerGlobals.h 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();


Loading…
Cancel
Save