From: "andrzej zaborowski" <balrog@zabor.org>
To: malc <av1474@comtv.ru>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: SDL audio and AIO hogging each other's signals
Date: Wed, 4 Apr 2007 10:26:15 +0200 [thread overview]
Message-ID: <fb249edb0704040126u64e051f6j5c4c76abebf9eb18@mail.gmail.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0704040143540.5785@linmac.oyster.ru>
Hi, thanks for quick response!
On 03/04/07, malc <av1474@comtv.ru> wrote:
> On Tue, 3 Apr 2007, andrzej zaborowski wrote:
>
> > Hi,
> > with QEMU_AUDIO_DRV set to "sdl" and booting from CD-ROM with AIO on
> > a Linux host and with SDL 1.2.11, qemu locks up in sigwait() (the main
> > thread) and SDL_SemWait() (the audio thread) as soon as music is
> > playing and CD-ROM is being read at the same time. It appears that
> > audio/sdlaudio.c:sdl_callback is called by SDL when it shouldn't be
> > called, and block-raw.c is trying to flush the AIO operations, so it
> > would seem that the SIGUSR2 which is intended to wake up the sigwait
> > is instead captured by SDL and SDL tries to be smart and calls
> > sdl_callback. sdl_callback has a sanity check but this check is
> > *after* SDL_SemWait() so it is not triggered. The strange thing is
> > that using a different signal (tried SIGUSR1 and SIGPOLL) for AIO
> > doesn't help. Does SDL catch all signals?
> > I could be totally wrong because I don't know SDLAudio at all.
>
> If my reading of SDLs sources are correct then it shouldn't be trying
> to catch any signals when explicitly instructed not to do so (which is
> done in sdl.c (SDL_INIT_NOPARACHUTE flag)).
>
> >
> > Any ideas about the exact reason why this is happening and how to fix it?
> >
>
> Given the semantics of signal delivery in POSIX what you describe
> might happen, what is a little surprising is that SDL (btw. which
> backend SDL uses?) doesn't complain.
It should be using ALSA.
>
> Here's my theory: signal will be delivered to the arbitrary thread
> that happens to not block it, for whatever reason, the thread SDL
> created to do audio processing is picked up, which leads to some
> system call being interrupted(eventually) and -1 (errno == EINTR), SDL
> happily continues calling stuff.
Yes, reading the PTHREAD_SIGNAL(3) note, this sounds very likely.
>
> One solution would be to explicitly block everything upon entering
> sdl_callback for the first time. This is ugly and can have any
> consequences one cares to imagine, but that's SDL for you (any
> particular reason why you are using it?)
Not really - just had only OSS and SDL compiled into qemu at this moment.
Yes, the suggested solution works. Unfortunately it's neither pretty
nor correct, because at the time sdl_callback runs, the signal which
was supposed to wake up sigwait() is already lost and I can't find any
way to prevent that - we can add a kill(0, SIGUSR2) but this is even
uglier and again we don't know when sdl_callback is called as a result
of this signal and when legally. (That's also why I didn't put a
"return" after pthread_sigmask().)
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index f2a6896..efeb3c0 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -46,6 +46,7 @@ struct SDLAudioState {
SDL_mutex *mutex;
SDL_sem *sem;
int initialized;
+ int threadstart;
} glob_sdl;
typedef struct SDLAudioState SDLAudioState;
@@ -197,13 +198,25 @@ static void sdl_close (SDLAudioState *s)
}
}
+#ifdef __sun__
+#define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+#include <signal.h>
+
static void sdl_callback (void *opaque, Uint8 *buf, int len)
{
SDLVoiceOut *sdl = opaque;
SDLAudioState *s = &glob_sdl;
HWVoiceOut *hw = &sdl->hw;
int samples = len >> hw->info.shift;
+ sigset_t set;
+ if (s->threadstart) {
+ /* QEMU uses sigwait() so all threads should block signals. */
+ s->threadstart = 0;
+ sigfillset(&set);
+ pthread_sigmask(SIG_BLOCK, &set, 0);
+ }
if (s->exit) {
return;
}
@@ -313,6 +326,8 @@ static int sdl_init_out (HWVoiceOut *hw, audsettings_t *as)
audfmt_e effective_fmt;
audsettings_t obt_as;
+ s->threadstart = 1;
+
shift <<= as->nchannels == 2;
req.freq = as->freq;
What POSIX needs is a way to set the default signal mask for new threads :-/
Regards,
Andrzej
next prev parent reply other threads:[~2007-04-04 8:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-03 21:12 [Qemu-devel] SDL audio and AIO hogging each other's signals andrzej zaborowski
2007-04-03 21:56 ` [Qemu-devel] " malc
2007-04-04 8:26 ` andrzej zaborowski [this message]
2007-04-04 11:49 ` malc
2007-04-04 12:23 ` andrzej zaborowski
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=fb249edb0704040126u64e051f6j5c4c76abebf9eb18@mail.gmail.com \
--to=balrog@zabor.org \
--cc=av1474@comtv.ru \
--cc=balrogg@gmail.com \
--cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).