Rui Nuno Capela wrote:
> On Fri, May 9, 2008 03:24, Paul Davis wrote:
>> Changes:
>>
>> * use poll+read, not just read, when waiting for clients to finish up
>> non-process "event" handling
>> * mark clients as Finished after their process callback has executed
>> * remove clients that failed to respond to events
>> * add new -r option to completely remove the JACK shm registry
>> at startup (orthogonal to everything else, but in my codebase for months)
>>
>> I would commit this directly, but I'm trying to be cautious for once. It
>> works much better for me now. Note that I believe there may be some
>> locking issues still to address in the code (insufficient locking,
>> that is, not deadlocks).
>>
>
> sorry to tell, but it still fails on the jack_test2.c crash tester (the
> very same at stake on that last night in Cologne:)
>
> fyi, this is just one simple client that, after a while, enters into an
> endless loop and tests for jackd being able to detect and remove it from
> the graph. what happens is that jackd gets severely stuck and
> jack_watchdog kicks in and bang! everything is thrown to the floor
>
> funny thing, and it might just be relevant to the case, is that this
> meltdown behavior seems to be most evident when, and only when, the bad
> client shares the graph with any other client. when left alone, everything
> seems to work just fine. puzzled ;)
For me it seems to be working fine. I'm on a dual core machine though so
this might be the reason.
I've attached a slightly modified version of your tester that also
displays a loop counter for when the process callback enters the stuck
loop. for me this gives the following:
ppalmers@ox-D820:~/programming/jack/tests$ ./jack_test2 2> log
seconds to run: 30
num.of ports: 2
client_name: jack_test2-32116
jack_test2-32116: client_new
jack_test2-32116: port_register
jack_test2-32116: set_process_callback
jack_test2-32116: on_shutdown
jack_test2-32116: activate
jack_test2-32116: connect: jack_test2-32116:out_0 -> system:playback_1
jack_test2-32116: connect: jack_test2-32116:out_1 -> system:playback_2
jack_test2-32116: running(0, 0)... 1
jack_test2-32116: mark!
jack_test2-32116: running(1, 2071971914)... 54
*** shutdown ***
jack_test2-32116: running(1, 2147483647)... 48
ppalmers@ox-D820:~/programming/jack/tests$
after the shutdown message, the counter stops increasing, so the process
callback is dead. The client itself stays alive, as I would expect it to
be. This is both with and without other clients in the graph.
Greets,
Pieter
/* jack_test2.c */
/****************************************************************************
Copyright (C) 2007, rncbc aka Rui Nuno Capela.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <jack/jack.h>
jack_client_t *client;
jack_port_t **iports;
jack_port_t **oports;
unsigned int seconds_to_run = 30;
unsigned int num_of_ports = 2;
float mixer_gain = 1.0f;
int ret = 0;
long int loop_count = 0;
/* shutdown process.. */
void shutdown_0 (void *arg)
{
fprintf(stdout, "\n*** shutdown ***\n");
// ret = 0;
}
/* stand-alone process. mix all the input ports to each output port. */
int process_0 (jack_nframes_t frames, void *arg)
{
jack_default_audio_sample_t *ibuf;
jack_default_audio_sample_t *obuf;
jack_nframes_t k;
int i, j, n;
if (ret > 0)
for (n = 0; n < 0x7fffffff; ++n) {
loop_count++;
}
for (i = 0; i < num_of_ports; i++) {
obuf = (jack_default_audio_sample_t*)
jack_port_get_buffer(oports[i], frames);
for (j = 0; j < num_of_ports; j++) {
ibuf = (jack_default_audio_sample_t*)
jack_port_get_buffer(iports[j], frames);
for (k = 0; k < frames; k++) {
if (j == 0)
obuf[k] = 0.0;
if (ibuf[k] < -1E-6f || ibuf[k] > +1E-6f)
obuf[k] += ibuf[k];
if (j == num_of_ports - 1)
obuf[k] *= mixer_gain;
}
}
}
return 0; // ret;
}
int main(int argc, char *argv[])
{
char client_name[33];
char iport_name[33];
char oport_name[33];
const char **pports;
int i;
/* seconds_to_run: default = 60 seconds. */
if (argc > 1)
seconds_to_run = (unsigned int) atoi(argv[1]);
fprintf(stdout, "seconds to run: %u\n", seconds_to_run);
/* num_of_ports: default = 2 ports. */
if (argc > 2)
num_of_ports = (unsigned int) atoi(argv[2]);
fprintf(stdout, "num.of ports: %u\n", num_of_ports);
sprintf(client_name, "jack_test2-%u", getpid());
fprintf(stdout, "client_name: %s\n", client_name);
fprintf(stdout, "%s: client_new\n", client_name);
client = jack_client_new(client_name);
if (!client) {
fprintf(stdout, "%s: jackd not running?\n", client_name);
return 1;
}
mixer_gain = 1.0f / (float) num_of_ports;
iports = (jack_port_t **) malloc(num_of_ports * sizeof(jack_port_t *));
oports = (jack_port_t **) malloc(num_of_ports * sizeof(jack_port_t *));
fprintf(stdout, "%s: port_register\n", client_name);
for (i = 0; i < num_of_ports; i++) {
sprintf(iport_name, "in_%d", i);
iports[i] = jack_port_register(client, iport_name,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
if (iports[i] == NULL) {
fprintf(stdout, "%s:%s port registration failed\n",
client_name, iport_name);
goto exit1;
}
sprintf(oport_name, "out_%d", i);
oports[i] = jack_port_register(client, oport_name,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
if (oports[i] == NULL) {
fprintf(stdout, "%s:%s port registration failed\n",
client_name, oport_name);
goto exit1;
}
}
fprintf(stdout, "%s: set_process_callback\n", client_name);
jack_set_process_callback(client, process_0, 0);
fprintf(stdout, "%s: on_shutdown\n", client_name);
jack_on_shutdown(client, shutdown_0, 0);
fprintf(stdout, "%s: activate\n", client_name);
jack_activate(client);
/* try to connect to available physical outputs. */
pports = jack_get_ports(client, 0, 0,
JackPortIsInput | JackPortIsPhysical);
if (pports) {
for (i = 0; i < num_of_ports && pports[i]; i++) {
sprintf(oport_name, "%s:out_%d", client_name, i);
fprintf(stdout, "%s: connect: %s -> %s\n",
client_name, oport_name, pports[i]);
if (jack_connect(client, oport_name, pports[i]) != 0) {
fprintf(stdout, "%s: connect failed\n");
goto exit2;
}
}
free(pports);
}
/* ok, we're up and running... */
for (i = seconds_to_run; i > 0; --i) {
fprintf(stdout, "%s: running(%d, %ld)...%3d\r", client_name, ret, loop_count, i);
fflush(stdout);
sleep(1);
}
/* make it blast... */
fprintf(stdout, "\n%s: mark!\n", client_name);
ret = 1;
/* duh?, still here... */
for (i = seconds_to_run*2; i > 0; --i) {
fprintf(stdout, "%s: running(%d, %ld)...%3d\r", client_name, ret, loop_count, i);
fflush(stdout);
sleep(1);
}
exit2:
fprintf(stdout, "%s: deactivate\n", client_name);
jack_deactivate(client);
exit1:
fprintf(stdout, "%s: close\n", client_name);
jack_client_close(client);
free(iports);
free(oports);
return 0;
}
/* end of jack_test2.c */
_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org