[PD-cvs] pd/src s_inter.c,1.1.1.3.2.10,1.1.1.3.2.11

Tim Blechmann timblech at users.sourceforge.net
Wed Mar 31 15:19:12 CEST 2004


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 at 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 at free.fr */
+ #endif /* THREADED_GUI */
+ 
  #ifdef MSW
  static LARGE_INTEGER nt_inittime;
***************
*** 394,398 ****
--- 418,566 ----
  }
  
+ #ifdef THREADED_GUI
+ /* thread patch by ydegoyon at 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 at 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 at 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 at 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); 
  }





More information about the Pd-cvs mailing list