Update of /cvsroot/pure-data/externals/io/hidio In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv862
Modified Files: hidio.c hidio.h Log Message: added threading for 'open' and 'close', needs more work but shows that open is a blocking function that takes ages to complete on first call
Index: hidio.c =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** hidio.c 1 Dec 2006 15:18:10 -0000 1.4 --- hidio.c 1 Dec 2006 16:04:37 -0000 1.5 *************** *** 366,372 **** debug_print(LOG_DEBUG,"hid_%s",s->s_name); /* store running state to be restored after the device has been opened */ ! t_int started = x->x_started; ! short device_number = get_device_number_from_arguments(argc, argv); if(device_number > -1) { --- 366,373 ---- debug_print(LOG_DEBUG,"hid_%s",s->s_name); /* store running state to be restored after the device has been opened */ ! short device_number; ! pthread_mutex_lock(&x->x_mutex); ! device_number = get_device_number_from_arguments(argc, argv); if(device_number > -1) { *************** *** 375,392 **** if(! x->x_device_open) { ! if(hidio_open_device(x,device_number)) ! error("[hidio] can not open device %d",device_number); ! else ! x->x_device_open = 1; } } else debug_print(LOG_WARNING,"[hidio] device does not exist"); ! /* restore the polling state so that when I [tgl] is used to start/stop [hidio], ! * the [tgl]'s state will continue to accurately reflect [hidio]'s state */ ! if(started) ! hidio_set_from_float(x,x->x_delay); ! debug_print(LOG_DEBUG,"[hidio] set device# to %d",device_number); ! output_open_status(x); ! output_device_number(x); }
--- 376,386 ---- if(! x->x_device_open) { ! x->x_device_number = device_number; ! x->x_requestcode = REQUEST_OPEN; ! pthread_cond_signal(&x->x_requestcondition); } } else debug_print(LOG_WARNING,"[hidio] device does not exist"); ! pthread_mutex_unlock(&x->x_mutex); }
*************** *** 462,476 ****
/*------------------------------------------------------------------------------ * system functions */ static void hidio_free(t_hidio* x) { debug_print(LOG_DEBUG,"hidio_free"); ! hidio_close(x); clock_free(x->x_clock); hidio_instance_count--;
hidio_platform_specific_free(x); }
--- 456,585 ----
/*------------------------------------------------------------------------------ + * child thread + */ + + static void *hidio_child(void *zz) + { + t_hidio *x = zz; + + pthread_mutex_lock(&x->x_mutex); + while (1) + { + if (x->x_requestcode == REQUEST_NOTHING) + { + pthread_cond_signal(&x->x_answercondition); + pthread_cond_wait(&x->x_requestcondition, &x->x_mutex); + } + else if (x->x_requestcode == REQUEST_OPEN) + { + short device_number = x->x_device_number; + t_int started = x->x_started; + int err; + pthread_mutex_unlock(&x->x_mutex); + err = hidio_open_device(x, device_number); + pthread_mutex_lock(&x->x_mutex); + if (err) + { + x->x_device_number = -1; + error("[hidio] can not open device %d",device_number); + } + else + { + x->x_device_open = 1; + pthread_mutex_unlock(&x->x_mutex); + /* restore the polling state so that when I [tgl] is used to start/stop [hidio], + * the [tgl]'s state will continue to accurately reflect [hidio]'s state */ + if (started) + hidio_set_from_float(x,x->x_delay); + debug_print(LOG_DEBUG,"[hidio] set device# to %d",device_number); + output_open_status(x); + output_device_number(x); + pthread_mutex_lock(&x->x_mutex); + } + if (x->x_requestcode == REQUEST_OPEN) + x->x_requestcode = REQUEST_NOTHING; + pthread_cond_signal(&x->x_answercondition); + } + else if (x->x_requestcode == REQUEST_READ) + { + if (x->x_requestcode == REQUEST_READ) + x->x_requestcode = REQUEST_NOTHING; + pthread_cond_signal(&x->x_answercondition); + } + else if (x->x_requestcode == REQUEST_SEND) + { + if (x->x_requestcode == REQUEST_SEND) + x->x_requestcode = REQUEST_NOTHING; + pthread_cond_signal(&x->x_answercondition); + } + else if (x->x_requestcode == REQUEST_CLOSE) + { + pthread_mutex_unlock(&x->x_mutex); + hidio_close(x); + pthread_mutex_lock(&x->x_mutex); + if (x->x_requestcode == REQUEST_CLOSE) + x->x_requestcode = REQUEST_NOTHING; + pthread_cond_signal(&x->x_answercondition); + } + else if (x->x_requestcode == REQUEST_QUIT) + { + pthread_mutex_unlock(&x->x_mutex); + hidio_close(x); + pthread_mutex_lock(&x->x_mutex); + x->x_requestcode = REQUEST_NOTHING; + pthread_cond_signal(&x->x_answercondition); + break; /* leave the while loop */ + } + else + { + ; /* nothing: shouldn't get here anyway */ + } + } + pthread_mutex_unlock(&x->x_mutex); + return (0); + } + + + /*------------------------------------------------------------------------------ * system functions */ static void hidio_free(t_hidio* x) { + void *threadrtn; + debug_print(LOG_DEBUG,"hidio_free"); ! /* stop polling for input */ ! if (x->x_clock) ! clock_unset(x->x_clock); ! ! pthread_mutex_lock(&x->x_mutex); ! /* request QUIT and wait for acknowledge */ ! x->x_requestcode = REQUEST_QUIT; ! if (x->x_thread) ! { ! post("hidio: stopping worker thread. . ."); ! pthread_cond_signal(&x->x_requestcondition); ! while (x->x_requestcode != REQUEST_NOTHING) ! { ! post("hidio: ...signalling..."); ! pthread_cond_signal(&x->x_requestcondition); ! pthread_cond_wait(&x->x_answercondition, &x->x_mutex); ! } ! pthread_mutex_unlock(&x->x_mutex); ! if (pthread_join(x->x_thread, &threadrtn)) ! error("hidio_free: join failed"); ! post("hidio: ...done"); ! } ! else pthread_mutex_unlock(&x->x_mutex); ! clock_free(x->x_clock); hidio_instance_count--;
hidio_platform_specific_free(x); + + pthread_cond_destroy(&x->x_requestcondition); + pthread_cond_destroy(&x->x_answercondition); + pthread_mutex_destroy(&x->x_mutex); }
*************** *** 520,523 **** --- 629,636 ---- #endif
+ pthread_mutex_init(&x->x_mutex, 0); + pthread_cond_init(&x->x_requestcondition, 0); + pthread_cond_init(&x->x_answercondition, 0); + x->x_device_number = get_device_number_from_arguments(argc, argv);
*************** *** 525,528 **** --- 638,644 ---- hidio_instance_count++;
+ x->x_requestcode = REQUEST_NOTHING; + pthread_create(&x->x_thread, 0, hidio_child, x); + return (x); }
Index: hidio.h =================================================================== RCS file: /cvsroot/pure-data/externals/io/hidio/hidio.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** hidio.h 1 Dec 2006 15:07:46 -0000 1.2 --- hidio.h 1 Dec 2006 16:04:37 -0000 1.3 *************** *** 4,7 **** --- 4,8 ---- #include <stdio.h> #include <sys/syslog.h> + #include <pthread.h>
#ifdef __linux__ *************** *** 54,57 **** --- 55,70 ----
/*------------------------------------------------------------------------------ + * THREADING RELATED DEFINES + */ + + #define REQUEST_NOTHING 0 + #define REQUEST_OPEN 1 + #define REQUEST_READ 2 + #define REQUEST_SEND 3 + #define REQUEST_CLOSE 4 + #define REQUEST_QUIT 5 + + + /*------------------------------------------------------------------------------ * CLASS DEF */ *************** *** 74,77 **** --- 87,95 ---- t_outlet *x_data_outlet; t_outlet *x_status_outlet; + t_int x_requestcode; + pthread_mutex_t x_mutex; + pthread_cond_t x_requestcondition; + pthread_cond_t x_answercondition; + pthread_t x_thread; } t_hidio;