Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2001:
[Freeciv-Dev] Re: possible segfault and help!
Home

[Freeciv-Dev] Re: possible segfault and help!

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: kero@xxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: possible segfault and help!
From: Mike Kaufman <mkaufman@xxxxxxxxxxxxxx>
Date: Mon, 12 Mar 2001 21:44:43 -0600 (CST)

I'm wondering if my example discounts at least part of that. If, for
example, the callback didn't run until after the calling function had
completed, then my program would segfault no matter which toggle button
wasactivated.

> As I just learned from David, gtk uses an event-loop, so the callback
> triggered by setting the radio-button to zero, will be executed
> _after_ the current function is completely finished and control is
> passed back to gtk.

If that were true, then in the example program below, the printf would
never print 1, it would always print 0. 

What I found out (after posting, of course) was that if I set a toggle
active before registering the callback and then set it true again, it
won't trigger the callback (not even to unset and then set it
again). Also, if I set all the toggles false before registering the
callback, gtk will automatically set the 0th button true. (which is also
why my 'patch' to dialogs.c is bogus)

Solution: block the signal and place the relevant code in the calling
function.

> 'coz if an event would trigger a new function _before_ finishing its
> current function, you would immediately have multiple threads when the
> _user_ creates a new event.

now maybe my example is tangential since my code generates the event
rather than a user clicking a button...

> 
> And now, David, I have to tell Mike what would happen if his were
> the case: There are >1 threads of control _and_you_will_never_know_
> _the_order_of_execution_ hence random crashes on your -1 index. That's
> worse than a 100% guarantee of a crash.
> 
> Bye,
> Kero.

--mike 

#include<gtk/gtk.h>
#include<stdio.h>

struct dlg {
  GtkWidget *shell;
  GtkWidget **races_toggles;
  int i;
};

/*****************************************************************/
static void races_toggles_callback( GtkWidget *w, struct dlg *en)
{
  printf("into callback\n");fflush(stdout);/* DEBUG */
  en->i = 1;  /* valid array index */
}

/*****************************************************************/
static void select_random_race(struct dlg *en)
{
  en->i = 0;

   gtk_toggle_button_set_state(
     GTK_TOGGLE_BUTTON(en->races_toggles[1]),TRUE);

  printf("%d\n",en->i);fflush(stdout);/* DEBUG */
}

/*****************************************************************/
int main(int argc, char **argv)
{
  int i;
  char buffer[3];
  struct dlg *en;
  GSList *group = NULL;

  gtk_init(&argc,&argv);

  en        = (struct dlg *)malloc(sizeof(struct dlg));
  en->i     = -1;              /* invalid array index */
  en->shell = gtk_dialog_new();

  en->races_toggles = (GtkWidget**)malloc(5*sizeof(GtkWidget*));

  for(i=0; i < 15 ; i++) {
    sprintf(buffer,"%d",i);

    en->races_toggles[i] = gtk_radio_button_new_with_label(group, buffer);

    /* setting FALSE -> TRUE cures it */
    group =
gtk_radio_button_group(GTK_RADIO_BUTTON(en->races_toggles[i]));

    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(en->races_toggles[i]),
FALSE);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(en->shell)->vbox),
      en->races_toggles[i],FALSE,FALSE,0);
  }

  for(i=0; i< 15 ; i++)
     gtk_signal_connect(GTK_OBJECT(en->races_toggles[i]), "toggled",
       races_toggles_callback, (gpointer)en );
  
  select_random_race(en);
  
  gtk_widget_show_all(en->shell);
  gtk_main();
  return 0;
}





[Prev in Thread] Current Thread [Next in Thread]