Re: GUI still hanging...



In message <39076F28.80EA52F9@cs.nmt.edu>you write:
>This works (kinda), but I still have to call
>a gtk_button_leave() in the while loop to get
>my button to pop up. The code I'm using is
>the following:
>
>   pthread_create(&rwin->tid, NULL, ftp_connect_thread, NULL);
>   while(gtk_events_pending())
>   {
>      g_main_iteration(FALSE);
>      gtk_button_leave(GTK_BUTTON(toolbar->cd_button));
>   }

Sorry, this is wrong. This loop will simply flush out existing events,
and then breaks, and continues on to call:

>   pthread_join(rwin->tid, &thread_ret);

which then blocks, as you've observed.

You can't make this work in a simple fashion. If you have another
thread which is going to take some time for it to finish, you should
not be blocking on its completion. Instead, you need to arrange for it
to notify you that its done in an asynchronous fashion. One method for
doing this, and the one easiest to integrate into GTK, is to use a
pipe.

pseudo code:

       void
       ftp_thread (void *arg)

       { 
          char c;
          ... do my stuff ...
	  if (ok) {
	      c = 0;
	  } else {
	      c = 1;
	  }
	  write (ftp_thread_pipe[1], &c, 1);
	  pthread_exit (0);
       }

       
   in GUI thread:
   
       int ftp_thread_pipe[2];

       pipe (ftp_thread_pipe);

        ... make pipe non-blocking with fcntl ... 

       /* add it to the set of fd's select(2)-ed in the glib main loop */

       gtk_input_add (ftp_thread_pipe[0],
                      GDK_INPUT_READ,
		      ftp_thread_pipe_callback);

       /* create the thread */
 		      
       pthread_create (&thread_id, NULL, ftp_thread, arg);

       /* ... continue with other stuff ... */

   with

       void ftp_thread_pipe_callback (void *arg, int fd, 
                                      GdkInputCondition cond)
           
       {
              char c;

	      while (read (ftp_thread_pipe[0], &c, 1) == 1) {
		    if (c == 0) {
			  /* FTP thread completed OK */
			  
			  .... do something ...
			     
		    } else {
		          /* FTP thread failed */
			  
			  ... do something ...

	            }
              }
        }

I hope this gives you the general idea.

--p		  




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]