# To subscribers of the xforms list from "T.C. Zhao" <tc_zhao@yahoo.com> :
Thanks Steve. Good insight.
--- Steve Lamont <spl@blinky.ucsd.edu> wrote:
> # To subscribers of the xforms list from Steve Lamont
> <spl@blinky.ucsd.edu> :
>
> I did some reading and research, digging briefly into the innards of
> XForms, and may have a potential workaround for the lack of direct
> threads support in XForms.
>
> The major problem lies in the fact that asynchronous events (button
> clicks, etc.) can bollix up the works if some thread is attempting to
> update a form.
>
> I may have a workaround which eventually, with embellishments, should
> probably get folded into XForms. That is to replace the XForms main
> loop, fl_do_forms() with
>
>
> EXTERN pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
>
> [...]
>
> while ( 1 ) {
>
> pthread_mutex_lock( &mutex );
> fl_check_forms();
> pthread_mutex_unlock( &mutex );
> /* you may need to sleep here to give up the CPU to */
> /* the concurrent threads */
>
> }
>
> Any thread that makes an XForms call should do
>
> pthread_mutex_lock( &mutex );
> fl_whatever( ... );
> pthread_mutex_unlock( &mutex );
>
> Callbacks do not need to set a mutex lock since they're already in a
> mutex -- they're called by fl_check_forms().
>
> The following rather simpleminded application should be a useful
> illustration of how this can be done.
>
> I compiled it on Solaris 8 with
>
> gcc -fpcc-struct-return try.c -o try \
> -L/usr/openwin/lib -lforms -lXpm -lXext -lX11 \
> -lpthread -lm
>
> I've been running it while composing this email (probably about 20
> minutes -- I write slowly) with nary a hiccough.
>
> - - -
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/time.h>
>
> #include <pthread.h>
>
> #include "forms.h"
>
> extern void click_cb(FL_OBJECT *, long);
>
> typedef struct {
> FL_FORM *try;
> void *vdata;
> char *cdata;
> long ldata;
> FL_OBJECT *b[4];
> } FD_try;
>
> extern FD_try * create_form_try(void);
>
> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
> FD_try *fd_try;
>
> void click_cb( FL_OBJECT *ob, long data )
>
> {
>
> FD_try *fd_try = ( FD_try *) ob->form->fdui;
> int whatever_button = lrand48() % 4;
>
> /* No mutex needed here */
>
> fl_set_button( fd_try->b[whatever_button],
> !fl_get_button( fd_try->b[whatever_button] ) );
>
> }
>
> void *do_stuff( void *arg )
>
> {
>
> while ( 1 ) {
>
> struct timeval sleepy_time;
> int random_button = lrand48() % 4; /* Pick a random button */
>
> /* Wait some random time */
>
> sleepy_time.tv_sec = 0;
> sleepy_time.tv_usec = lrand48() % 100000; /* 10 msec max */
> select( 0, NULL, NULL, NULL, &sleepy_time );
>
> pthread_mutex_lock( &mutex ); { /* critical section */
>
> fl_set_button( fd_try->b[random_button],
> !fl_get_button( fd_try->b[random_button] ) );
>
> } pthread_mutex_unlock( &mutex );
>
> }
>
> }
>
> int main(int argc, char *argv[])
>
> {
>
> int i;
> pthread_t pthread_id;
>
> XInitThreads(); /* Make Xlib happy -- this must be called */
> /* before any other Xlib calls. Requires */
> /* X11R6 */
>
> fl_initialize( &argc, argv, 0, 0, 0 );
>
> fd_try = create_form_try();
>
> fl_show_form( fd_try->try,
> FL_PLACE_CENTERFREE,
> FL_FULLBORDER,
> "try" );
>
> thr_setconcurrency( 5 ); /* A Solaris thing -- other systems will
> */
> /* probably require pthread_setconcurrency() */
>
> for ( i = 0; i < 4; i++ ) { /* Launch the threads */
>
> pthread_attr_t attr;
>
> pthread_attr_init( &attr );
> pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
>
> pthread_create( &pthread_id, &attr, do_stuff, NULL );
>
> pthread_attr_destroy( &attr );
>
> }
>
> /* Replace fl_do_forms() */
>
> while ( 1 ) {
>
> struct timeval sleepy_time;
>
> /* Give up the CPU for 10 milliseconds */
>
> sleepy_time.tv_sec = 0;
> sleepy_time.tv_usec = 10000
> select( 0, NULL, NULL, NULL, &sleepy_time );
>
> pthread_mutex_lock( &mutex ); { /* Critial section */
>
> fl_check_forms();
>
> } pthread_mutex_unlock( &mutex );
>
> }
>
> return 0;
>
> }
>
> FD_try *create_form_try(void)
>
> {
>
> FL_OBJECT *obj;
> FD_try *fdui = (FD_try *) fl_calloc(1, sizeof(*fdui));
>
> fdui->try = fl_bgn_form(FL_NO_BOX, 150, 230);
> obj = fl_add_box(FL_EMBOSSED_BOX,0,0,150,230,"");
> fl_set_object_color(obj,FL_LEFT_BCOL,FL_COL1);
> obj = fl_add_button(FL_NORMAL_BUTTON,20,20,110,40,"Click Me");
> fl_set_object_callback(obj,click_cb,0);
> fdui->b[0] = obj =
> fl_add_lightbutton(FL_PUSH_BUTTON,25,80,105,25,"Button 1");
> fl_set_object_boxtype(obj,FL_NO_BOX);
> fdui->b[1] = obj =
> fl_add_lightbutton(FL_PUSH_BUTTON,25,115,105,25,"Button 2");
> fl_set_object_boxtype(obj,FL_NO_BOX);
> fdui->b[3] = obj =
> fl_add_lightbutton(FL_PUSH_BUTTON,25,185,105,25,"Button 4");
> fl_set_object_boxtype(obj,FL_NO_BOX);
> fdui->b[2] = obj =
> fl_add_lightbutton(FL_PUSH_BUTTON,25,150,105,25,"Button 3");
> fl_set_object_boxtype(obj,FL_NO_BOX);
> fl_end_form();
>
=== message truncated ===
__________________________________________________
Do You Yahoo!?
Yahoo! Photos -- now, 100 FREE prints!
http://photos.yahoo.com
_________________________________________________
To unsubscribe, send the message "unsubscribe" to
xforms-request@bob.usuhs.mil or see
http://bob.usuhs.mil/mailserv/xforms.html
XForms Home Page: http://world.std.com/~xforms
List Archive: http://bob.usuhs.mil/mailserv/list-archives/
This archive was generated by hypermail 2b29 : Sat Jun 03 2000 - 18:13:46 EDT