hi,

here's my "template" for a threaded external. i had to use pthread, because polling an usb device was causing glitches in pd. since i didn't want to have 2 instance of pd (1 for polling usb + netsend, 1 for audio + netreceive) i came up with this solution. i am sure it's dirty and unstable, but at least no more glitches...

if anyone can tight it up, it could be a nice template for anyone who wants to build a thread safe external!

pat
#include "m_pd.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pthread.h"

typedef struct _pdexterna
{
	t_object 		p_ob;					// object header - ALL pd external MUST begin with this...
	void 			*outlets[OUTLETS];		// handle to the objects outlets
	int				x_verbose;
	
	pthread_attr_t 	pdexterna_thread_attr;
	pthread_t    	x_threadid;
} t_pdexterna;

void *pdexterna_class;					// global pointer to the object class - so pd can reference the object 

// ==============================================================================
// Function Prototypes
// ------------------------------------------------------------------------------
void *pdexterna_new(t_symbol *s);
void pdexterna_bang(t_pdexterna *x);				

// =============================================================================
// Thread crap
// =============================================================================
static void *usb_thread_read(void *w)
{
	t_pdexterna *x = (t_pdexterna*) w;
	while(1) {
		pthread_testcancel();
		//sys_lock();
		pdexterna_bang(x);
		//sys_unlock();
	}
}

static void usb_thread_start(t_pdexterna *x)
{

	// create the worker thread
    if(pthread_attr_init(&x->pdexterna_thread_attr) < 0)
	{
       error("pdexterna: could not launch receive thread");
       return;
    }
    if(pthread_attr_setdetachstate(&x->pdexterna_thread_attr, PTHREAD_CREATE_DETACHED) < 0)
	{
       error("pdexterna: could not launch receive thread");
       return;
    }
    if(pthread_create(&x->x_threadid, &x->pdexterna_thread_attr, usb_thread_read, x) < 0)
	{
       error("pdexterna: could not launch receive thread");
       return;
    }
    else
    {
       if(x->x_verbose)post("pdexterna: thread %d launched", (int)x->x_threadid );
    }
}



//--------------------------------------------------------------------------
// - Message: bang  -> poll pdexterna
//--------------------------------------------------------------------------
void pdexterna_bang(t_pdexterna *x)	// poll pdexterna
{
		//whatever
}


//--------------------------------------------------------------------------
// - Object creation and setup
//--------------------------------------------------------------------------
int pdexterna_setup(void)
{
	pdexterna_class = class_new ( gensym("pdexterna"),(t_newmethod)pdexterna_new, 0, sizeof(t_pdexterna), 	CLASS_DEFAULT,0);
	
	// Add message handlers
	class_addbang(pdexterna_class, (t_method)pdexterna_bang);
	post("pdexterna version 0.1",0);
	return 1;
}

//--------------------------------------------------------------------------
void *pdexterna_new(t_symbol *s)		// s = optional argument typed into object box (A_SYM) -- defaults to 0 if no args are typed
{
	t_pdexterna *x;									// local variable (pointer to a t_pdexterna data structure)
	x = (t_pdexterna *)pd_new(pdexterna_class);			 // create a new instance of this object

    x->x_verbose = 1;

	int i;
	
	// create outlets and assign it to our outlet variable in the instance's data structure
	for (i=0; i < OUTLETS; i++) {
		x->outlets[i] = outlet_new(&x->p_ob, &s_float);
	}	

    usb_thread_start(x);

	return x; // return a reference to the object instance 
}

//--------------------------------------------------------------------------
// - Object destruction
//--------------------------------------------------------------------------
void pdexterna_free(t_pdexterna *x)
{
		while(pthread_cancel(x->x_threadid) < 0)
			if(x->x_verbose)post("pdexterna: killing thread\n");
		if(x->x_verbose)post("pdexterna: thread canceled\n");
    		
}
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list

Reply via email to