Re: XForms: More on the subject of threads

From: T.C. Zhao (tc_zhao@yahoo.com)
Date: Sat Jun 03 2000 - 18:09:12 EDT

  • Next message: Daniela Soares de Almeida: "XForms: Segmentation Fault using xyplot"

    # 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