Re: Redundant code in gtk_propagate_event()



On Thu, 4 Oct 2001, Padraig O'Briain wrote:

> I had been assuming that if the event was not handled, i.e. gtk_widget_event() 
> returned false, then no change would have occurred.

that's not a good assumption to make, there are various things
that happen upon dispatching an event on a widget.
1) ::event is emitted with the event as data, and can carry
   signal handlers that shuffle things but return FALSE.
2) ::*_event, the event specific GtkWidgetClass signal is being
   emitted, same thing about signal handlers applies here.
   since this is the signal that most widget implementations
   actually provide a class signal handler for, this is also
   the place were various other signals on the same obejct are
   being emitted from (e.g. ::text_insert due to a key press event).
3) ::event_after is being emitted with the event as data. this is
   a pure notification signal, i.e. returns void, and signal handlers
   don't (cannot) return whether they handled it (altered the widget).

> 
> Thanks for your patience.

in general, upon emitting signals, people should keep in mind that
_arbitrary_ things can happen. here, "arbitrary" is really to be taken
in the most paranoid sense, i.e. the object you get out of g_signal_emit()
might have:
- had its field contents shuffled (so don't keep a pointer to e.g.
  label->text across it),
- unrealized and/or removed from its parent, and in case you intend to
  check that, it probably got readded to another container and therefore
  was rerealized ;)
- been destroyed, thus other objects it held a reference to might be
  gone already (e.g. adjustments, children)
- be finalized, i.e. dead, if someone released a reference count to it.
  so if one wants to at all continue to use an object across signal emission,
  use code like:
  ref (o);
  emit (o);
  use_frobnicator (o);
  unref (o);

if you now think i'm exagerating, think of people that perform CORBA calls
from within signal handlers (two way, so they also take incoming calls
meanwhile) or running recursive main loops (think popping up modal dialogs
due to e.g. "File/Open") or simply popping down a dialog by destroying
its window due to a ::button_press_event on an "Ok" button.

unfortunately, not all code takes the required robustness measurements
to be deduced from the above reentrancy concerns, which is why some
applications tend to be really crashy ;(

> 
> Padraig
> 

---
ciaoTJ





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