Re: R: XForms: More on the subject of threads

From: Steve Lamont (spl@blinky.ucsd.edu)
Date: Tue Jun 13 2000 - 16:29:31 EDT

  • Next message: Clive A Stubbings: "Re: XForms: Bug report for fl_show_fselector(..)"

    # To subscribers of the xforms list from Steve Lamont <spl@blinky.UCSD.Edu> :

    > Thank you Steve for your very detailed and useful idea.
    > There is a caveat (as always...).
    > Try it: if you use XInitThreads() then any input field (as in
    > file selector...) where a keyboard input is expected lockups the
    > program if a key is pressed.
    > I think it is a problem in X. And you?

    Hm. I just tested a modified version of the test code (below) with an
    input field in the form and with fl_show_fselector() invoked by the
    click callback and it worked okay.

    The only problem I saw was that the do_stuff() function running in the
    threads blocked at the mutex lock until the file selector closed but
    this is to be expected since fl_show_fselector() is called from within
    the main loop mutex lock (by fl_check_forms() ultimately calling
    click_cb(), which calls fl_show_fselector()).

    This is probably the case for any of the Goodies. The only workaround
    for this would be to write your own version of the Goodies you use.
    Not perfect but not impossible, either.

                                                            spl
                                    - - -
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>

    #include <pthread.h>

    #include "forms.h"

    extern void click_cb(FL_OBJECT *, long);
    extern void input_cb(FL_OBJECT *, long);

    typedef struct {
            FL_FORM *try;
            void *vdata;
            char *cdata;
            long ldata;
            FL_OBJECT *input;
            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 input_cb( FL_OBJECT *ob, long data )

    {

        fprintf( stderr, "got input %s\n", fl_get_input( ob ) );

    }

    void click_cb( FL_OBJECT *ob, long data )

    {

        const char *file;

        file = fl_show_fselector( "Select something",
                                  ".", "*.c", "try.c" );
        if ( file )
            fprintf( stderr, "selected `%s'\n", file );

    }

    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, 295);
        obj = fl_add_box(FL_EMBOSSED_BOX,0,0,150,295,"");
        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,"Thread 1");
        fl_set_object_boxtype(obj,FL_NO_BOX);
        fdui->b[1] =
            obj = fl_add_lightbutton(FL_PUSH_BUTTON,25,115,105,25,"Thread 2");
        fl_set_object_boxtype(obj,FL_NO_BOX);
        fdui->b[3] =
            obj = fl_add_lightbutton(FL_PUSH_BUTTON,25,185,105,25,"Thread 4");
        fl_set_object_boxtype(obj,FL_NO_BOX);
        fdui->b[2] =
            obj = fl_add_lightbutton(FL_PUSH_BUTTON,25,150,105,25,"Thread 3");
        fl_set_object_boxtype(obj,FL_NO_BOX);
        fdui->input = obj = fl_add_input(FL_NORMAL_INPUT,30,235,90,35,"Input");
        fl_set_object_lalign(obj,FL_ALIGN_TOP);
        fl_set_object_callback(obj,input_cb,0);
        fl_end_form();
        
        fdui->try->fdui = fdui;

        return fdui;

    }
    _________________________________________________
    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 : Tue Jun 13 2000 - 16:37:17 EDT