Re: gtk1.2 -> gtk2.0: recursing expose events



On 27 May 2003, Owen Taylor wrote:

On Sun, 2003-05-25 at 13:35, Richard Guenther wrote:
Hi!

I'm trying to get GLAME ported to gtk/gnome 2.0 and am stuck at trying
to find out, why gtk segfaults on me if recursing into the expose event
of a GtkDrawingArea.

The matter is to do async redrawing by checking gtk_events_pending() in
a heavyweight redraw function which is connected to the expose_event of
a drawing area.

The code looks like

expose_event_cb()
{
   static int expose_cnt;

   if (expose_cnt++ > 0) {
       /* merge exposes */
       return TRUE;
   }

again:
   expose_cnt = 0;

   for (;;) {

       /* partial redraw */

      if (gtk_events_pending()) {
           while (gtk_events_pending())
               gtk_main_iteration();

       if (expose_cnt > 0) {
          /* remember undrawn */
              goto out;
           }
      }

   }

out:
   if (expose_cnt > 0)
       goto again;

   return TRUE;
}

And I'm getting backtraces like

#5  <signal handler called>
#6  0x0f057370 in gdk_event_get_graphics_expose () from
/usr/lib/libgdk-x11-2.0.so.0
#7  0x0f058f30 in gdk_add_client_message_filter () from
/usr/lib/libgdk-x11-2.0.so.0
#8  0x0f0591d0 in _gdk_events_queue () from /usr/lib/libgdk-x11-2.0.so.0
#9  0x0f059474 in _gdk_events_queue () from /usr/lib/libgdk-x11-2.0.so.0
#10 0x0ede7990 in g_get_current_time () from /usr/lib/libglib-2.0.so.0
#11 0x0ede8c78 in g_main_context_dispatch () from
/usr/lib/libglib-2.0.so.0
#12 0x0ede9000 in g_main_context_dispatch () from
/usr/lib/libglib-2.0.so.0
#13 0x0ede9264 in g_main_context_iteration () from
/usr/lib/libglib-2.0.so.0
#14 0x0f1a063c in gtk_main_iteration () from /usr/lib/libgtk-x11-2.0.so.0

where frame #14 is the gtk_main_iteration() call in the above loop.

Any hints what changed between gtk1.2 and 2.0 to make this fail? Any ideas
on how to convert such handlers?

I'd actually be *very* interested if you could produce a test case
that reliably reproduces the above crash ... it's the same backtrace as:

 http://bugzilla.gnome.org/show_bug.cgi?id=105745

A bad GDK crash that something in GNOME is triggering in rare
conditions that we've had no luck in tracking down so far.

And the goal is that no matter how weird stuff an app does, GTK+
shouldn't crash.

(In fact, I'm so interested, that I won't make my usual fuss
about small, standalone test cases. Whatever code you have
is fine.)

If you really want to, you can get the glame CVS from sourceforge
(sf.net/projects/glame)
and look into src/gui/libgtkwaveform/gtkwaveview.c - the relevant
functions are gtk_wave_view_redraw_wave and on_area_expose_event (the
former gets called by the latter), re-enable the #if0'ed code at line
650 and you get crashes scrolling the wavewidget very fast.

Maybe I have time at the weekend to produce a smaller testcase, just
ripping off all but the above functions and stick the expose to a
drawing area should be enough, I think.

I just wanted to know if its ok in principle to call gtk_main_iteration()
from an expose event? And then possibly receive another expose during this
operation?

Though, in the end, I'm somewhat surprised that code of that
nature worked in GTK+-1.2. Both GTK+-1.2 and GTK+-2.0 already have
expose compression code internally before the app ever gets
an expose. The GTK+-1.2 code looks a bit like the above (but
hunts the event queue instead of iterating the main loop), the
GTK+-2.0 code is more sophisticated and sane.

So, for your app, just ditch the compression code. When you
get an expose event, compression has already happened

I know, the above code is not expose event compression, but async
redrawing - redrawing one pixel may cost us >1s here and such we
check for pending events and execute the main loop just like anyone
does for busy computation loops. Of course we need to detect other
expose events coming by and merge them in.

 event->area is the bounding box
 event->region is the exact GdkRegion of the exposed area

Regards,
                                          Owen

Thanks,

Richard.

--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/




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