~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to docs/reference/gdk/xml/threads.xml

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<refentry id="gdk-Threads">
 
2
<refmeta>
 
3
<refentrytitle role="top_of_page">Threads</refentrytitle>
 
4
<manvolnum>3</manvolnum>
 
5
<refmiscinfo>GDK Library</refmiscinfo>
 
6
</refmeta>
 
7
 
 
8
<refnamediv>
 
9
<refname>Threads</refname>
 
10
<refpurpose>Functions for using GDK in multi-threaded programs</refpurpose>
 
11
<!--[<xref linkend="desc" endterm="desc.title"/>]-->
 
12
</refnamediv>
 
13
 
 
14
<refsynopsisdiv role="synopsis">
 
15
<title role="synopsis.title">Synopsis</title>
 
16
 
 
17
<synopsis>
 
18
 
 
19
#include &lt;gdk/gdk.h&gt;
 
20
 
 
21
 
 
22
#define             <link linkend="GDK-THREADS-ENTER:CAPS">GDK_THREADS_ENTER</link>                   ()
 
23
#define             <link linkend="GDK-THREADS-LEAVE:CAPS">GDK_THREADS_LEAVE</link>                   ()
 
24
<link linkend="void">void</link>                <link linkend="gdk-threads-init">gdk_threads_init</link>                    (void);
 
25
<link linkend="void">void</link>                <link linkend="gdk-threads-enter">gdk_threads_enter</link>                   (void);
 
26
<link linkend="void">void</link>                <link linkend="gdk-threads-leave">gdk_threads_leave</link>                   (void);
 
27
extern              GMutex *<link linkend="gdk-threads-mutex">gdk_threads_mutex</link>;
 
28
<link linkend="void">void</link>                <link linkend="gdk-threads-set-lock-functions">gdk_threads_set_lock_functions</link>      (<link linkend="GCallback">GCallback</link> enter_fn,
 
29
                                                         <link linkend="GCallback">GCallback</link> leave_fn);
 
30
 
 
31
</synopsis>
 
32
</refsynopsisdiv>
 
33
 
 
34
 
 
35
 
 
36
 
 
37
 
 
38
 
 
39
 
 
40
 
 
41
 
 
42
<refsect1 role="desc">
 
43
<title role="desc.title">Description</title>
 
44
<para>
 
45
For thread safety, GDK relies on the thread primitives in GLib, 
 
46
and on the thread-safe GLib main loop.
 
47
</para>
 
48
<para>
 
49
GLib is completely thread safe (all global data is automatically 
 
50
locked), but individual data structure instances are not automatically 
 
51
locked for performance reasons. So e.g. you must coordinate 
 
52
accesses to the same <link linkend="GHashTable"><type>GHashTable</type></link> from multiple threads.
 
53
</para>
 
54
<para>
 
55
GTK+ is "thread aware" but not thread safe &mdash; it provides a
 
56
global lock controlled by <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>/<link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link>
 
57
which protects all use of GTK+. That is, only one thread can use GTK+ 
 
58
at any given time.
 
59
</para>
 
60
<para>
 
61
Unfortunately the above holds with the X11 backend only. With the
 
62
Win32 backend, GDK calls should not be attempted from multiple threads
 
63
at all.
 
64
</para>
 
65
<para>
 
66
You must call <link linkend="g-thread-init"><function>g_thread_init()</function></link> and <link linkend="gdk-threads-init"><function>gdk_threads_init()</function></link> before executing
 
67
any other GTK+ or GDK functions in a threaded GTK+ program.
 
68
</para>
 
69
<para>
 
70
Idles, timeouts, and input functions are executed outside
 
71
of the main GTK+ lock. So, if you need to call GTK+
 
72
inside of such a callback, you must surround the callback
 
73
with a <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>/<link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link> pair.
 
74
(However, signals are still executed within the main
 
75
GTK+ lock.)
 
76
</para>
 
77
<para>
 
78
In particular, this means, if you are writing widgets that might 
 
79
be used in threaded programs, you <emphasis>must</emphasis> surround 
 
80
timeouts and idle functions in this matter.
 
81
</para>
 
82
<para>
 
83
As always, you must also surround any calls to GTK+ not made within 
 
84
a signal handler with a <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>/<link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link> pair.
 
85
</para>
 
86
 
 
87
<para>
 
88
Before calling <link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link> from a thread other
 
89
than your main thread, you probably want to call <link linkend="gdk-flush"><function>gdk_flush()</function></link>
 
90
to send all pending commands to the windowing system.
 
91
(The reason you don't need to do this from the main thread
 
92
is that GDK always automatically flushes pending commands
 
93
when it runs out of incoming events to process and has
 
94
to sleep while waiting for more events.)
 
95
</para>
 
96
 
 
97
<para>A minimal main program for a threaded GTK+ application
 
98
looks like:</para>
 
99
 
 
100
<informalexample>
 
101
<programlisting role="C">
 
102
int
 
103
main (int argc, char *argv[])
 
104
{
 
105
  GtkWidget *window;
 
106
 
 
107
  g_thread_init (NULL);
 
108
  gdk_threads_init (<!-- -->);
 
109
  gdk_threads_enter (<!-- -->);
 
110
 
 
111
  gtk_init (&amp;argc, &amp;argv);
 
112
 
 
113
  window = create_window (<!-- -->);
 
114
  gtk_widget_show (window);
 
115
 
 
116
  gtk_main (<!-- -->);
 
117
  gdk_threads_leave (<!-- -->);
 
118
 
 
119
  return 0;
 
120
}
 
121
</programlisting>
 
122
</informalexample>
 
123
 
 
124
<para>
 
125
Callbacks require a bit of attention. Callbacks from GTK+ signals
 
126
are made within the GTK+ lock. However callbacks from GLib (timeouts,
 
127
IO callbacks, and idle functions) are made outside of the GTK+
 
128
lock. So, within a signal handler you do not need to call
 
129
<link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>, but within the other types of callbacks, you
 
130
do.
 
131
</para>
 
132
 
 
133
<para>Erik Mouw contributed the following code example to
 
134
illustrate how to use threads within GTK+ programs.
 
135
</para>
 
136
 
 
137
<informalexample>
 
138
<programlisting role="C">
 
139
/*-------------------------------------------------------------------------
 
140
 * Filename:      gtk-thread.c
 
141
 * Version:       0.99.1
 
142
 * Copyright:     Copyright (C) 1999, Erik Mouw
 
143
 * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
 
144
 * Description:   GTK threads example. 
 
145
 * Created at:    Sun Oct 17 21:27:09 1999
 
146
 * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
 
147
 * Modified at:   Sun Oct 24 17:21:41 1999
 
148
 *-----------------------------------------------------------------------*/
 
149
/*
 
150
 * Compile with:
 
151
 *
 
152
 * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
 
153
 *
 
154
 * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
 
155
 * bugs.
 
156
 *
 
157
 */
 
158
 
 
159
&num;include &lt;stdio.h&gt;
 
160
&num;include &lt;stdlib.h&gt;
 
161
&num;include &lt;unistd.h&gt;
 
162
&num;include &lt;time.h&gt;
 
163
&num;include &lt;gtk/gtk.h&gt;
 
164
&num;include &lt;glib.h&gt;
 
165
&num;include &lt;pthread.h&gt;
 
166
 
 
167
&num;define YES_IT_IS    (1)
 
168
&num;define NO_IT_IS_NOT (0)
 
169
 
 
170
typedef struct 
 
171
{
 
172
  GtkWidget *label;
 
173
  int what;
 
174
} yes_or_no_args;
 
175
 
 
176
G_LOCK_DEFINE_STATIC (yes_or_no);
 
177
static volatile int yes_or_no = YES_IT_IS;
 
178
 
 
179
void destroy (GtkWidget *widget, gpointer data)
 
180
{
 
181
  gtk_main_quit (<!-- -->);
 
182
}
 
183
 
 
184
void *argument_thread (void *args)
 
185
{
 
186
  yes_or_no_args *data = (yes_or_no_args *)args;
 
187
  gboolean say_something;
 
188
 
 
189
  for (;;)
 
190
    {
 
191
      /* sleep a while */
 
192
      sleep(rand(<!-- -->) / (RAND_MAX / 3) + 1);
 
193
 
 
194
      /* lock the yes_or_no_variable */
 
195
      G_LOCK(yes_or_no);
 
196
 
 
197
      /* do we have to say something? */
 
198
      say_something = (yes_or_no != data->what);
 
199
 
 
200
      if(say_something)
 
201
        {
 
202
          /* set the variable */
 
203
          yes_or_no = data->what;
 
204
        }
 
205
 
 
206
      /* Unlock the yes_or_no variable */
 
207
      G_UNLOCK (yes_or_no);
 
208
 
 
209
      if (say_something)
 
210
        {
 
211
          /* get GTK thread lock */
 
212
          gdk_threads_enter (<!-- -->);
 
213
 
 
214
          /* set label text */
 
215
          if(data->what == YES_IT_IS)
 
216
            gtk_label_set_text (GTK_LABEL (data->label), "O yes, it is!");
 
217
          else
 
218
            gtk_label_set_text (GTK_LABEL (data->label), "O no, it isn't!");
 
219
 
 
220
          /* release GTK thread lock */
 
221
          gdk_threads_leave (<!-- -->);
 
222
        }
 
223
    }
 
224
 
 
225
  return NULL;
 
226
}
 
227
 
 
228
int main (int argc, char *argv[])
 
229
{
 
230
  GtkWidget *window;
 
231
  GtkWidget *label;
 
232
  yes_or_no_args yes_args, no_args;
 
233
  pthread_t no_tid, yes_tid;
 
234
 
 
235
  /* init threads */
 
236
  g_thread_init (NULL);
 
237
  gdk_threads_init (<!-- -->);
 
238
  gdk_threads_enter (<!-- -->);
 
239
 
 
240
  /* init gtk */
 
241
  gtk_init(&amp;argc, &amp;argv);
 
242
 
 
243
  /* init random number generator */
 
244
  srand ((unsigned int) time (NULL));
 
245
 
 
246
  /* create a window */
 
247
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
248
 
 
249
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
 
250
                      GTK_SIGNAL_FUNC (destroy), NULL);
 
251
 
 
252
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
 
253
 
 
254
  /* create a label */
 
255
  label = gtk_label_new ("And now for something completely different ...");
 
256
  gtk_container_add (GTK_CONTAINER (window), label);
 
257
  
 
258
  /* show everything */
 
259
  gtk_widget_show (label);
 
260
  gtk_widget_show (window);
 
261
 
 
262
  /* create the threads */
 
263
  yes_args.label = label;
 
264
  yes_args.what = YES_IT_IS;
 
265
  pthread_create (&amp;yes_tid, NULL, argument_thread, &amp;yes_args);
 
266
 
 
267
  no_args.label = label;
 
268
  no_args.what = NO_IT_IS_NOT;
 
269
  pthread_create (&amp;no_tid, NULL, argument_thread, &amp;no_args);
 
270
 
 
271
  /* enter the GTK main loop */
 
272
  gtk_main (<!-- -->);
 
273
  gdk_threads_leave (<!-- -->);
 
274
 
 
275
  return 0;
 
276
}
 
277
</programlisting>
 
278
</informalexample>
 
279
</refsect1>
 
280
 
 
281
<refsect1 role="details">
 
282
<title role="details.title">Details</title>
 
283
<refsect2>
 
284
<title><anchor id="GDK-THREADS-ENTER:CAPS" role="macro"/>GDK_THREADS_ENTER()</title>
 
285
<indexterm><primary>GDK_THREADS_ENTER</primary></indexterm><programlisting>#define             GDK_THREADS_ENTER()</programlisting>
 
286
<para>
 
287
This macro marks the beginning of a critical section in which GDK and GTK+
 
288
functions can be called.  Only one thread at a time can be in such a
 
289
critial section. The macro expands to a no-op if <link linkend="G-THREADS-ENABLED:CAPS"><type>G_THREADS_ENABLED</type></link>
 
290
has not been defined. Typically <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link> should be used 
 
291
instead of this macro.
 
292
</para></refsect2>
 
293
<refsect2>
 
294
<title><anchor id="GDK-THREADS-LEAVE:CAPS" role="macro"/>GDK_THREADS_LEAVE()</title>
 
295
<indexterm><primary>GDK_THREADS_LEAVE</primary></indexterm><programlisting>#define             GDK_THREADS_LEAVE()</programlisting>
 
296
<para>
 
297
This macro marks the end of a critical section 
 
298
begun with <link linkend="GDK-THREADS-ENTER:CAPS"><type>GDK_THREADS_ENTER</type></link>.
 
299
</para></refsect2>
 
300
<refsect2>
 
301
<title><anchor id="gdk-threads-init" role="function"/>gdk_threads_init ()</title>
 
302
<indexterm><primary>gdk_threads_init</primary></indexterm><programlisting><link linkend="void">void</link>                gdk_threads_init                    (void);</programlisting>
 
303
<para>
 
304
Initializes GDK so that it can be used from multiple threads
 
305
in conjunction with <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link> and <link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link>.
 
306
<link linkend="g-thread-init"><function>g_thread_init()</function></link> must be called previous to this function.
 
307
</para>
 
308
<para>
 
309
This call must be made before any use of the main loop from
 
310
GTK+; to be safe, call it before <link linkend="gtk-init"><function>gtk_init()</function></link>.</para>
 
311
<para>
 
312
 
 
313
</para></refsect2>
 
314
<refsect2>
 
315
<title><anchor id="gdk-threads-enter" role="function"/>gdk_threads_enter ()</title>
 
316
<indexterm><primary>gdk_threads_enter</primary></indexterm><programlisting><link linkend="void">void</link>                gdk_threads_enter                   (void);</programlisting>
 
317
<para>
 
318
This macro marks the beginning of a critical section
 
319
in which GDK and GTK+ functions can be called.
 
320
Only one thread at a time can be in such a critial 
 
321
section.
 
322
</para></refsect2>
 
323
<refsect2>
 
324
<title><anchor id="gdk-threads-leave" role="function"/>gdk_threads_leave ()</title>
 
325
<indexterm><primary>gdk_threads_leave</primary></indexterm><programlisting><link linkend="void">void</link>                gdk_threads_leave                   (void);</programlisting>
 
326
<para>
 
327
Leaves a critical region begun with <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>. 
 
328
</para></refsect2>
 
329
<refsect2>
 
330
<title><anchor id="gdk-threads-mutex" role="variable" condition="deprecated:"/>gdk_threads_mutex</title>
 
331
<indexterm role="deprecated"><primary>gdk_threads_mutex</primary></indexterm><programlisting>extern GMutex *gdk_threads_mutex; /* private */
 
332
</programlisting>
 
333
<warning><para><literal>gdk_threads_mutex</literal> is deprecated and should not be used in newly-written code.</para></warning>
 
334
<para>
 
335
The <link linkend="GMutex"><type>GMutex</type></link> used to implement the critical region for
 
336
<link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>/<link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link>. 
 
337
</para></refsect2>
 
338
<refsect2>
 
339
<title><anchor id="gdk-threads-set-lock-functions" role="function" condition="since:2.4"/>gdk_threads_set_lock_functions ()</title>
 
340
<indexterm role="2.4"><primary>gdk_threads_set_lock_functions</primary></indexterm><programlisting><link linkend="void">void</link>                gdk_threads_set_lock_functions      (<link linkend="GCallback">GCallback</link> enter_fn,
 
341
                                                         <link linkend="GCallback">GCallback</link> leave_fn);</programlisting>
 
342
<para>
 
343
Allows the application to replace the standard method that
 
344
GDK uses to protect its data structures. Normally, GDK
 
345
creates a single <link linkend="GMutex"><type>GMutex</type></link> that is locked by <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link>,
 
346
and released by <link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link>; using this function an
 
347
application provides, instead, a function <parameter>enter_fn</parameter> that is
 
348
called by <link linkend="gdk-threads-enter"><function>gdk_threads_enter()</function></link> and a function <parameter>leave_fn</parameter> that is
 
349
called by <link linkend="gdk-threads-leave"><function>gdk_threads_leave()</function></link>.
 
350
</para>
 
351
<para>
 
352
The functions must provide at least same locking functionality
 
353
as the default implementation, but can also do extra application
 
354
specific processing.
 
355
</para>
 
356
<para>
 
357
As an example, consider an application that has its own recursive
 
358
lock that when held, holds the GTK+ lock as well. When GTK+ unlocks
 
359
the GTK+ lock when entering a recursive main loop, the application
 
360
must temporarily release its lock as well.
 
361
</para>
 
362
<para>
 
363
Most threaded GTK+ apps won't need to use this method.
 
364
</para>
 
365
<para>
 
366
This method must be called before <link linkend="gdk-threads-init"><function>gdk_threads_init()</function></link>, and cannot
 
367
be called multiple times.</para>
 
368
<para>
 
369
 
 
370
</para><variablelist role="params">
 
371
<varlistentry><term><parameter>enter_fn</parameter>&nbsp;:</term>
 
372
<listitem><simpara>   function called to guard GDK
 
373
</simpara></listitem></varlistentry>
 
374
<varlistentry><term><parameter>leave_fn</parameter>&nbsp;:</term>
 
375
<listitem><simpara> function called to release the guard
 
376
</simpara></listitem></varlistentry>
 
377
</variablelist><para role="since">Since  2.4
 
378
</para></refsect2>
 
379
 
 
380
</refsect1>
 
381
 
 
382
 
 
383
 
 
384
 
 
385
</refentry>