After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 138161 - Return value from gtk_main_iteration is not valid
Return value from gtk_main_iteration is not valid
Status: RESOLVED NOTABUG
Product: gtk+
Classification: Platform
Component: Documentation
2.2.x
Other All
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2004-03-26 02:32 UTC by Andrew P. Lentvorski, Jr.
Modified: 2011-02-04 16:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gtk_main_iteration test program (1.09 KB, text/plain)
2004-03-26 02:33 UTC, Andrew P. Lentvorski, Jr.
  Details
New test case demonstrating further problems (1.44 KB, text/plain)
2004-03-27 00:45 UTC, Andrew P. Lentvorski, Jr.
  Details
Patch to isolate mainloop pieces (2.68 KB, patch)
2004-03-28 10:10 UTC, Andrew P. Lentvorski, Jr.
none Details | Review
New test case showing how to implement a user code main loop correctly (1.12 KB, text/plain)
2004-03-28 10:12 UTC, Andrew P. Lentvorski, Jr.
  Details

Description Andrew P. Lentvorski, Jr. 2004-03-26 02:32:41 UTC
Compile and run the attached program.  The print statements track what the
correct value should be and show the incorrect value being returned.
Comment 1 Andrew P. Lentvorski, Jr. 2004-03-26 02:33:48 UTC
Created attachment 25956 [details]
gtk_main_iteration test program
Comment 2 Andrew P. Lentvorski, Jr. 2004-03-26 02:34:42 UTC
This bug prevent people from manually taking control of the gtk event loop.  How
do projects work around this?
Comment 3 Owen Taylor 2004-03-26 15:33:44 UTC
Docs bug - the return value is whether any events are pending.
Comment 4 Owen Taylor 2004-03-26 17:08:10 UTC
Didn't actually mean to close, since the docs are wrong.
Comment 5 Andrew P. Lentvorski, Jr. 2004-03-27 00:45:56 UTC
Created attachment 25994 [details]
New test case demonstrating further problems
Comment 6 Andrew P. Lentvorski, Jr. 2004-03-27 00:55:51 UTC
Well, if that's what the docs are supposed to say, that makes the problem
*worse*, not better.  There is no way to determine if gtk_main_quit() was called
without explicity setting a global variable on every exit point in user code. 
Even this solution may not be possible if someone is using a builder like Glade.

In addition, there is a mismatch between the return code and gtk_events_pending.
 The attached second test case demonstrates the problem.

The docs currently explain what is actually the most useful behavior; the flag
should reflect whether gtk_main_quit() was called.  That is the only piece of
information which it is not possible to get using gtk_XXX functions (if this is
an incorrect statement, please feel free to correct me).
Comment 7 Andrew P. Lentvorski, Jr. 2004-03-27 01:33:41 UTC
Okay, I figured this would be an easy patch, then I looked at the Gtk code for
gtk_main().  Grumble.  Since gtk_main() is not implemented in terms of
gtk_main_iteration() there is a lot of extra state floating around that
gtk_main() adds.  It also explains why gtk_loop_level returns an incorrect
answer when using iterations.

So much for an easy patch.

The correct solution is probably to split gtk_main() apart and add two helper
functions:  gtk_main_iteration_enter() and gtk_main_iteration_leave(). 
gtk_main_iteration_enter() would establish all of the state which now sits at
the beginning of gtk_main(); gtk_main_iteration_leave() would handle all of the
cleanup which now sits at the end of gtk_main() and gtk_main_iteration() would
handle the main loop in the center.

Consequently, gtk_main() would remain unchanged.  However, programs could get at
the main loop correctly from their own source code by explicitly calling the
gtk_main_iteration_(enter,do,leave) trio.  At this point, all of the loop level
and event pending functions would be correct as well as the state which
gtk_main() adds (which is currently unavailable when using gtk_main_iteration())
Comment 8 Owen Taylor 2004-03-27 15:21:07 UTC
gtk_main_quit() is *purely* convenience functionality; no GTK+
function ever calls it. If you want to write your own main loop,
just keep your own quit variable.

(Note also that gtk_main_iteration() is obsolete; see the 
mainloop functionality in GLib for the current interfaces)

Chnaging the return value of the gtk_main_iteration() function
to mean something different isn't an option.

Comment 9 Andrew P. Lentvorski, Jr. 2004-03-27 22:14:29 UTC
This is not true.  Please look at the code.  gtktreeview.c and gtkwidget.c both
call gtk_main_iteration in 2.4.0.  Possibly those particular functions might
also be convenience, but it is there.

In fact, since the return value is useless, both of these functions throw it away.

As I explained earlier, the issue is with builders like Glade which are wired to
use gtk_main_quit().  I *cannot* just "write my own main loop" without access to
the gtk state.

I'm also becoming convinced that there are some threading issues that are the
fault of not having the initialized state activated.

Finally, if the system gets split into gtk_main_iteration_{enter,do,leave}, then
the return value of gtk_main_iteration can remain exactly the same because
gtk_main_level() will now return a useful value.

Clearly we're talking past one another, I'll try to submit a patch later to clarify.
Comment 10 Andrew P. Lentvorski, Jr. 2004-03-28 10:10:52 UTC
Created attachment 26016 [details] [review]
Patch to isolate mainloop pieces

This patch creates three new functions:
gtk_main_loop_enter()
gtk_main_loop_iterate()
gtk_main_loop_leave()

and then implements the gtk_main() function in terms of them.  The only
question is whether the gtk_main_loop_iterate function is equivalent to the
g_main_loop_run() function.  Someone with far more knowledge than I have about
gtk internals should looks at that.

However, the preliminary tests I have run all seem to behave equivalently.
Comment 11 Andrew P. Lentvorski, Jr. 2004-03-28 10:12:19 UTC
Created attachment 26017 [details]
New test case showing how to implement a user code main loop correctly
Comment 12 Andrew P. Lentvorski, Jr. 2004-03-28 10:22:13 UTC
The original docs appear to be correct in intent about gtk_main_iteration(). 
The relevant code is from gtkmain.c:

>  if (main_loops)
>    return !g_main_loop_is_running (main_loops->data);
>  else
>    return TRUE;

The intent is that if a main_loop is still active, return the complement of its
state.  The primary means of killing an active main loop is gtk_main_quit(), so
this code matches the docs. 

I might argue that returning TRUE when no loop exists is probably not the best
choice, but it is now standard and probably cannot be fixed while maintaining
binary compatibility.
Comment 13 Owen Taylor 2004-03-28 15:11:46 UTC
Hmm, you seem to be right about gtk_main_iteration() return value;
because it's an obsolete useless function, I had forgotten what 
it returned; the correct resolution is probably to add "or if gtk_main_run() h
has not been called" to the docs.

Let me give you a very brief overview of the big picture to show
you why you are really looking in the wrong places for writing
a custom main looop:

The basic unit of running the main loop in GLib/GTK+
g_main_context_iteration() which checks for pending events, possibly
waits for new events, and then dispatches the events found. 

(You can actually break it into individual pieces, but I'll ignore
that for now.)

This operation has no concept of quitting. The concept of quiting is
introduced with GMainLoop; g_main_loop_run() conceptually does

 while (loop->running)
   g_main_context_iteration (loop->context, ...)

while g_main_loop_quit() does loop->running = FALSE;  

gtk_main_run() and gtk_main_quit() are convenience functions that
create a stack of GMainLoop objects; gtk_main_run() adds a new
loop to the stack and calls g_main_loop_run() on it, gtk_main_quit()
quites the topmost loop. No GTK+ function ever calls either of
these two functions; they are purely convenience. You can write
a perfectly correct GTK+ program using only the GLib functionality.

While some GTK+ functions may run a recursive main loop
(gtk_widget_show_now(), gtk_dialog_run(), gtk_clipboard_wait...())
the main loop they run always terminates based only on
conditions documented for these functions; if gtk_main_quit() 
caused these functions to terminate, that would be a serious bug
in GTK+. These functions thus don't use gtk_main_run(), they use
GMainLoop or just do iterations directly and check their own
quit variable.

(The main thing that GMainLoop gives you is that it works correctly
with multiple threads; the fact that gtk_widget_show_now() doesn't
use it is a minor bug.)
Comment 14 Andrew P. Lentvorski, Jr. 2004-03-28 22:56:03 UTC
The context that this came up in was a PyGtk app that needed to make the Gtk
loop inferior to another framework event loop.  By opening the Gtk loop, I can
make both systems intermix.

Unfortunately, PyGtk (and other wrappers) very rarely wrap glib since the
languages natively have most of its functionality.  Consequently, glib calls are
really out of the question.  Gtk needs to provide the hooks to get at the glib
calls directly (even if they are just pass through functions).

As for gtk_main_quit(), the fact that a Gtk function may not work if I take over
the event loop is a bug in my book.  There is no indication that gtk_main_quit()
is merely convenience or that it may not work.  I think most developers would be
stunned to have several of the gtk functions simply quit working because an app
took manual control of the event loop.

At this point, this is clearly an architectural discussion.  I'd like to take
this to one of the mailing lists.  Which mailing list should I take it to? 
gtk-devel or gtk-app-devel?
Comment 15 Matthias Clasen 2004-04-23 20:52:26 UTC
gtk-devel is the right list
Comment 16 Elijah Newren 2004-06-19 18:42:36 UTC
Mass changing gtk+ bugs with target milestone of 2.4.2 to target 2.4.4, as
Matthias said he was trying to do himself on IRC and was asking for help with. 
If you see this message, it means I was successful at fixing the borken-ness in
bugzilla :)  Sorry for the spam; just query on this message and delete all
emails you get with this message, since there will probably be a lot.
Comment 17 weskaggs 2004-10-11 17:02:46 UTC
Closing as NOTABUG because the discussion has moved to the mailing lists.  If
this bug report remains relevant, please reopen and add a summary of developments.
Comment 18 Owen Taylor 2004-10-12 03:36:19 UTC
Reopening, closed inappropriuately.