• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 2000-2001 Red Hat, Inc.
3  * Copyright (C) 2005 Imendio AB
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 /*
22  * MT safe with regards to reference counting.
23  */
24 
25 #include "config.h"
26 
27 #include <string.h>
28 
29 #include "gclosure.h"
30 #include "gvalue.h"
31 #include "gobjectalias.h"
32 
33 
34 /**
35  * SECTION:gclosure
36  * @short_description: Functions as first-class objects
37  * @title: Closures
38  *
39  * A #GClosure represents a callback supplied by the programmer. It
40  * will generally comprise a function of some kind and a marshaller
41  * used to call it. It is the reponsibility of the marshaller to
42  * convert the arguments for the invocation from #GValue<!-- -->s into
43  * a suitable form, perform the callback on the converted arguments,
44  * and transform the return value back into a #GValue.
45  *
46  * In the case of C programs, a closure usually just holds a pointer
47  * to a function and maybe a data argument, and the marshaller
48  * converts between #GValue<!-- --> and native C types. The GObject
49  * library provides the #GCClosure type for this purpose. Bindings for
50  * other languages need marshallers which convert between #GValue<!--
51  * -->s and suitable representations in the runtime of the language in
52  * order to use functions written in that languages as callbacks.
53  *
54  * Within GObject, closures play an important role in the
55  * implementation of signals. When a signal is registered, the
56  * @c_marshaller argument to g_signal_new() specifies the default C
57  * marshaller for any closure which is connected to this
58  * signal. GObject provides a number of C marshallers for this
59  * purpose, see the g_cclosure_marshal_*() functions. Additional C
60  * marshallers can be generated with the <link
61  * linkend="glib-genmarshal">glib-genmarshal</link> utility.  Closures
62  * can be explicitly connected to signals with
63  * g_signal_connect_closure(), but it usually more convenient to let
64  * GObject create a closure automatically by using one of the
65  * g_signal_connect_*() functions which take a callback function/user
66  * data pair.
67  *
68  * Using closures has a number of important advantages over a simple
69  * callback function/data pointer combination:
70  * <itemizedlist>
71  * <listitem><para>
72  * Closures allow the callee to get the types of the callback parameters,
73  * which means that language bindings don't have to write individual glue
74  * for each callback type.
75  * </para></listitem>
76  * <listitem><para>
77  * The reference counting of #GClosure makes it easy to handle reentrancy
78  * right; if a callback is removed while it is being invoked, the closure
79  * and its parameters won't be freed until the invocation finishes.
80  * </para></listitem>
81  * <listitem><para>
82  * g_closure_invalidate() and invalidation notifiers allow callbacks to be
83  * automatically removed when the objects they point to go away.
84  * </para></listitem>
85  * </itemizedlist>
86  */
87 
88 
89 #define	CLOSURE_MAX_REF_COUNT		((1 << 15) - 1)
90 #define	CLOSURE_MAX_N_GUARDS		((1 << 1) - 1)
91 #define	CLOSURE_MAX_N_FNOTIFIERS	((1 << 2) - 1)
92 #define	CLOSURE_MAX_N_INOTIFIERS	((1 << 8) - 1)
93 #define	CLOSURE_N_MFUNCS(cl)		((cl)->meta_marshal + \
94                                          ((cl)->n_guards << 1L))
95 /* same as G_CLOSURE_N_NOTIFIERS() (keep in sync) */
96 #define	CLOSURE_N_NOTIFIERS(cl)		(CLOSURE_N_MFUNCS (cl) + \
97                                          (cl)->n_fnotifiers + \
98                                          (cl)->n_inotifiers)
99 
100 typedef union {
101   GClosure closure;
102   volatile gint vint;
103 } ClosureInt;
104 
105 #define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW)      \
106 G_STMT_START {                                                                          \
107   ClosureInt *cunion = (ClosureInt*) _closure;                 		                \
108   gint new_int, old_int, success;                              		                \
109   do                                                    		                \
110     {                                                   		                \
111       ClosureInt tmp;                                   		                \
112       tmp.vint = old_int = cunion->vint;                		                \
113       _SET_OLD tmp.closure._field;                                                      \
114       tmp.closure._field _OP _value;                      		                \
115       _SET_NEW tmp.closure._field;                                                      \
116       new_int = tmp.vint;                               		                \
117       success = g_atomic_int_compare_and_exchange (&cunion->vint, old_int, new_int);    \
118     }                                                   		                \
119   while (!success && _must_set);                                                        \
120 } G_STMT_END
121 
122 #define SWAP(_closure, _field, _value, _oldv)   CHANGE_FIELD (_closure, _field, =, _value, TRUE, *(_oldv) =,     (void) )
123 #define SET(_closure, _field, _value)           CHANGE_FIELD (_closure, _field, =, _value, TRUE,     (void),     (void) )
124 #define INC(_closure, _field)                   CHANGE_FIELD (_closure, _field, +=,     1, TRUE,     (void),     (void) )
125 #define INC_ASSIGN(_closure, _field, _newv)     CHANGE_FIELD (_closure, _field, +=,     1, TRUE,     (void), *(_newv) = )
126 #define DEC(_closure, _field)                   CHANGE_FIELD (_closure, _field, -=,     1, TRUE,     (void),     (void) )
127 #define DEC_ASSIGN(_closure, _field, _newv)     CHANGE_FIELD (_closure, _field, -=,     1, TRUE,     (void), *(_newv) = )
128 
129 #if 0   /* for non-thread-safe closures */
130 #define SWAP(cl,f,v,o)     (void) (*(o) = cl->f, cl->f = v)
131 #define SET(cl,f,v)        (void) (cl->f = v)
132 #define INC(cl,f)          (void) (cl->f += 1)
133 #define INC_ASSIGN(cl,f,n) (void) (cl->f += 1, *(n) = cl->f)
134 #define DEC(cl,f)          (void) (cl->f -= 1)
135 #define DEC_ASSIGN(cl,f,n) (void) (cl->f -= 1, *(n) = cl->f)
136 #endif
137 
138 enum {
139   FNOTIFY,
140   INOTIFY,
141   PRE_NOTIFY,
142   POST_NOTIFY
143 };
144 
145 
146 /* --- functions --- */
147 /**
148  * g_closure_new_simple:
149  * @sizeof_closure: the size of the structure to allocate, must be at least
150  *                  <literal>sizeof (GClosure)</literal>
151  * @data: data to store in the @data field of the newly allocated #GClosure
152  *
153  * Allocates a struct of the given size and initializes the initial
154  * part as a #GClosure. This function is mainly useful when
155  * implementing new types of closures.
156  *
157  * |[
158  * typedef struct _MyClosure MyClosure;
159  * struct _MyClosure
160  * {
161  *   GClosure closure;
162  *   // extra data goes here
163  * };
164  *
165  * static void
166  * my_closure_finalize (gpointer  notify_data,
167  *                      GClosure *closure)
168  * {
169  *   MyClosure *my_closure = (MyClosure *)closure;
170  *
171  *   // free extra data here
172  * }
173  *
174  * MyClosure *my_closure_new (gpointer data)
175  * {
176  *   GClosure *closure;
177  *   MyClosure *my_closure;
178  *
179  *   closure = g_closure_new_simple (sizeof (MyClosure), data);
180  *   my_closure = (MyClosure *) closure;
181  *
182  *   // initialize extra data here
183  *
184  *   g_closure_add_finalize_notifier (closure, notify_data,
185  *                                    my_closure_finalize);
186  *   return my_closure;
187  * }
188  * ]|
189  *
190  * Returns: a newly allocated #GClosure
191  */
192 GClosure*
g_closure_new_simple(guint sizeof_closure,gpointer data)193 g_closure_new_simple (guint           sizeof_closure,
194 		      gpointer        data)
195 {
196   GClosure *closure;
197 
198   g_return_val_if_fail (sizeof_closure >= sizeof (GClosure), NULL);
199 
200   closure = g_malloc0 (sizeof_closure);
201   SET (closure, ref_count, 1);
202   SET (closure, meta_marshal, 0);
203   SET (closure, n_guards, 0);
204   SET (closure, n_fnotifiers, 0);
205   SET (closure, n_inotifiers, 0);
206   SET (closure, in_inotify, FALSE);
207   SET (closure, floating, TRUE);
208   SET (closure, derivative_flag, 0);
209   SET (closure, in_marshal, FALSE);
210   SET (closure, is_invalid, FALSE);
211   closure->marshal = NULL;
212   closure->data = data;
213   closure->notifiers = NULL;
214   memset (G_STRUCT_MEMBER_P (closure, sizeof (*closure)), 0, sizeof_closure - sizeof (*closure));
215 
216   return closure;
217 }
218 
219 static inline void
closure_invoke_notifiers(GClosure * closure,guint notify_type)220 closure_invoke_notifiers (GClosure *closure,
221 			  guint     notify_type)
222 {
223   /* notifier layout:
224    *     meta_marshal  n_guards    n_guards     n_fnotif.  n_inotifiers
225    * ->[[meta_marshal][pre_guards][post_guards][fnotifiers][inotifiers]]
226    *
227    * CLOSURE_N_MFUNCS(cl)    = meta_marshal + n_guards + n_guards;
228    * CLOSURE_N_NOTIFIERS(cl) = CLOSURE_N_MFUNCS(cl) + n_fnotifiers + n_inotifiers
229    *
230    * constrains/catches:
231    * - closure->notifiers may be reloacted during callback
232    * - closure->n_fnotifiers and closure->n_inotifiers may change during callback
233    * - i.e. callbacks can be removed/added during invocation
234    * - must prepare for callback removal during FNOTIFY and INOTIFY (done via ->marshal= & ->data=)
235    * - must distinguish (->marshal= & ->data=) for INOTIFY vs. FNOTIFY (via ->in_inotify)
236    * + closure->n_guards is const during PRE_NOTIFY & POST_NOTIFY
237    * + closure->meta_marshal is const for all cases
238    * + none of the callbacks can cause recursion
239    * + closure->n_inotifiers is const 0 during FNOTIFY
240    */
241   switch (notify_type)
242     {
243       GClosureNotifyData *ndata;
244       guint i, offs;
245     case FNOTIFY:
246       while (closure->n_fnotifiers)
247 	{
248           guint n;
249 	  DEC_ASSIGN (closure, n_fnotifiers, &n);
250 
251 	  ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n;
252 	  closure->marshal = (GClosureMarshal) ndata->notify;
253 	  closure->data = ndata->data;
254 	  ndata->notify (ndata->data, closure);
255 	}
256       closure->marshal = NULL;
257       closure->data = NULL;
258       break;
259     case INOTIFY:
260       SET (closure, in_inotify, TRUE);
261       while (closure->n_inotifiers)
262 	{
263           guint n;
264           DEC_ASSIGN (closure, n_inotifiers, &n);
265 
266 	  ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n;
267 	  closure->marshal = (GClosureMarshal) ndata->notify;
268 	  closure->data = ndata->data;
269 	  ndata->notify (ndata->data, closure);
270 	}
271       closure->marshal = NULL;
272       closure->data = NULL;
273       SET (closure, in_inotify, FALSE);
274       break;
275     case PRE_NOTIFY:
276       i = closure->n_guards;
277       offs = closure->meta_marshal;
278       while (i--)
279 	{
280 	  ndata = closure->notifiers + offs + i;
281 	  ndata->notify (ndata->data, closure);
282 	}
283       break;
284     case POST_NOTIFY:
285       i = closure->n_guards;
286       offs = closure->meta_marshal + i;
287       while (i--)
288 	{
289 	  ndata = closure->notifiers + offs + i;
290 	  ndata->notify (ndata->data, closure);
291 	}
292       break;
293     }
294 }
295 
296 /**
297  * g_closure_set_meta_marshal:
298  * @closure: a #GClosure
299  * @marshal_data: context-dependent data to pass to @meta_marshal
300  * @meta_marshal: a #GClosureMarshal function
301  *
302  * Sets the meta marshaller of @closure.  A meta marshaller wraps
303  * @closure->marshal and modifies the way it is called in some
304  * fashion. The most common use of this facility is for C callbacks.
305  * The same marshallers (generated by <link
306  * linkend="glib-genmarshal">glib-genmarshal</link>) are used
307  * everywhere, but the way that we get the callback function
308  * differs. In most cases we want to use @closure->callback, but in
309  * other cases we want to use some different technique to retrieve the
310  * callback function.
311  *
312  * For example, class closures for signals (see
313  * g_signal_type_cclosure_new()) retrieve the callback function from a
314  * fixed offset in the class structure.  The meta marshaller retrieves
315  * the right callback and passes it to the marshaller as the
316  * @marshal_data argument.
317  */
318 void
g_closure_set_meta_marshal(GClosure * closure,gpointer marshal_data,GClosureMarshal meta_marshal)319 g_closure_set_meta_marshal (GClosure       *closure,
320 			    gpointer        marshal_data,
321 			    GClosureMarshal meta_marshal)
322 {
323   GClosureNotifyData *notifiers;
324 
325   g_return_if_fail (closure != NULL);
326   g_return_if_fail (meta_marshal != NULL);
327   g_return_if_fail (closure->is_invalid == FALSE);
328   g_return_if_fail (closure->in_marshal == FALSE);
329   g_return_if_fail (closure->meta_marshal == 0);
330 
331   notifiers = closure->notifiers;
332   closure->notifiers = g_renew (GClosureNotifyData, NULL, CLOSURE_N_NOTIFIERS (closure) + 1);
333   if (notifiers)
334     {
335       /* usually the meta marshal will be setup right after creation, so the
336        * g_memmove() should be rare-case scenario
337        */
338       g_memmove (closure->notifiers + 1, notifiers, CLOSURE_N_NOTIFIERS (closure) * sizeof (notifiers[0]));
339       g_free (notifiers);
340     }
341   closure->notifiers[0].data = marshal_data;
342   closure->notifiers[0].notify = (GClosureNotify) meta_marshal;
343   SET (closure, meta_marshal, 1);
344 }
345 
346 /**
347  * g_closure_add_marshal_guards:
348  * @closure: a #GClosure
349  * @pre_marshal_data: data to pass to @pre_marshal_notify
350  * @pre_marshal_notify: a function to call before the closure callback
351  * @post_marshal_data: data to pass to @post_marshal_notify
352  * @post_marshal_notify: a function to call after the closure callback
353  *
354  * Adds a pair of notifiers which get invoked before and after the
355  * closure callback, respectively. This is typically used to protect
356  * the extra arguments for the duration of the callback. See
357  * g_object_watch_closure() for an example of marshal guards.
358  */
359 void
g_closure_add_marshal_guards(GClosure * closure,gpointer pre_marshal_data,GClosureNotify pre_marshal_notify,gpointer post_marshal_data,GClosureNotify post_marshal_notify)360 g_closure_add_marshal_guards (GClosure      *closure,
361 			      gpointer       pre_marshal_data,
362 			      GClosureNotify pre_marshal_notify,
363 			      gpointer       post_marshal_data,
364 			      GClosureNotify post_marshal_notify)
365 {
366   guint i;
367 
368   g_return_if_fail (closure != NULL);
369   g_return_if_fail (pre_marshal_notify != NULL);
370   g_return_if_fail (post_marshal_notify != NULL);
371   g_return_if_fail (closure->is_invalid == FALSE);
372   g_return_if_fail (closure->in_marshal == FALSE);
373   g_return_if_fail (closure->n_guards < CLOSURE_MAX_N_GUARDS);
374 
375   closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 2);
376   if (closure->n_inotifiers)
377     closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
378 			closure->n_fnotifiers +
379 			closure->n_inotifiers + 1)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
380 									  closure->n_fnotifiers + 0)];
381   if (closure->n_inotifiers > 1)
382     closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
383 			closure->n_fnotifiers +
384 			closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
385 								      closure->n_fnotifiers + 1)];
386   if (closure->n_fnotifiers)
387     closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
388 			closure->n_fnotifiers + 1)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 0];
389   if (closure->n_fnotifiers > 1)
390     closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
391 			closure->n_fnotifiers)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 1];
392   if (closure->n_guards)
393     closure->notifiers[(closure->meta_marshal +
394 			closure->n_guards +
395 			closure->n_guards + 1)] = closure->notifiers[closure->meta_marshal + closure->n_guards];
396   i = closure->n_guards;
397   closure->notifiers[closure->meta_marshal + i].data = pre_marshal_data;
398   closure->notifiers[closure->meta_marshal + i].notify = pre_marshal_notify;
399   closure->notifiers[closure->meta_marshal + i + 1].data = post_marshal_data;
400   closure->notifiers[closure->meta_marshal + i + 1].notify = post_marshal_notify;
401   INC (closure, n_guards);
402 }
403 
404 /**
405  * g_closure_add_finalize_notifier:
406  * @closure: a #GClosure
407  * @notify_data: data to pass to @notify_func
408  * @notify_func: the callback function to register
409  *
410  * Registers a finalization notifier which will be called when the
411  * reference count of @closure goes down to 0. Multiple finalization
412  * notifiers on a single closure are invoked in unspecified order. If
413  * a single call to g_closure_unref() results in the closure being
414  * both invalidated and finalized, then the invalidate notifiers will
415  * be run before the finalize notifiers.
416  */
417 void
g_closure_add_finalize_notifier(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)418 g_closure_add_finalize_notifier (GClosure      *closure,
419 				 gpointer       notify_data,
420 				 GClosureNotify notify_func)
421 {
422   guint i;
423 
424   g_return_if_fail (closure != NULL);
425   g_return_if_fail (notify_func != NULL);
426   g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS);
427 
428   closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
429   if (closure->n_inotifiers)
430     closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
431 			closure->n_fnotifiers +
432 			closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
433 								      closure->n_fnotifiers + 0)];
434   i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers;
435   closure->notifiers[i].data = notify_data;
436   closure->notifiers[i].notify = notify_func;
437   INC (closure, n_fnotifiers);
438 }
439 
440 /**
441  * g_closure_add_invalidate_notifier:
442  * @closure: a #GClosure
443  * @notify_data: data to pass to @notify_func
444  * @notify_func: the callback function to register
445  *
446  * Registers an invalidation notifier which will be called when the
447  * @closure is invalidated with g_closure_invalidate(). Invalidation
448  * notifiers are invoked before finalization notifiers, in an
449  * unspecified order.
450  */
451 void
g_closure_add_invalidate_notifier(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)452 g_closure_add_invalidate_notifier (GClosure      *closure,
453 				   gpointer       notify_data,
454 				   GClosureNotify notify_func)
455 {
456   guint i;
457 
458   g_return_if_fail (closure != NULL);
459   g_return_if_fail (notify_func != NULL);
460   g_return_if_fail (closure->is_invalid == FALSE);
461   g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS);
462 
463   closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
464   i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers;
465   closure->notifiers[i].data = notify_data;
466   closure->notifiers[i].notify = notify_func;
467   INC (closure, n_inotifiers);
468 }
469 
470 static inline gboolean
closure_try_remove_inotify(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)471 closure_try_remove_inotify (GClosure       *closure,
472 			    gpointer       notify_data,
473 			    GClosureNotify notify_func)
474 {
475   GClosureNotifyData *ndata, *nlast;
476 
477   nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1;
478   for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++)
479     if (ndata->notify == notify_func && ndata->data == notify_data)
480       {
481 	DEC (closure, n_inotifiers);
482 	if (ndata < nlast)
483 	  *ndata = *nlast;
484 
485 	return TRUE;
486       }
487   return FALSE;
488 }
489 
490 static inline gboolean
closure_try_remove_fnotify(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)491 closure_try_remove_fnotify (GClosure       *closure,
492 			    gpointer       notify_data,
493 			    GClosureNotify notify_func)
494 {
495   GClosureNotifyData *ndata, *nlast;
496 
497   nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - closure->n_inotifiers - 1;
498   for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++)
499     if (ndata->notify == notify_func && ndata->data == notify_data)
500       {
501 	DEC (closure, n_fnotifiers);
502 	if (ndata < nlast)
503 	  *ndata = *nlast;
504 	if (closure->n_inotifiers)
505 	  closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
506 			      closure->n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
507 									    closure->n_fnotifiers +
508 									    closure->n_inotifiers)];
509 	return TRUE;
510       }
511   return FALSE;
512 }
513 
514 /**
515  * g_closure_ref:
516  * @closure: #GClosure to increment the reference count on
517  *
518  * Increments the reference count on a closure to force it staying
519  * alive while the caller holds a pointer to it.
520  *
521  * Returns: The @closure passed in, for convenience
522  */
523 GClosure*
g_closure_ref(GClosure * closure)524 g_closure_ref (GClosure *closure)
525 {
526   guint new_ref_count;
527   g_return_val_if_fail (closure != NULL, NULL);
528   g_return_val_if_fail (closure->ref_count > 0, NULL);
529   g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
530 
531   INC_ASSIGN (closure, ref_count, &new_ref_count);
532   g_return_val_if_fail (new_ref_count > 1, NULL);
533 
534   return closure;
535 }
536 
537 /**
538  * g_closure_invalidate:
539  * @closure: GClosure to invalidate
540  *
541  * Sets a flag on the closure to indicate that its calling
542  * environment has become invalid, and thus causes any future
543  * invocations of g_closure_invoke() on this @closure to be
544  * ignored. Also, invalidation notifiers installed on the closure will
545  * be called at this point. Note that unless you are holding a
546  * reference to the closure yourself, the invalidation notifiers may
547  * unref the closure and cause it to be destroyed, so if you need to
548  * access the closure after calling g_closure_invalidate(), make sure
549  * that you've previously called g_closure_ref().
550  *
551  * Note that g_closure_invalidate() will also be called when the
552  * reference count of a closure drops to zero (unless it has already
553  * been invalidated before).
554  */
555 void
g_closure_invalidate(GClosure * closure)556 g_closure_invalidate (GClosure *closure)
557 {
558   g_return_if_fail (closure != NULL);
559 
560   if (!closure->is_invalid)
561     {
562       gboolean was_invalid;
563       g_closure_ref (closure);           /* preserve floating flag */
564       SWAP (closure, is_invalid, TRUE, &was_invalid);
565       /* invalidate only once */
566       if (!was_invalid)
567         closure_invoke_notifiers (closure, INOTIFY);
568       g_closure_unref (closure);
569     }
570 }
571 
572 /**
573  * g_closure_unref:
574  * @closure: #GClosure to decrement the reference count on
575  *
576  * Decrements the reference count of a closure after it was previously
577  * incremented by the same caller. If no other callers are using the
578  * closure, then the closure will be destroyed and freed.
579  */
580 void
g_closure_unref(GClosure * closure)581 g_closure_unref (GClosure *closure)
582 {
583   guint new_ref_count;
584 
585   g_return_if_fail (closure != NULL);
586   g_return_if_fail (closure->ref_count > 0);
587 
588   if (closure->ref_count == 1)	/* last unref, invalidate first */
589     g_closure_invalidate (closure);
590 
591   DEC_ASSIGN (closure, ref_count, &new_ref_count);
592 
593   if (new_ref_count == 0)
594     {
595       closure_invoke_notifiers (closure, FNOTIFY);
596       g_free (closure->notifiers);
597       g_free (closure);
598     }
599 }
600 
601 /**
602  * g_closure_sink:
603  * @closure: #GClosure to decrement the initial reference count on, if it's
604  *           still being held
605  *
606  * Takes over the initial ownership of a closure.  Each closure is
607  * initially created in a <firstterm>floating</firstterm> state, which
608  * means that the initial reference count is not owned by any caller.
609  * g_closure_sink() checks to see if the object is still floating, and
610  * if so, unsets the floating state and decreases the reference
611  * count. If the closure is not floating, g_closure_sink() does
612  * nothing. The reason for the existance of the floating state is to
613  * prevent cumbersome code sequences like:
614  * |[
615  * closure = g_cclosure_new (cb_func, cb_data);
616  * g_source_set_closure (source, closure);
617  * g_closure_unref (closure); // XXX GObject doesn't really need this
618  * ]|
619  * Because g_source_set_closure() (and similar functions) take ownership of the
620  * initial reference count, if it is unowned, we instead can write:
621  * |[
622  * g_source_set_closure (source, g_cclosure_new (cb_func, cb_data));
623  * ]|
624  *
625  * Generally, this function is used together with g_closure_ref(). Ane example
626  * of storing a closure for later notification looks like:
627  * |[
628  * static GClosure *notify_closure = NULL;
629  * void
630  * foo_notify_set_closure (GClosure *closure)
631  * {
632  *   if (notify_closure)
633  *     g_closure_unref (notify_closure);
634  *   notify_closure = closure;
635  *   if (notify_closure)
636  *     {
637  *       g_closure_ref (notify_closure);
638  *       g_closure_sink (notify_closure);
639  *     }
640  * }
641  * ]|
642  *
643  * Because g_closure_sink() may decrement the reference count of a closure
644  * (if it hasn't been called on @closure yet) just like g_closure_unref(),
645  * g_closure_ref() should be called prior to this function.
646  */
647 void
g_closure_sink(GClosure * closure)648 g_closure_sink (GClosure *closure)
649 {
650   g_return_if_fail (closure != NULL);
651   g_return_if_fail (closure->ref_count > 0);
652 
653   /* floating is basically a kludge to avoid creating closures
654    * with a ref_count of 0. so the intial ref_count a closure has
655    * is unowned. with invoking g_closure_sink() code may
656    * indicate that it takes over that intiial ref_count.
657    */
658   if (closure->floating)
659     {
660       gboolean was_floating;
661       SWAP (closure, floating, FALSE, &was_floating);
662       /* unref floating flag only once */
663       if (was_floating)
664         g_closure_unref (closure);
665     }
666 }
667 
668 /**
669  * g_closure_remove_invalidate_notifier:
670  * @closure: a #GClosure
671  * @notify_data: data which was passed to g_closure_add_invalidate_notifier()
672  *               when registering @notify_func
673  * @notify_func: the callback function to remove
674  *
675  * Removes an invalidation notifier.
676  *
677  * Notice that notifiers are automatically removed after they are run.
678  */
679 void
g_closure_remove_invalidate_notifier(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)680 g_closure_remove_invalidate_notifier (GClosure      *closure,
681 				      gpointer       notify_data,
682 				      GClosureNotify notify_func)
683 {
684   g_return_if_fail (closure != NULL);
685   g_return_if_fail (notify_func != NULL);
686 
687   if (closure->is_invalid && closure->in_inotify && /* account removal of notify_func() while it's called */
688       ((gpointer) closure->marshal) == ((gpointer) notify_func) &&
689       closure->data == notify_data)
690     closure->marshal = NULL;
691   else if (!closure_try_remove_inotify (closure, notify_data, notify_func))
692     g_warning (G_STRLOC ": unable to remove uninstalled invalidation notifier: %p (%p)",
693 	       notify_func, notify_data);
694 }
695 
696 /**
697  * g_closure_remove_finalize_notifier:
698  * @closure: a #GClosure
699  * @notify_data: data which was passed to g_closure_add_finalize_notifier()
700  *  when registering @notify_func
701  * @notify_func: the callback function to remove
702  *
703  * Removes a finalization notifier.
704  *
705  * Notice that notifiers are automatically removed after they are run.
706  */
707 void
g_closure_remove_finalize_notifier(GClosure * closure,gpointer notify_data,GClosureNotify notify_func)708 g_closure_remove_finalize_notifier (GClosure      *closure,
709 				    gpointer       notify_data,
710 				    GClosureNotify notify_func)
711 {
712   g_return_if_fail (closure != NULL);
713   g_return_if_fail (notify_func != NULL);
714 
715   if (closure->is_invalid && !closure->in_inotify && /* account removal of notify_func() while it's called */
716       ((gpointer) closure->marshal) == ((gpointer) notify_func) &&
717       closure->data == notify_data)
718     closure->marshal = NULL;
719   else if (!closure_try_remove_fnotify (closure, notify_data, notify_func))
720     g_warning (G_STRLOC ": unable to remove uninstalled finalization notifier: %p (%p)",
721                notify_func, notify_data);
722 }
723 
724 /**
725  * g_closure_invoke:
726  * @closure: a #GClosure
727  * @return_value: a #GValue to store the return value. May be %NULL if the
728  *                callback of @closure doesn't return a value.
729  * @n_param_values: the length of the @param_values array
730  * @param_values: an array of #GValue<!-- -->s holding the arguments on
731  *                which to invoke the callback of @closure
732  * @invocation_hint: a context-dependent invocation hint
733  *
734  * Invokes the closure, i.e. executes the callback represented by the @closure.
735  */
736 void
g_closure_invoke(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint)737 g_closure_invoke (GClosure       *closure,
738 		  GValue /*out*/ *return_value,
739 		  guint           n_param_values,
740 		  const GValue   *param_values,
741 		  gpointer        invocation_hint)
742 {
743   g_return_if_fail (closure != NULL);
744 
745   g_closure_ref (closure);      /* preserve floating flag */
746   if (!closure->is_invalid)
747     {
748       GClosureMarshal marshal;
749       gpointer marshal_data;
750       gboolean in_marshal = closure->in_marshal;
751 
752       g_return_if_fail (closure->marshal || closure->meta_marshal);
753 
754       SET (closure, in_marshal, TRUE);
755       if (closure->meta_marshal)
756 	{
757 	  marshal_data = closure->notifiers[0].data;
758 	  marshal = (GClosureMarshal) closure->notifiers[0].notify;
759 	}
760       else
761 	{
762 	  marshal_data = NULL;
763 	  marshal = closure->marshal;
764 	}
765       if (!in_marshal)
766 	closure_invoke_notifiers (closure, PRE_NOTIFY);
767       marshal (closure,
768 	       return_value,
769 	       n_param_values, param_values,
770 	       invocation_hint,
771 	       marshal_data);
772       if (!in_marshal)
773 	closure_invoke_notifiers (closure, POST_NOTIFY);
774       SET (closure, in_marshal, in_marshal);
775     }
776   g_closure_unref (closure);
777 }
778 
779 /**
780  * g_closure_set_marshal:
781  * @closure: a #GClosure
782  * @marshal: a #GClosureMarshal function
783  *
784  * Sets the marshaller of @closure. The <literal>marshal_data</literal>
785  * of @marshal provides a way for a meta marshaller to provide additional
786  * information to the marshaller. (See g_closure_set_meta_marshal().) For
787  * GObject's C predefined marshallers (the g_cclosure_marshal_*()
788  * functions), what it provides is a callback function to use instead of
789  * @closure->callback.
790  */
791 void
g_closure_set_marshal(GClosure * closure,GClosureMarshal marshal)792 g_closure_set_marshal (GClosure       *closure,
793 		       GClosureMarshal marshal)
794 {
795   g_return_if_fail (closure != NULL);
796   g_return_if_fail (marshal != NULL);
797 
798   if (closure->marshal && closure->marshal != marshal)
799     g_warning ("attempt to override closure->marshal (%p) with new marshal (%p)",
800 	       closure->marshal, marshal);
801   else
802     closure->marshal = marshal;
803 }
804 
805 /**
806  * g_cclosure_new:
807  * @callback_func: the function to invoke
808  * @user_data: user data to pass to @callback_func
809  * @destroy_data: destroy notify to be called when @user_data is no longer used
810  *
811  * Creates a new closure which invokes @callback_func with @user_data as
812  * the last parameter.
813  *
814  * Returns: a new #GCClosure
815  */
816 GClosure*
g_cclosure_new(GCallback callback_func,gpointer user_data,GClosureNotify destroy_data)817 g_cclosure_new (GCallback      callback_func,
818 		gpointer       user_data,
819 		GClosureNotify destroy_data)
820 {
821   GClosure *closure;
822 
823   g_return_val_if_fail (callback_func != NULL, NULL);
824 
825   closure = g_closure_new_simple (sizeof (GCClosure), user_data);
826   if (destroy_data)
827     g_closure_add_finalize_notifier (closure, user_data, destroy_data);
828   ((GCClosure*) closure)->callback = (gpointer) callback_func;
829 
830   return closure;
831 }
832 
833 /**
834  * g_cclosure_new_swap:
835  * @callback_func: the function to invoke
836  * @user_data: user data to pass to @callback_func
837  * @destroy_data: destroy notify to be called when @user_data is no longer used
838  *
839  * Creates a new closure which invokes @callback_func with @user_data as
840  * the first parameter.
841  *
842  * Returns: a new #GCClosure
843  */
844 GClosure*
g_cclosure_new_swap(GCallback callback_func,gpointer user_data,GClosureNotify destroy_data)845 g_cclosure_new_swap (GCallback      callback_func,
846 		     gpointer       user_data,
847 		     GClosureNotify destroy_data)
848 {
849   GClosure *closure;
850 
851   g_return_val_if_fail (callback_func != NULL, NULL);
852 
853   closure = g_closure_new_simple (sizeof (GCClosure), user_data);
854   if (destroy_data)
855     g_closure_add_finalize_notifier (closure, user_data, destroy_data);
856   ((GCClosure*) closure)->callback = (gpointer) callback_func;
857   SET (closure, derivative_flag, TRUE);
858 
859   return closure;
860 }
861 
862 static void
g_type_class_meta_marshal(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)863 g_type_class_meta_marshal (GClosure       *closure,
864 			   GValue /*out*/ *return_value,
865 			   guint           n_param_values,
866 			   const GValue   *param_values,
867 			   gpointer        invocation_hint,
868 			   gpointer        marshal_data)
869 {
870   GTypeClass *class;
871   gpointer callback;
872   /* GType itype = (GType) closure->data; */
873   guint offset = GPOINTER_TO_UINT (marshal_data);
874 
875   class = G_TYPE_INSTANCE_GET_CLASS (g_value_peek_pointer (param_values + 0), itype, GTypeClass);
876   callback = G_STRUCT_MEMBER (gpointer, class, offset);
877   if (callback)
878     closure->marshal (closure,
879 		      return_value,
880 		      n_param_values, param_values,
881 		      invocation_hint,
882 		      callback);
883 }
884 
885 static void
g_type_iface_meta_marshal(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)886 g_type_iface_meta_marshal (GClosure       *closure,
887 			   GValue /*out*/ *return_value,
888 			   guint           n_param_values,
889 			   const GValue   *param_values,
890 			   gpointer        invocation_hint,
891 			   gpointer        marshal_data)
892 {
893   GTypeClass *class;
894   gpointer callback;
895   GType itype = (GType) closure->data;
896   guint offset = GPOINTER_TO_UINT (marshal_data);
897 
898   class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_peek_pointer (param_values + 0), itype, GTypeClass);
899   callback = G_STRUCT_MEMBER (gpointer, class, offset);
900   if (callback)
901     closure->marshal (closure,
902 		      return_value,
903 		      n_param_values, param_values,
904 		      invocation_hint,
905 		      callback);
906 }
907 
908 /**
909  * g_signal_type_cclosure_new:
910  * @itype: the #GType identifier of an interface or classed type
911  * @struct_offset: the offset of the member function of @itype's class
912  *  structure which is to be invoked by the new closure
913  *
914  * Creates a new closure which invokes the function found at the offset
915  * @struct_offset in the class structure of the interface or classed type
916  * identified by @itype.
917  *
918  * Returns: a new #GCClosure
919  */
920 GClosure*
g_signal_type_cclosure_new(GType itype,guint struct_offset)921 g_signal_type_cclosure_new (GType    itype,
922 			    guint    struct_offset)
923 {
924   GClosure *closure;
925 
926   g_return_val_if_fail (G_TYPE_IS_CLASSED (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
927   g_return_val_if_fail (struct_offset >= sizeof (GTypeClass), NULL);
928 
929   closure = g_closure_new_simple (sizeof (GClosure), (gpointer) itype);
930   if (G_TYPE_IS_INTERFACE (itype))
931     g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_iface_meta_marshal);
932   else
933     g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_class_meta_marshal);
934 
935   return closure;
936 }
937 
938 
939 /**
940  * g_cclosure_marshal_VOID__VOID:
941  * @closure: the #GClosure to which the marshaller belongs
942  * @return_value: ignored
943  * @n_param_values: 1
944  * @param_values: a #GValue array holding only the instance
945  * @invocation_hint: the invocation hint given as the last argument
946  *  to g_closure_invoke()
947  * @marshal_data: additional data specified when registering the marshaller
948  *
949  * A marshaller for a #GCClosure with a callback of type
950  * <literal>void (*callback) (gpointer instance, gpointer user_data)</literal>.
951  */
952 
953 /**
954  * g_cclosure_marshal_VOID__BOOLEAN:
955  * @closure: the #GClosure to which the marshaller belongs
956  * @return_value: ignored
957  * @n_param_values: 2
958  * @param_values: a #GValue array holding the instance and the #gboolean parameter
959  * @invocation_hint: the invocation hint given as the last argument
960  *  to g_closure_invoke()
961  * @marshal_data: additional data specified when registering the marshaller
962  *
963  * A marshaller for a #GCClosure with a callback of type
964  * <literal>void (*callback) (gpointer instance, gboolean arg1, gpointer user_data)</literal>.
965  */
966 
967 /**
968  * g_cclosure_marshal_VOID__CHAR:
969  * @closure: the #GClosure to which the marshaller belongs
970  * @return_value: ignored
971  * @n_param_values: 2
972  * @param_values: a #GValue array holding the instance and the #gchar parameter
973  * @invocation_hint: the invocation hint given as the last argument
974  *  to g_closure_invoke()
975  * @marshal_data: additional data specified when registering the marshaller
976  *
977  * A marshaller for a #GCClosure with a callback of type
978  * <literal>void (*callback) (gpointer instance, gchar arg1, gpointer user_data)</literal>.
979  */
980 
981 /**
982  * g_cclosure_marshal_VOID__UCHAR:
983  * @closure: the #GClosure to which the marshaller belongs
984  * @return_value: ignored
985  * @n_param_values: 2
986  * @param_values: a #GValue array holding the instance and the #guchar parameter
987  * @invocation_hint: the invocation hint given as the last argument
988  *  to g_closure_invoke()
989  * @marshal_data: additional data specified when registering the marshaller
990  *
991  * A marshaller for a #GCClosure with a callback of type
992  * <literal>void (*callback) (gpointer instance, guchar arg1, gpointer user_data)</literal>.
993  */
994 
995 /**
996  * g_cclosure_marshal_VOID__INT:
997  * @closure: the #GClosure to which the marshaller belongs
998  * @return_value: ignored
999  * @n_param_values: 2
1000  * @param_values: a #GValue array holding the instance and the #gint parameter
1001  * @invocation_hint: the invocation hint given as the last argument
1002  *  to g_closure_invoke()
1003  * @marshal_data: additional data specified when registering the marshaller
1004  *
1005  * A marshaller for a #GCClosure with a callback of type
1006  * <literal>void (*callback) (gpointer instance, gint arg1, gpointer user_data)</literal>.
1007  */
1008 
1009 /**
1010  * g_cclosure_marshal_VOID__UINT:
1011  * @closure: the #GClosure to which the marshaller belongs
1012  * @return_value: ignored
1013  * @n_param_values: 2
1014  * @param_values: a #GValue array holding the instance and the #guint parameter
1015  * @invocation_hint: the invocation hint given as the last argument
1016  *  to g_closure_invoke()
1017  * @marshal_data: additional data specified when registering the marshaller
1018  *
1019  * A marshaller for a #GCClosure with a callback of type
1020  * <literal>void (*callback) (gpointer instance, guint arg1, gpointer user_data)</literal>.
1021  */
1022 
1023 /**
1024  * g_cclosure_marshal_VOID__LONG:
1025  * @closure: the #GClosure to which the marshaller belongs
1026  * @return_value: ignored
1027  * @n_param_values: 2
1028  * @param_values: a #GValue array holding the instance and the #glong parameter
1029  * @invocation_hint: the invocation hint given as the last argument
1030  *  to g_closure_invoke()
1031  * @marshal_data: additional data specified when registering the marshaller
1032  *
1033  * A marshaller for a #GCClosure with a callback of type
1034  * <literal>void (*callback) (gpointer instance, glong arg1, gpointer user_data)</literal>.
1035  */
1036 
1037 /**
1038  * g_cclosure_marshal_VOID__ULONG:
1039  * @closure: the #GClosure to which the marshaller belongs
1040  * @return_value: ignored
1041  * @n_param_values: 2
1042  * @param_values: a #GValue array holding the instance and the #gulong parameter
1043  * @invocation_hint: the invocation hint given as the last argument
1044  *  to g_closure_invoke()
1045  * @marshal_data: additional data specified when registering the marshaller
1046  *
1047  * A marshaller for a #GCClosure with a callback of type
1048  * <literal>void (*callback) (gpointer instance, gulong arg1, gpointer user_data)</literal>.
1049  */
1050 
1051 /**
1052  * g_cclosure_marshal_VOID__ENUM:
1053  * @closure: the #GClosure to which the marshaller belongs
1054  * @return_value: ignored
1055  * @n_param_values: 2
1056  * @param_values: a #GValue array holding the instance and the enumeration parameter
1057  * @invocation_hint: the invocation hint given as the last argument
1058  *  to g_closure_invoke()
1059  * @marshal_data: additional data specified when registering the marshaller
1060  *
1061  * A marshaller for a #GCClosure with a callback of type
1062  * <literal>void (*callback) (gpointer instance, gint arg1, gpointer user_data)</literal> where the #gint parameter denotes an enumeration type..
1063  */
1064 
1065 /**
1066  * g_cclosure_marshal_VOID__FLAGS:
1067  * @closure: the #GClosure to which the marshaller belongs
1068  * @return_value: ignored
1069  * @n_param_values: 2
1070  * @param_values: a #GValue array holding the instance and the flags parameter
1071  * @invocation_hint: the invocation hint given as the last argument
1072  *  to g_closure_invoke()
1073  * @marshal_data: additional data specified when registering the marshaller
1074  *
1075  * A marshaller for a #GCClosure with a callback of type
1076  * <literal>void (*callback) (gpointer instance, gint arg1, gpointer user_data)</literal> where the #gint parameter denotes a flags type.
1077  */
1078 
1079 /**
1080  * g_cclosure_marshal_VOID__FLOAT:
1081  * @closure: the #GClosure to which the marshaller belongs
1082  * @return_value: ignored
1083  * @n_param_values: 2
1084  * @param_values: a #GValue array holding the instance and the #gfloat parameter
1085  * @invocation_hint: the invocation hint given as the last argument
1086  *  to g_closure_invoke()
1087  * @marshal_data: additional data specified when registering the marshaller
1088  *
1089  * A marshaller for a #GCClosure with a callback of type
1090  * <literal>void (*callback) (gpointer instance, gfloat arg1, gpointer user_data)</literal>.
1091  */
1092 
1093 /**
1094  * g_cclosure_marshal_VOID__DOUBLE:
1095  * @closure: the #GClosure to which the marshaller belongs
1096  * @return_value: ignored
1097  * @n_param_values: 2
1098  * @param_values: a #GValue array holding the instance and the #gdouble parameter
1099  * @invocation_hint: the invocation hint given as the last argument
1100  *  to g_closure_invoke()
1101  * @marshal_data: additional data specified when registering the marshaller
1102  *
1103  * A marshaller for a #GCClosure with a callback of type
1104  * <literal>void (*callback) (gpointer instance, gdouble arg1, gpointer user_data)</literal>.
1105  */
1106 
1107 /**
1108  * g_cclosure_marshal_VOID__STRING:
1109  * @closure: the #GClosure to which the marshaller belongs
1110  * @return_value: ignored
1111  * @n_param_values: 2
1112  * @param_values: a #GValue array holding the instance and the #gchar* parameter
1113  * @invocation_hint: the invocation hint given as the last argument
1114  *  to g_closure_invoke()
1115  * @marshal_data: additional data specified when registering the marshaller
1116  *
1117  * A marshaller for a #GCClosure with a callback of type
1118  * <literal>void (*callback) (gpointer instance, const gchar *arg1, gpointer user_data)</literal>.
1119  */
1120 
1121 /**
1122  * g_cclosure_marshal_VOID__PARAM:
1123  * @closure: the #GClosure to which the marshaller belongs
1124  * @return_value: ignored
1125  * @n_param_values: 2
1126  * @param_values: a #GValue array holding the instance and the #GParamSpec* parameter
1127  * @invocation_hint: the invocation hint given as the last argument
1128  *  to g_closure_invoke()
1129  * @marshal_data: additional data specified when registering the marshaller
1130  *
1131  * A marshaller for a #GCClosure with a callback of type
1132  * <literal>void (*callback) (gpointer instance, GParamSpec *arg1, gpointer user_data)</literal>.
1133  */
1134 
1135 /**
1136  * g_cclosure_marshal_VOID__BOXED:
1137  * @closure: the #GClosure to which the marshaller belongs
1138  * @return_value: ignored
1139  * @n_param_values: 2
1140  * @param_values: a #GValue array holding the instance and the #GBoxed* parameter
1141  * @invocation_hint: the invocation hint given as the last argument
1142  *  to g_closure_invoke()
1143  * @marshal_data: additional data specified when registering the marshaller
1144  *
1145  * A marshaller for a #GCClosure with a callback of type
1146  * <literal>void (*callback) (gpointer instance, GBoxed *arg1, gpointer user_data)</literal>.
1147  */
1148 
1149 /**
1150  * g_cclosure_marshal_VOID__POINTER:
1151  * @closure: the #GClosure to which the marshaller belongs
1152  * @return_value: ignored
1153  * @n_param_values: 2
1154  * @param_values: a #GValue array holding the instance and the #gpointer parameter
1155  * @invocation_hint: the invocation hint given as the last argument
1156  *  to g_closure_invoke()
1157  * @marshal_data: additional data specified when registering the marshaller
1158  *
1159  * A marshaller for a #GCClosure with a callback of type
1160  * <literal>void (*callback) (gpointer instance, gpointer arg1, gpointer user_data)</literal>.
1161  */
1162 
1163 /**
1164  * g_cclosure_marshal_VOID__OBJECT:
1165  * @closure: the #GClosure to which the marshaller belongs
1166  * @return_value: ignored
1167  * @n_param_values: 2
1168  * @param_values: a #GValue array holding the instance and the #GObject* parameter
1169  * @invocation_hint: the invocation hint given as the last argument
1170  *  to g_closure_invoke()
1171  * @marshal_data: additional data specified when registering the marshaller
1172  *
1173  * A marshaller for a #GCClosure with a callback of type
1174  * <literal>void (*callback) (gpointer instance, GOBject *arg1, gpointer user_data)</literal>.
1175  */
1176 
1177 /**
1178  * g_cclosure_marshal_VOID__UINT_POINTER:
1179  * @closure: the #GClosure to which the marshaller belongs
1180  * @return_value: ignored
1181  * @n_param_values: 3
1182  * @param_values: a #GValue array holding instance, arg1 and arg2
1183  * @invocation_hint: the invocation hint given as the last argument
1184  *  to g_closure_invoke()
1185  * @marshal_data: additional data specified when registering the marshaller
1186  *
1187  * A marshaller for a #GCClosure with a callback of type
1188  * <literal>void (*callback) (gpointer instance, guint arg1, gpointer arg2, gpointer user_data)</literal>.
1189  */
1190 
1191 /**
1192  * g_cclosure_marshal_BOOLEAN__FLAGS:
1193  * @closure: the #GClosure to which the marshaller belongs
1194  * @return_value: a #GValue which can store the returned #gboolean
1195  * @n_param_values: 2
1196  * @param_values: a #GValue array holding instance and arg1
1197  * @invocation_hint: the invocation hint given as the last argument
1198  *  to g_closure_invoke()
1199  * @marshal_data: additional data specified when registering the marshaller
1200  *
1201  * A marshaller for a #GCClosure with a callback of type
1202  * <literal>gboolean (*callback) (gpointer instance, gint arg1, gpointer user_data)</literal> where the #gint parameter
1203  * denotes a flags type.
1204  */
1205 
1206 /**
1207  * g_cclosure_marshal_BOOL__FLAGS:
1208  *
1209  * Another name for g_cclosure_marshal_BOOLEAN__FLAGS().
1210  */
1211 /**
1212  * g_cclosure_marshal_STRING__OBJECT_POINTER:
1213  * @closure: the #GClosure to which the marshaller belongs
1214  * @return_value: a #GValue, which can store the returned string
1215  * @n_param_values: 3
1216  * @param_values: a #GValue array holding instance, arg1 and arg2
1217  * @invocation_hint: the invocation hint given as the last argument
1218  *  to g_closure_invoke()
1219  * @marshal_data: additional data specified when registering the marshaller
1220  *
1221  * A marshaller for a #GCClosure with a callback of type
1222  * <literal>gchar* (*callback) (gpointer instance, GObject *arg1, gpointer arg2, gpointer user_data)</literal>.
1223  */
1224 
1225 #define __G_CLOSURE_C__
1226 #include "gobjectaliasdef.c"
1227