]> Pileus Git - ~andy/gtk/commitdiff
docs: Move documentation to inline comments: gdkthreads
authorJavier Jardón <jjardon@gnome.org>
Mon, 15 Nov 2010 18:37:28 +0000 (19:37 +0100)
committerJavier Jardón <jjardon@gnome.org>
Mon, 15 Nov 2010 20:06:35 +0000 (21:06 +0100)
docs/reference/gdk/tmpl/.gitignore
docs/reference/gdk/tmpl/threads.sgml [deleted file]
gdk/gdk.c
gdk/gdkthreads.h

index 0256910f0628019b0ee9eb697d3254e6013b68fa..7b5f673a1e652fe30191253047103545af4c0026 100644 (file)
@@ -15,5 +15,6 @@ properties.sgml
 pixbufs.sgml
 regions.sgml
 selections.sgml
+threads.sgml
 visuals.sgml
 windows.sgml
diff --git a/docs/reference/gdk/tmpl/threads.sgml b/docs/reference/gdk/tmpl/threads.sgml
deleted file mode 100644 (file)
index 7b857d8..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-<!-- ##### SECTION Title ##### -->
-Threads
-
-<!-- ##### SECTION Short_Description ##### -->
-Functions for using GDK in multi-threaded programs
-
-<!-- ##### SECTION Long_Description ##### -->
-<para>
-For thread safety, GDK relies on the thread primitives in GLib, 
-and on the thread-safe GLib main loop.
-</para>
-<para>
-GLib is completely thread safe (all global data is automatically 
-locked), but individual data structure instances are not automatically 
-locked for performance reasons. So e.g. you must coordinate 
-accesses to the same #GHashTable from multiple threads.
-</para>
-<para>
-GTK+ is "thread aware" but not thread safe &mdash; it provides a
-global lock controlled by gdk_threads_enter()/gdk_threads_leave()
-which protects all use of GTK+. That is, only one thread can use GTK+ 
-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 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 
-be used in threaded programs, you <emphasis>must</emphasis> surround 
-timeouts and idle functions in this matter.
-</para>
-<para>
-As always, you must also surround any calls to GTK+ not made within 
-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>
-
-<informalexample>
-<programlisting role="C">
-int
-main (int argc, char *argv[])
-{
-  GtkWidget *window;
-
-  g_thread_init (NULL);
-  gdk_threads_init (<!-- -->);
-  gdk_threads_enter (<!-- -->);
-
-  gtk_init (&amp;argc, &amp;argv);
-
-  window = create_window (<!-- -->);
-  gtk_widget_show (window);
-
-  gtk_main (<!-- -->);
-  gdk_threads_leave (<!-- -->);
-
-  return 0;
-}
-</programlisting>
-</informalexample>
-
-<para>
-Callbacks require a bit of attention. Callbacks from GTK+ signals
-are made within the GTK+ lock. However callbacks from GLib (timeouts,
-IO callbacks, and idle functions) are made outside of the GTK+
-lock. So, within a signal handler you do not need to call
-gdk_threads_enter(), but within the other types of callbacks, you
-do.
-</para>
-
-<para>Erik Mouw contributed the following code example to
-illustrate how to use threads within GTK+ programs.
-</para>
-
-<informalexample>
-<programlisting role="C">
-/*-------------------------------------------------------------------------
- * Filename:      gtk-thread.c
- * Version:       0.99.1
- * Copyright:     Copyright (C) 1999, Erik Mouw
- * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
- * Description:   GTK threads example. 
- * Created at:    Sun Oct 17 21:27:09 1999
- * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
- * Modified at:   Sun Oct 24 17:21:41 1999
- *-----------------------------------------------------------------------*/
-/*
- * Compile with:
- *
- * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
- *
- * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
- * bugs.
- *
- */
-
-&num;include &lt;stdio.h&gt;
-&num;include &lt;stdlib.h&gt;
-&num;include &lt;unistd.h&gt;
-&num;include &lt;time.h&gt;
-&num;include &lt;gtk/gtk.h&gt;
-&num;include &lt;glib.h&gt;
-&num;include &lt;pthread.h&gt;
-
-&num;define YES_IT_IS    (1)
-&num;define NO_IT_IS_NOT (0)
-
-typedef struct 
-{
-  GtkWidget *label;
-  int what;
-} yes_or_no_args;
-
-G_LOCK_DEFINE_STATIC (yes_or_no);
-static volatile int yes_or_no = YES_IT_IS;
-
-void destroy (GtkWidget *widget, gpointer data)
-{
-  gtk_main_quit (<!-- -->);
-}
-
-void *argument_thread (void *args)
-{
-  yes_or_no_args *data = (yes_or_no_args *)args;
-  gboolean say_something;
-
-  for (;;)
-    {
-      /* sleep a while */
-      sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
-
-      /* lock the yes_or_no_variable */
-      G_LOCK(yes_or_no);
-
-      /* do we have to say something? */
-      say_something = (yes_or_no != data->what);
-
-      if(say_something)
-       {
-         /* set the variable */
-         yes_or_no = data->what;
-       }
-
-      /* Unlock the yes_or_no variable */
-      G_UNLOCK (yes_or_no);
-
-      if (say_something)
-       {
-         /* get GTK thread lock */
-         gdk_threads_enter (<!-- -->);
-
-         /* set label text */
-         if(data->what == YES_IT_IS)
-           gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
-         else
-           gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
-
-         /* release GTK thread lock */
-         gdk_threads_leave (<!-- -->);
-       }
-    }
-
-  return NULL;
-}
-
-int main (int argc, char *argv[])
-{
-  GtkWidget *window;
-  GtkWidget *label;
-  yes_or_no_args yes_args, no_args;
-  pthread_t no_tid, yes_tid;
-
-  /* init threads */
-  g_thread_init (NULL);
-  gdk_threads_init (<!-- -->);
-  gdk_threads_enter (<!-- -->);
-
-  /* init gtk */
-  gtk_init(&amp;argc, &amp;argv);
-
-  /* init random number generator */
-  srand ((unsigned int) time (NULL));
-
-  /* create a window */
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-  g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
-
-  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-
-  /* create a label */
-  label = gtk_label_new ("And now for something completely different ...");
-  gtk_container_add (GTK_CONTAINER (window), label);
-  
-  /* show everything */
-  gtk_widget_show (label);
-  gtk_widget_show (window);
-
-  /* create the threads */
-  yes_args.label = label;
-  yes_args.what = YES_IT_IS;
-  pthread_create (&amp;yes_tid, NULL, argument_thread, &amp;yes_args);
-
-  no_args.label = label;
-  no_args.what = NO_IT_IS_NOT;
-  pthread_create (&amp;no_tid, NULL, argument_thread, &amp;no_args);
-
-  /* enter the GTK main loop */
-  gtk_main (<!-- -->);
-  gdk_threads_leave (<!-- -->);
-
-  return 0;
-}
-</programlisting>
-</informalexample>
-
-<!-- ##### SECTION See_Also ##### -->
-<para>
-
-</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 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>
-
-
-
-<!-- ##### MACRO GDK_THREADS_LEAVE ##### -->
-<para>
-This macro marks the end of a critical section 
-begun with #GDK_THREADS_ENTER.
-</para>
-
-
-
-<!-- ##### FUNCTION gdk_threads_init ##### -->
-<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 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 ##### -->
-<para>
-Leaves a critical region begun with gdk_threads_enter(). 
-</para>
-
-@void: 
-
-
-<!-- ##### 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: 
-
-
index 8c701ff6e6d342ad1089ef06fafb4fc42dab217d..f0ff4336eb82ce2a474483a28e504987573c7132 100644 (file)
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -399,6 +399,244 @@ gdk_init (int *argc, char ***argv)
     }
 }
 
+
+
+/**
+ * SECTION:threads
+ * @Short_description: Functions for using GDK in multi-threaded programs
+ * @Title: Threads
+ *
+ * For thread safety, GDK relies on the thread primitives in GLib,
+ * and on the thread-safe GLib main loop.
+ *
+ * GLib is completely thread safe (all global data is automatically
+ * locked), but individual data structure instances are not automatically
+ * locked for performance reasons. So e.g. you must coordinate
+ * accesses to the same #GHashTable from multiple threads.
+ *
+ * GTK+ is "thread aware" but not thread safe &mdash; it provides a
+ * global lock controlled by gdk_threads_enter()/gdk_threads_leave()
+ * which protects all use of GTK+. That is, only one thread can use GTK+
+ * at any given time.
+ *
+ * Unfortunately the above holds with the X11 backend only. With the
+ * Win32 backend, GDK calls should not be attempted from multiple threads
+ * at all.
+ *
+ * You must call g_thread_init() and gdk_threads_init() before executing
+ * any other GTK+ or GDK functions in a threaded GTK+ program.
+ *
+ * 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.
+ *
+ * In particular, this means, if you are writing widgets that might
+ * be used in threaded programs, you <emphasis>must</emphasis> surround
+ * timeouts and idle functions in this matter.
+ *
+ * As always, you must also surround any calls to GTK+ not made within
+ * a signal handler with a gdk_threads_enter()/gdk_threads_leave() pair.
+ *
+ * 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.)
+ *
+ * A minimal main program for a threaded GTK+ application
+ * looks like:
+ * <informalexample>
+ * <programlisting role="C">
+ * int
+ * main (int argc, char *argv[])
+ * {
+ *   GtkWidget *window;
+ *
+ *   g_thread_init (NULL);
+ *   gdk_threads_init (<!-- -->);
+ *   gdk_threads_enter (<!-- -->);
+ *
+ *   gtk_init (&argc, &argv);
+ *
+ *   window = create_window (<!-- -->);
+ *   gtk_widget_show (window);
+ *
+ *   gtk_main (<!-- -->);
+ *   gdk_threads_leave (<!-- -->);
+ *
+ *   return 0;
+ * }
+ * </programlisting>
+ * </informalexample>
+ *
+ * Callbacks require a bit of attention. Callbacks from GTK+ signals
+ * are made within the GTK+ lock. However callbacks from GLib (timeouts,
+ * IO callbacks, and idle functions) are made outside of the GTK+
+ * lock. So, within a signal handler you do not need to call
+ * gdk_threads_enter(), but within the other types of callbacks, you
+ * do.
+ *
+ * Erik Mouw contributed the following code example to
+ * illustrate how to use threads within GTK+ programs.
+ * <informalexample>
+ * <programlisting role="C">
+ * /<!---->*-------------------------------------------------------------------------
+ *  * Filename:      gtk-thread.c
+ *  * Version:       0.99.1
+ *  * Copyright:     Copyright (C) 1999, Erik Mouw
+ *  * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
+ *  * Description:   GTK threads example.
+ *  * Created at:    Sun Oct 17 21:27:09 1999
+ *  * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
+ *  * Modified at:   Sun Oct 24 17:21:41 1999
+ *  *-----------------------------------------------------------------------*<!---->/
+ * /<!---->*
+ *  * Compile with:
+ *  *
+ *  * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
+ *  *
+ *  * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
+ *  * bugs.
+ *  *
+ *  *<!---->/
+ *
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <unistd.h>
+ * #include <time.h>
+ * #include <gtk/gtk.h>
+ * #include <glib.h>
+ * #include <pthread.h>
+ *
+ * #define YES_IT_IS    (1)
+ * #define NO_IT_IS_NOT (0)
+ *
+ * typedef struct
+ * {
+ *   GtkWidget *label;
+ *   int what;
+ * } yes_or_no_args;
+ *
+ * G_LOCK_DEFINE_STATIC (yes_or_no);
+ * static volatile int yes_or_no = YES_IT_IS;
+ *
+ * void destroy (GtkWidget *widget, gpointer data)
+ * {
+ *   gtk_main_quit (<!-- -->);
+ * }
+ *
+ * void *argument_thread (void *args)
+ * {
+ *   yes_or_no_args *data = (yes_or_no_args *)args;
+ *   gboolean say_something;
+ *
+ *   for (;;)
+ *     {
+ *       /<!---->* sleep a while *<!---->/
+ *       sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
+ *
+ *       /<!---->* lock the yes_or_no_variable *<!---->/
+ *       G_LOCK(yes_or_no);
+ *
+ *       /<!---->* do we have to say something? *<!---->/
+ *       say_something = (yes_or_no != data->what);
+ *
+ *       if(say_something)
+ *     {
+ *       /<!---->* set the variable *<!---->/
+ *       yes_or_no = data->what;
+ *     }
+ *
+ *       /<!---->* Unlock the yes_or_no variable *<!---->/
+ *       G_UNLOCK (yes_or_no);
+ *
+ *       if (say_something)
+ *     {
+ *       /<!---->* get GTK thread lock *<!---->/
+ *       gdk_threads_enter (<!-- -->);
+ *
+ *       /<!---->* set label text *<!---->/
+ *       if(data->what == YES_IT_IS)
+ *         gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
+ *       else
+ *         gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
+ *
+ *       /<!---->* release GTK thread lock *<!---->/
+ *       gdk_threads_leave (<!-- -->);
+ *     }
+ *     }
+ *
+ *   return NULL;
+ * }
+ *
+ * int main (int argc, char *argv[])
+ * {
+ *   GtkWidget *window;
+ *   GtkWidget *label;
+ *   yes_or_no_args yes_args, no_args;
+ *   pthread_t no_tid, yes_tid;
+ *
+ *   /<!---->* init threads *<!---->/
+ *   g_thread_init (NULL);
+ *   gdk_threads_init (<!-- -->);
+ *   gdk_threads_enter (<!-- -->);
+ *
+ *   /<!---->* init gtk *<!---->/
+ *   gtk_init(&argc, &argv);
+ *
+ *   /<!---->* init random number generator *<!---->/
+ *   srand ((unsigned int) time (NULL));
+ *
+ *   /<!---->* create a window *<!---->/
+ *   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ *
+ *   g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
+ *
+ *   gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+ *
+ *   /<!---->* create a label *<!---->/
+ *   label = gtk_label_new ("And now for something completely different ...");
+ *   gtk_container_add (GTK_CONTAINER (window), label);
+ *
+ *   /<!---->* show everything *<!---->/
+ *   gtk_widget_show (label);
+ *   gtk_widget_show (window);
+ *
+ *   /<!---->* create the threads *<!---->/
+ *   yes_args.label = label;
+ *   yes_args.what = YES_IT_IS;
+ *   pthread_create (&yes_tid, NULL, argument_thread, &yes_args);
+ *
+ *   no_args.label = label;
+ *   no_args.what = NO_IT_IS_NOT;
+ *   pthread_create (&no_tid, NULL, argument_thread, &no_args);
+ *
+ *   /<!---->* enter the GTK main loop *<!---->/
+ *   gtk_main (<!-- -->);
+ *   gdk_threads_leave (<!-- -->);
+ *
+ *   return 0;
+ * }
+ * </programlisting>
+ * </informalexample>
+ */
+
+
+/**
+ * gdk_threads_enter:
+ *
+ * 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.
+ */
 void
 gdk_threads_enter (void)
 {
@@ -406,6 +644,11 @@ gdk_threads_enter (void)
     (*gdk_threads_lock) ();
 }
 
+/**
+ * gdk_threads_leave:
+ *
+ * Leaves a critical region begun with gdk_threads_enter().
+ */
 void
 gdk_threads_leave (void)
 {
@@ -429,7 +672,7 @@ gdk_threads_impl_unlock (void)
 
 /**
  * gdk_threads_init:
- * 
+ *
  * Initializes GDK so that it can be used from multiple threads
  * in conjunction with gdk_threads_enter() and gdk_threads_leave().
  * g_thread_init() must be called previous to this function.
index 743e6ec6fa1b79561d7fcbc5970770b014ed0dab..ad2f09d5d9d1677f12c0047d824f21572b117706 100644 (file)
@@ -64,7 +64,24 @@ guint    gdk_threads_add_timeout_seconds      (guint          interval,
                                                GSourceFunc    function,
                                                gpointer       data);
 
+/**
+ * GDK_THREADS_ENTER:
+ *
+ * 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.
+ */
 #define GDK_THREADS_ENTER() gdk_threads_enter()
+
+/**
+ * GDK_THREADS_LEAVE:
+ *
+ * This macro marks the end of a critical section
+ * begun with #GDK_THREADS_ENTER.
+ */
 #define GDK_THREADS_LEAVE() gdk_threads_leave()
 
 G_END_DECLS