Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2814
Modified Files:
Tag: devel_0_37
s_inter.c
Log Message:
added yves' threaded gui patch
Index: s_inter.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/s_inter.c,v
retrieving revision 1.1.1.3.2.10
retrieving revision 1.1.1.3.2.11
diff -C2 -d -r1.1.1.3.2.10 -r1.1.1.3.2.11
*** s_inter.c 22 Feb 2004 17:36:51 -0000 1.1.1.3.2.10
--- s_inter.c 31 Mar 2004 13:19:10 -0000 1.1.1.3.2.11
***************
*** 88,91 ****
--- 88,115 ----
extern int sys_addhist(int phase);
+ #ifdef THREADED_GUI
+ /* thread patch by ydegoyon(a)free.fr */
+ #include <pthread.h>
+
+
+ #define UPDATER_POLLING_DELAY 10000000 /* polling delay in nano seconds ( 10ms ) */
+
+ typedef struct _guichunk {
+ char *s_chunk;
+ struct _guichunk *p_next;
+ } t_guichunk;
+ static t_guichunk *sys_chunkslist=NULL;
+ static t_guichunk *sys_nextchunk=NULL;
+
+ static pthread_t sys_updater; // = -1; /* thread id for the update child */
+ static pthread_attr_t sys_updater_attr; /* thread attributes for update child */
+
+ static t_int sys_message_counter=0; /* counter of all pending messages */
+ static t_int sys_message_size=0; /* size of all pending messages */
+
+ static pthread_mutex_t sys_update_mutex;
+ /* end thread patch by ydegoyon(a)free.fr */
+ #endif /* THREADED_GUI */
+
#ifdef MSW
static LARGE_INTEGER nt_inittime;
***************
*** 394,398 ****
--- 418,566 ----
}
+ #ifdef THREADED_GUI
+ /* thread patch by ydegoyon(a)free.fr */
+ static void *sys_dosend(void *tdata)
+ {
+ int length, written, res, histwas;
+ struct timespec ts;
+ t_guichunk *pnext;
+
+ if (sys_nogui)
+ return NULL;
+
+ ts.tv_sec=0;
+ ts.tv_nsec=UPDATER_POLLING_DELAY;
+
+ for (;;)
+ {
+ while ( sys_chunkslist != NULL )
+ {
+ // fprintf(stderr, "updater sending : %s", sys_chunkslist->s_chunk);
+ histwas = sys_addhist(4);
+ if (sys_debuglevel & DEBUG_MESSUP)
+ fprintf(stderr, "%s", sys_chunkslist->s_chunk);
+ written = 0;
+ length = strlen(sys_chunkslist->s_chunk);
+ while (1)
+ {
+ res = send(sys_guisock, sys_chunkslist->s_chunk + written, length, 0);
+ if (res < 0)
+ {
+ // closing the socket will end up this thread
+ fprintf(stderr, "updater thread : ·þ ð : ending...\n");
+ exit(0);
+ }
+ else
+ {
+ written += res;
+ if (written >= length)
+ break;
+ }
+ }
+
+ // need exclusive access to modify the list
+ if ( pthread_mutex_lock( &sys_update_mutex ) < 0 )
+ {
+ fprintf(stderr, "pd updater mutex locking error");
+ perror( "pthread_mutex_lock" );
+
+ }
+
+ // free sent data
+ sys_message_size -= strlen(sys_chunkslist->s_chunk) + 1;
+ freebytes( sys_chunkslist->s_chunk, strlen(sys_chunkslist->s_chunk) + 1 );
+ pnext = sys_chunkslist->p_next;
+ sys_message_size -= sizeof( t_guichunk );
+ if ( sys_chunkslist == sys_nextchunk ) sys_nextchunk = NULL;
+ freebytes( sys_chunkslist, sizeof( t_guichunk ) );
+ sys_chunkslist = pnext;
+ sys_message_counter--;
+ if ( ( sys_message_counter != 0 ) && ( sys_message_counter % 1000 == 0 ) )
+ {
+ fprintf(stderr, "messages pending : %d : size : %d\n", sys_message_counter, sys_message_size);
+ }
+
+ // ok, list is modified
+ if ( pthread_mutex_unlock( &sys_update_mutex ) < 0 )
+ {
+ fprintf(stderr, "pd updater mutex unlocking error");
+ perror( "pthread_mutex_unlock" );
+ }
+
+ sys_addhist(histwas);
+ }
+
+ #ifdef UNIX
+ if ( nanosleep( &ts, NULL ) < 0 )
+ {
+ fprintf(stderr, "Pd: updater sleping error\n");
+ perror( "nanosleep" );
+ }
+ #endif
+ #ifdef NT
+ Sleep(ts.tv_nsec / 1000000);
+ #endif
+ }
+ }
+
+
+ void sys_gui(char *s)
+ {
+ char *newchunk;
+
+ // fprintf(stderr, "storing : %s size=%d\n", s, sys_message_size);
+ newchunk = (char*) malloc(strlen (s) + 1 );
+ sys_message_size += strlen(s) + 1;
+ sys_message_counter++;
+
+ if ( ( sys_message_counter != 0 ) && ( sys_message_counter % 1000 == 0 ) )
+ {
+ fprintf(stderr, "messages pending : %d : size : %d\n", sys_message_counter, sys_message_size);
+ }
+
+ if ( !newchunk )
+ {
+ fprintf(stderr, "Pd: could not allocate buffer...message to the GUI LOST!!!!!!\n");
+ }
+
+ sprintf( newchunk, "%s", s );
+
+ // need exclusive access to modify the list
+ if ( pthread_mutex_lock( &sys_update_mutex ) < 0 )
+ {
+ fprintf(stderr, "pd updater mutex locking error");
+ perror( "pthread_mutex_lock" );
+ }
+
+ if ( sys_chunkslist == NULL )
+ {
+ sys_chunkslist = (t_guichunk*) malloc( sizeof( t_guichunk ) );
+ sys_message_size += sizeof( t_guichunk );
+ sys_chunkslist->s_chunk = newchunk;
+ sys_chunkslist->p_next = NULL;
+ sys_nextchunk = sys_chunkslist;
+ }
+ else
+ {
+ // find the end of the list
+ sys_nextchunk->p_next = (t_guichunk*) malloc( sizeof( t_guichunk ) );
+ sys_message_size += sizeof( t_guichunk );
+ sys_nextchunk->p_next->s_chunk = newchunk;
+ sys_nextchunk->p_next->p_next = NULL;
+ sys_nextchunk=sys_nextchunk->p_next;
+ }
+
+ // ok, list is modified
+ if ( pthread_mutex_unlock( &sys_update_mutex ) < 0 )
+ {
+ fprintf(stderr, "pd updater mutex unlocking error");
+ perror( "pthread_mutex_unlock" );
+ }
+
+ }
+
+ /* end thread patch by ydegoyon(a)free.fr */
+ #else /* THREADED_GUI */
void sys_gui(char *s)
{
***************
*** 419,422 ****
--- 587,591 ----
sys_addhist(histwas);
}
+ #endif /* THREADED_GUI */
/* LATER should do a bounds check -- but how do you get printf to do that?
***************
*** 513,517 ****
p1 = sched_get_priority_min(SCHED_FIFO);
p2 = sched_get_priority_max(SCHED_FIFO);
! p3 = (higher ? p1 + 3 : p1 + 1);
par.sched_priority = p3;
if (sched_setscheduler(0,SCHED_FIFO,&par) != -1)
--- 682,686 ----
p1 = sched_get_priority_min(SCHED_FIFO);
p2 = sched_get_priority_max(SCHED_FIFO);
! p3 = (higher ? p2 - 1 : p2 - 3);
par.sched_priority = p3;
if (sched_setscheduler(0,SCHED_FIFO,&par) != -1)
***************
*** 878,881 ****
--- 1047,1077 ----
fprintf(stderr, "... connected\n");
+ #ifdef THREADED_GUI
+ /* thread patch by ydegoyon(a)free.fr */
+ // launch update thread
+ if ( pthread_attr_init( &sys_updater_attr ) < 0 ) {
+ post( "pd_startgui : could not launch update thread" );
+ perror( "pthread_attr_init" );
+ exit(-1);
+ }
+ if ( pthread_attr_setdetachstate( &sys_updater_attr, PTHREAD_CREATE_DETACHED ) < 0 ) {
+ post( "pd_startgui : could not launch update thread" );
+ perror( "pthread_attr_setdetachstate" );
+ exit(-1);
+ }
+ if ( pthread_create( &sys_updater, &sys_updater_attr, sys_dosend, NULL ) < 0 ) {
+ post( "pd_startgui : could not launch update thread" );
+ perror( "pthread_create" );
+ exit (-1);
+ }
+ else
+ {
+ post( "pd_startgui : updater thread %d launched", (int)sys_updater );
+ }
+ // no error return code
+ pthread_mutex_init( &sys_update_mutex, NULL );
+ /* end thread patch by ydegoyon(a)free.fr */
+ #endif /* THREADED_GUI */
+
/* here is where we start the pinging. */
#ifdef __linux__
***************
*** 906,910 ****
extern void sys_exit(void);
! /* LATER try to save dirty documents */
void sys_bail(int n)
{
--- 1102,1108 ----
extern void sys_exit(void);
! /* This is called when something bad has happened, like a segfault.
! Call glob_quit() below to exit cleanly.
! LATER try to save dirty documents even in the bad case. */
void sys_bail(int n)
{
***************
*** 920,930 ****
fprintf(stderr, "... done.\n");
#endif
!
! #if 1 /* default to soft quit */
! /* T.Grill - exit PD cleanly, just signal the scheduler loop */
! sys_exit();
! #else
! exit(1);
! #endif
}
else _exit(n);
--- 1118,1122 ----
fprintf(stderr, "... done.\n");
#endif
! exit(1);
}
else _exit(n);
***************
*** 935,939 ****
--- 1127,1134 ----
sys_vgui("exit\n");
if (!sys_nogui)
+ {
close(sys_guisock);
+ sys_rmpollfn(sys_guisock);
+ }
sys_bail(0);
}