Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Torben Hohn <torbenh@gmx.de>
To: alsa-devel@alsa-project.org
Cc: Torben Hohn <torbenh@gmx.de>
Subject: [PATCH] jack: use eventfd which never blocks.
Date: Fri, 19 Nov 2010 15:22:29 +0100	[thread overview]
Message-ID: <1290176549-31258-1-git-send-email-torbenh@gmx.de> (raw)

the use of the socketpair for synchronisation is not correct.
jack does not allow blocking calls in the process_callback,
the socket buffers are quite small, and seem to overflow under some
conditions.

the result was write(2) blocking, and jack kicking the client.
(jack needs to be running in RT mode, with a pretty low period size (<=128)
but this really is the normal usecase)

this patch uses eventfd(2) when its available to mitigate the problem.

Signed-off-by: Torben Hohn <torbenh@gmx.de>
---
 configure.in    |    5 +++++
 jack/pcm_jack.c |   30 +++++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/configure.in b/configure.in
index 5d71cae..9fa7f27 100644
--- a/configure.in
+++ b/configure.in
@@ -21,6 +21,11 @@ AC_CHECK_LIB(asound, snd_pcm_ioplug_create,,
 AC_ARG_ENABLE([jack],
       AS_HELP_STRING([--disable-jack], [Disable building of JACK plugin]))
 
+AC_CHECK_HEADER([sys/eventfd.h], [HAVE_EVENTFD=yes], [HAVE_EVENTFD=no])
+if test "$HAVE_EVENTFD" = "yes"; then
+	AC_DEFINE(HAVE_EVENTFD, 1,"eventfd is available")
+fi
+
 if test "x$enable_jack" != "xno"; then
   PKG_CHECK_MODULES(JACK, jack >= 0.98, [HAVE_JACK=yes], [HAVE_JACK=no])
 fi
diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
index 3370a26..83ac56a 100644
--- a/jack/pcm_jack.c
+++ b/jack/pcm_jack.c
@@ -20,6 +20,8 @@
  *
  */
 
+#include "config.h"
+
 #include <byteswap.h>
 #include <sys/shm.h>
 #include <sys/types.h>
@@ -28,6 +30,10 @@
 #include <alsa/asoundlib.h>
 #include <alsa/pcm_external.h>
 
+#ifdef HAVE_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
 typedef enum _jack_format {
 	SND_PCM_JACK_FORMAT_RAW
 } snd_pcm_jack_format_t;
@@ -63,8 +69,10 @@ static void snd_pcm_jack_free(snd_pcm_jack_t *jack)
 		}
 		if (jack->fd >= 0)
 			close(jack->fd);
+#ifndef HAVE_EVENTFD
 		if (jack->io.poll_fd >= 0)
 			close(jack->io.poll_fd);
+#endif
 		free(jack->areas);
 		free(jack);
 	}
@@ -81,11 +89,19 @@ static int snd_pcm_jack_poll_revents(snd_pcm_ioplug_t *io ATTRIBUTE_UNUSED,
 				     struct pollfd *pfds, unsigned int nfds,
 				     unsigned short *revents)
 {
+#ifdef HAVE_EVENTFD
+	eventfd_t buf[1];
+#else
 	static char buf[1];
-	
+#endif
+
 	assert(pfds && nfds == 1 && revents);
 
-	read(pfds[0].fd, buf, 1);
+	read(pfds[0].fd, buf, sizeof(buf));
+#ifdef HAVE_EVENTFD
+	buf[0] -= 1;
+	write(pfds[0].fd, buf, sizeof(buf));
+#endif
 
 	*revents = pfds[0].revents;
 	return 0;
@@ -103,7 +119,11 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
 	snd_pcm_jack_t *jack = io->private_data;
 	const snd_pcm_channel_area_t *areas;
 	snd_pcm_uframes_t xfer = 0;
+#ifdef HAVE_EVENTFD
+	static eventfd_t buf[1] = { 0x00000001 };
+#else
 	static char buf[1];
+#endif
 	unsigned int channel;
 	
 	for (channel = 0; channel < io->channels; channel++) {
@@ -143,7 +163,7 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
 		xfer += frames;
 	}
 
-	write(jack->fd, buf, 1); /* for polling */
+	write(jack->fd, buf, sizeof(buf)); /* for polling */
 
 	return 0;
 }
@@ -361,7 +381,11 @@ static int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name,
 		return -ENOMEM;
 	}
 
+#ifdef HAVE_EVENTFD
+	fd[0] = fd[1] = eventfd(0, 0);
+#else
 	socketpair(AF_LOCAL, SOCK_STREAM, 0, fd);
+#endif
 	
 	jack->fd = fd[0];
 
-- 
1.7.1

             reply	other threads:[~2010-11-19 14:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-19 14:22 Torben Hohn [this message]
2010-11-21 10:15 ` [PATCH] jack: use eventfd which never blocks Alexander E. Patrakov
     [not found]   ` <20101122121518.GM4646@siel.b>
2010-11-22 13:09     ` Alexander E. Patrakov
2010-11-22 15:04       ` torbenh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1290176549-31258-1-git-send-email-torbenh@gmx.de \
    --to=torbenh@gmx.de \
    --cc=alsa-devel@alsa-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox