« Return to Thread: Callback question

Re: Callback question

by torbenh :: Rate this Message:

Reply to Author | View in Thread

On Wed, May 27, 2009 at 07:24:02PM -0500, Gabriel M. Beddingfield wrote:

>
> Hi Jorge,
>
> On Wed, May 27, 2009 6:35 pm, Jorge Cardona wrote:
> > I'm trying to understand how works jack, but i'm stuck on the way that
> > the callbacks at the clients are called from the server. Is there a
> > signaling system, like the posix signals? i was reading the code, but
> > i can't find where exactly is stored the client process function
> > pointer, and when is called.
>
> For Jack1, look in engine.c for jack_engine_process().  Whenever it wants
> to call the client callbacks, this is the function that does it.  The
> JSList* node holds a linked-list to all the client data (void*
> node->data).  For each client, either jack_process_internal() or
> jack_process_external() is called.
>
> Inside jack_process_internal(), you'll find:
>
> jack_client_internal_t *client;
> jack_client_control_t *ctl;
>
> client = (jack_client_internal_t *) node->data;
> ctl = client->control;
>
> And later on:
>
> if (ctl->process_cbset)
> if (client->private_client->process (nframes,
> client->private_client->process_arg)) {
> jack_error ("internal client %s failed", ctl->name);
> engine->process_errors++;
> }
>
> ctl->process_cbset is a flag indicating whether or not the callback has
> been set.  If so, client->private_client->process is the pointer to the
> callback.

note that client->private_client->process only exists in the clients
address space.

I also think the question was rather how to implement a similar system,
and how the control is passed around processes.
So internal clients are not really relevant here.

jack is a lot cleverer, than described here.
between the invocation of the process callbacks of two clients, control
will not be transfered to jackd, the external clients transfer control,
by writing a byte into a pipe, where the next process is blocking on.

look at libjack/client.c: jack_client_thread_aux()
this is where it all happens.

------------------------------------------------------------------------------------
static void
jack_client_thread_aux (void *arg)
{
        jack_client_t *client = (jack_client_t *) arg;
        jack_client_control_t *control = client->control;

        pthread_mutex_lock (&client_lock);
        client->thread_ok = TRUE;
        client->thread_id = pthread_self();
        pthread_cond_signal (&client_ready);
        pthread_mutex_unlock (&client_lock);

        control->pid = getpid();
        control->pgrp = getpgrp();

        DEBUG ("client thread is now running");

        if (control->thread_init_cbset) {
                DEBUG ("calling client thread init callback");
                client->thread_init (client->thread_init_arg);
        }

        /* wait for first wakeup from server */

        if (jack_thread_first_wait (client) == control->nframes) {

                /* now run till we're done */

                if (control->process_cbset) {

                        /* run process callback, then wait... ad-infinitum */

                        while (1) {
                                DEBUG("client calls process()");
                                int status = (client->process (control->nframes,
                                                                client->process_arg) ==
                                              control->nframes);
                                control->state = Finished;
                                DEBUG("client leaves process(), re-enters wait");
                                if (!jack_thread_wait (client, status)) {
                                        break;
                                }
                                DEBUG("client done with wait");
                        }

                } else {
                        /* no process handling but still need to process events */
                        while (jack_thread_wait (client, 0) == control->nframes)
                                ;
                }
        }

        jack_client_thread_suicide (client);
}
-------------------------------------------------------------------------------------

note that these fds are setup during the graphchange step, where
processing is suspended.




>
> Someone correct me if I made a mistake here.
>
> HTH,
> Gabriel
>
> --
>                G a b r i e l   M   B e d d i n g f i e l d
>
> _______________________________________________
> Jack-Devel mailing list
> Jack-Devel@...
> http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

--
torben Hohn
http://galan.sourceforge.net -- The graphical Audio language
_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

 « Return to Thread: Callback question