Threads
<!-- ##### SECTION Short_Description ##### -->
-functions for using GDK in multi-threaded programs
+Functions for using GDK in multi-threaded programs
<!-- ##### SECTION Long_Description ##### -->
<para>
at any given time.
</para>
<para>
+Unfortunately the above holds with the X11 backend only. With the
+Win32 backend, GDK calls should not be attempted from multiple threads
+at all.
+</para>
+<para>
You must call g_thread_init() and gdk_threads_init() before executing
any other GTK+ or GDK functions in a threaded GTK+ program.
</para>
<para>
-Idles, timeouts, and input functions are executed outside
-of the main GTK+ lock. So, if you need to call GTK+
-inside of such a callback, you must surround the callback
-with a gdk_threads_enter()/gdk_threads_leave() pair.
-(However, signals are still executed within the main
-GTK+ lock.)
+Idles, timeouts, and input functions from GLib, such as g_idle_add(), are
+executed outside of the main GTK+ lock.
+So, if you need to call GTK+ inside of such a callback, you must surround
+the callback with a gdk_threads_enter()/gdk_threads_leave() pair or use
+gdk_threads_add_idle_full() which does this for you.
+However, event dispatching from the mainloop is still executed within
+the main GTK+ lock, so callback functions connected to event signals
+like GtkWidget::button-press-event, do not need thread protection.
</para>
<para>
In particular, this means, if you are writing widgets that might
a signal handler with a gdk_threads_enter()/gdk_threads_leave() pair.
</para>
+<para>
+Before calling gdk_threads_leave() from a thread other
+than your main thread, you probably want to call gdk_flush()
+to send all pending commands to the windowing system.
+(The reason you don't need to do this from the main thread
+is that GDK always automatically flushes pending commands
+when it runs out of incoming events to process and has
+to sleep while waiting for more events.)
+</para>
+
<para>A minimal main program for a threaded GTK+ application
looks like:</para>
g_thread_init (NULL);
gdk_threads_init (<!-- -->);
+ gdk_threads_enter (<!-- -->);
+
gtk_init (&argc, &argv);
window = create_window (<!-- -->);
gtk_widget_show (window);
- gdk_threads_enter (<!-- -->);
gtk_main (<!-- -->);
gdk_threads_leave (<!-- -->);
/* init threads */
g_thread_init (NULL);
gdk_threads_init (<!-- -->);
+ gdk_threads_enter (<!-- -->);
/* init gtk */
gtk_init(&argc, &argv);
/* create a window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC (destroy), NULL);
+ g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
pthread_create (&no_tid, NULL, argument_thread, &no_args);
/* enter the GTK main loop */
- gdk_threads_enter (<!-- -->);
gtk_main (<!-- -->);
gdk_threads_leave (<!-- -->);
</para>
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### SECTION Image ##### -->
+
+
<!-- ##### MACRO GDK_THREADS_ENTER ##### -->
<para>
-This macro marks the beginning of a critical section in which GDK and GTK+
-functions can be called. Only one thread at a time can be in such a
-critial section. The macro expands to a no-op if #G_THREADS_ENABLED
-has not been defined. Typically gdk_threads_enter() should be used
-instead of this macro.
+This macro marks the beginning of a critical section in which GDK and
+GTK+ functions can be called safely and without causing race
+conditions. Only one thread at a time can be in such a critial
+section. The macro expands to a no-op if #G_THREADS_ENABLED has not
+been defined. Typically gdk_threads_enter() should be used instead of
+this macro.
</para>
</para>
+@void:
<!-- ##### FUNCTION gdk_threads_enter ##### -->
<para>
-This macro marks the beginning of a critical section
-in which GDK and GTK+ functions can be called.
-Only one thread at a time can be in such a critial
+This macro marks the beginning of a critical section in which GDK and
+GTK+ functions can be called safely and without causing race
+conditions. Only one thread at a time can be in such a critial
section.
</para>
+@void:
<!-- ##### FUNCTION gdk_threads_leave ##### -->
Leaves a critical region begun with gdk_threads_enter().
</para>
+@void:
<!-- ##### VARIABLE gdk_threads_mutex ##### -->
<para>
The #GMutex used to implement the critical region for
-gdk_threads_enter()/gdk_threads_leave(). This variable should not be
-used directly — consider it private.
+gdk_threads_enter()/gdk_threads_leave().
+</para>
+
+
+<!-- ##### FUNCTION gdk_threads_set_lock_functions ##### -->
+<para>
+
+</para>
+
+@enter_fn:
+@leave_fn:
+
+
+<!-- ##### FUNCTION gdk_threads_add_idle ##### -->
+<para>
+
+</para>
+
+@function:
+@data:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_threads_add_idle_full ##### -->
+<para>
+
+</para>
+
+@priority:
+@function:
+@data:
+@notify:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_threads_add_timeout ##### -->
+<para>
+
+</para>
+
+@interval:
+@function:
+@data:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_threads_add_timeout_full ##### -->
+<para>
+
+</para>
+
+@priority:
+@interval:
+@function:
+@data:
+@notify:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_threads_add_timeout_seconds ##### -->
+<para>
+
</para>
+@interval:
+@function:
+@data:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_threads_add_timeout_seconds_full ##### -->
+<para>
+
+</para>
+
+@priority:
+@interval:
+@function:
+@data:
+@notify:
+@Returns:
+