mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-25 05:41:20 +00:00
Detect the silent death of the jack client thread.
When jackd gets an unhandled xrun, it stops all processing but neglects to tell the client about it. Thus, add a bit of a watchdog function to s_update() and assume the client thread is dead if there's no sign of life after one second. No more hanging on exit.
This commit is contained in:
parent
86c5b79816
commit
9ffa1f410a
2 changed files with 56 additions and 12 deletions
10
TODO
10
TODO
|
@ -14,28 +14,30 @@ X ~/.quakeforgerc should support all commands, not just set and setrom
|
||||||
X software PCXs don't work in X11 at least if you're using 16/24/32 color
|
X software PCXs don't work in X11 at least if you're using 16/24/32 color
|
||||||
X ogg support
|
X ogg support
|
||||||
X server-side demos
|
X server-side demos
|
||||||
|
X Scitech MGL used in win32 is screwed - dump it and use SDL
|
||||||
|
X kill MAX_STATIC_ENTITIES
|
||||||
|
X stateful console (eg, rcon mode, chat mode, normal command mode...)
|
||||||
M it seems possible to crash a QF server still - need to fix this!
|
M it seems possible to crash a QF server still - need to fix this!
|
||||||
M merge nq and qw code bases
|
M merge nq and qw code bases
|
||||||
M mingw cross compiling
|
M mingw cross compiling
|
||||||
X Scitech MGL used in win32 is screwed - dump it and use SDL
|
|
||||||
M software targets should mix color at 16/16 or 24/32 color
|
M software targets should mix color at 16/16 or 24/32 color
|
||||||
I GL is still way too slow
|
I GL is still way too slow
|
||||||
I Client side QuakeC.
|
I Client side QuakeC.
|
||||||
I menu rewrite
|
I menu rewrite
|
||||||
I clean up TODO ;)
|
I clean up TODO ;)
|
||||||
o kill MAX_STATIC_ENTITIES
|
|
||||||
o doublesize modes (eg, render in 320x240 but display in 640x480)
|
o doublesize modes (eg, render in 320x240 but display in 640x480)
|
||||||
o allow qf clients to download .lit files from qf servers.
|
o allow qf clients to download .lit files from qf servers.
|
||||||
o better server control of certain cvars
|
o better server control of certain cvars
|
||||||
o triggers (f_respawn, f_death, f_took; cl_triggers)
|
o triggers (f_respawn, f_death, f_took; cl_triggers)
|
||||||
X stateful console (eg, rcon mode, chat mode, normal command mode...)
|
|
||||||
o scripted hud
|
o scripted hud
|
||||||
o add a U_PHYSICAL field to entities. it should include a solid bit,
|
o add a U_PHYSICAL field to entities. it should include a solid bit,
|
||||||
a rotated bbox bit, and mins/maxs for the bbos
|
a rotated bbox bit, and mins/maxs for the bbos
|
||||||
o gui for serverlist
|
o gui for serverlist
|
||||||
o add favorates serverlist manipulation
|
o add favorites serverlist manipulation
|
||||||
o redo serverlist filtering for better flexability and/or easier use
|
o redo serverlist filtering for better flexability and/or easier use
|
||||||
o add individual server ping/info request from console
|
o add individual server ping/info request from console
|
||||||
|
? dynamically allocate missing fields, particularly ones not needed by the
|
||||||
|
progs.
|
||||||
? more direct intra-team comms (eg, talk to offense or defense directly)
|
? more direct intra-team comms (eg, talk to offense or defense directly)
|
||||||
? Draw_Pic and friends need a cleanup in GL at least
|
? Draw_Pic and friends need a cleanup in GL at least
|
||||||
? Draw_Pic and other tex draw functions should use local palettes
|
? Draw_Pic and other tex draw functions should use local palettes
|
||||||
|
|
|
@ -53,6 +53,8 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
static int sound_started = 0;
|
static int sound_started = 0;
|
||||||
static int snd_blocked = 0;
|
static int snd_blocked = 0;
|
||||||
static int snd_shutdown = 0;
|
static int snd_shutdown = 0;
|
||||||
|
static int snd_alive = 0;
|
||||||
|
static double snd_alive_time = 0;
|
||||||
static jack_client_t *jack_handle;
|
static jack_client_t *jack_handle;
|
||||||
static jack_port_t *jack_out[2];
|
static jack_port_t *jack_out[2];
|
||||||
static dma_t _snd_shm;
|
static dma_t _snd_shm;
|
||||||
|
@ -78,12 +80,38 @@ s_start_sound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin,
|
||||||
SND_StartSound (entnum, entchannel, sfx, origin, fvol, attenuation);
|
SND_StartSound (entnum, entchannel, sfx, origin, fvol, attenuation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
s_finish_channels (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
channel_t *ch;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_CHANNELS; i++) {
|
||||||
|
ch = &snd_channels[i];
|
||||||
|
ch->done = ch->stop = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
|
s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
|
||||||
const vec3_t up)
|
const vec3_t up)
|
||||||
{
|
{
|
||||||
|
double now = Sys_DoubleTime ();
|
||||||
|
|
||||||
if (!sound_started)
|
if (!sound_started)
|
||||||
return;
|
return;
|
||||||
|
if (snd_alive) {
|
||||||
|
snd_alive = 0;
|
||||||
|
snd_alive_time = now;
|
||||||
|
} else {
|
||||||
|
if (!snd_shutdown) {
|
||||||
|
if (now - snd_alive_time > 1.0) {
|
||||||
|
Sys_Printf ("jackd client thread seems to have died\n");
|
||||||
|
s_finish_channels ();
|
||||||
|
snd_shutdown = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (snd_shutdown) {
|
if (snd_shutdown) {
|
||||||
if (snd_shutdown == 1) {
|
if (snd_shutdown == 1) {
|
||||||
snd_shutdown++;
|
snd_shutdown++;
|
||||||
|
@ -120,8 +148,10 @@ s_jack_activate (void)
|
||||||
}
|
}
|
||||||
ports = jack_get_ports (jack_handle, 0, 0,
|
ports = jack_get_ports (jack_handle, 0, 0,
|
||||||
JackPortIsPhysical | JackPortIsInput);
|
JackPortIsPhysical | JackPortIsInput);
|
||||||
//for (i = 0; ports[i]; i++)
|
if (developer->int_val & SYS_SND) {
|
||||||
// Sys_Printf ("%s\n", ports[i]);
|
for (i = 0; ports[i]; i++)
|
||||||
|
Sys_Printf ("%s\n", ports[i]);
|
||||||
|
}
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
jack_connect (jack_handle, jack_port_name (jack_out[i]), ports[i]);
|
jack_connect (jack_handle, jack_port_name (jack_out[i]), ports[i]);
|
||||||
free (ports);
|
free (ports);
|
||||||
|
@ -254,6 +284,7 @@ snd_jack_process (jack_nframes_t nframes, void *arg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
snd_alive = 1;
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
output[i] = (float *) jack_port_get_buffer (jack_out[i], nframes);
|
output[i] = (float *) jack_port_get_buffer (jack_out[i], nframes);
|
||||||
SND_PaintChannels (snd_paintedtime + nframes);
|
SND_PaintChannels (snd_paintedtime + nframes);
|
||||||
|
@ -263,13 +294,21 @@ snd_jack_process (jack_nframes_t nframes, void *arg)
|
||||||
static void
|
static void
|
||||||
snd_jack_shutdown (void *arg)
|
snd_jack_shutdown (void *arg)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
channel_t *ch;
|
|
||||||
snd_shutdown = 1;
|
snd_shutdown = 1;
|
||||||
for (i = 0; i < MAX_CHANNELS; i++) {
|
s_finish_channels ();
|
||||||
ch = &snd_channels[i];
|
|
||||||
ch->done = ch->stop = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
snd_jack_error (const char *desc)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "snd_jack: %s\n", desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
snd_jack_xrun (void *arg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "snd_jack: xrun\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -291,12 +330,15 @@ s_init (void)
|
||||||
SND_SFX_Init ();
|
SND_SFX_Init ();
|
||||||
SND_Channels_Init ();
|
SND_Channels_Init ();
|
||||||
|
|
||||||
|
jack_set_error_function (snd_jack_error);
|
||||||
if ((jack_handle = jack_client_open ("QuakeForge",
|
if ((jack_handle = jack_client_open ("QuakeForge",
|
||||||
JackServerName | JackNoStartServer, 0,
|
JackServerName | JackNoStartServer, 0,
|
||||||
snd_jack_server->string)) == 0) {
|
snd_jack_server->string)) == 0) {
|
||||||
Sys_Printf ("Could not connect to JACK\n");
|
Sys_Printf ("Could not connect to JACK\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (jack_set_xrun_callback (jack_handle, snd_jack_xrun, 0))
|
||||||
|
Sys_Printf ("Could not set xrun callback\n");
|
||||||
jack_set_process_callback (jack_handle, snd_jack_process, 0);
|
jack_set_process_callback (jack_handle, snd_jack_process, 0);
|
||||||
jack_on_shutdown (jack_handle, snd_jack_shutdown, 0);
|
jack_on_shutdown (jack_handle, snd_jack_shutdown, 0);
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
|
|
Loading…
Reference in a new issue