gconvert: add note to avoid transliteration
[glib.git] / gobject / gclosure.c
blob02e9d8685c2d9e9d52cc8ef00d202d687b0e6fa8
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2000-2001 Red Hat, Inc.
3 * Copyright (C) 2005 Imendio AB
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.
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.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 * MT safe with regards to reference counting.
23 #include "config.h"
25 #include <string.h>
27 #include <ffi.h>
29 #include "gclosure.h"
30 #include "gboxed.h"
31 #include "gobject.h"
32 #include "genums.h"
33 #include "gvalue.h"
34 #include "gvaluetypes.h"
35 #include "gtype-private.h"
38 /**
39 * SECTION:gclosure
40 * @short_description: Functions as first-class objects
41 * @title: Closures
43 * A #GClosure represents a callback supplied by the programmer. It
44 * will generally comprise a function of some kind and a marshaller
45 * used to call it. It is the reponsibility of the marshaller to
46 * convert the arguments for the invocation from #GValues into
47 * a suitable form, perform the callback on the converted arguments,
48 * and transform the return value back into a #GValue.
50 * In the case of C programs, a closure usually just holds a pointer
51 * to a function and maybe a data argument, and the marshaller
52 * converts between #GValue and native C types. The GObject
53 * library provides the #GCClosure type for this purpose. Bindings for
54 * other languages need marshallers which convert between #GValue<!--
55 * -->s and suitable representations in the runtime of the language in
56 * order to use functions written in that languages as callbacks.
58 * Within GObject, closures play an important role in the
59 * implementation of signals. When a signal is registered, the
60 * @c_marshaller argument to g_signal_new() specifies the default C
61 * marshaller for any closure which is connected to this
62 * signal. GObject provides a number of C marshallers for this
63 * purpose, see the g_cclosure_marshal_*() functions. Additional C
64 * marshallers can be generated with the [glib-genmarshal][glib-genmarshal]
65 * utility. Closures can be explicitly connected to signals with
66 * g_signal_connect_closure(), but it usually more convenient to let
67 * GObject create a closure automatically by using one of the
68 * g_signal_connect_*() functions which take a callback function/user
69 * data pair.
71 * Using closures has a number of important advantages over a simple
72 * callback function/data pointer combination:
74 * - Closures allow the callee to get the types of the callback parameters,
75 * which means that language bindings don't have to write individual glue
76 * for each callback type.
78 * - The reference counting of #GClosure makes it easy to handle reentrancy
79 * right; if a callback is removed while it is being invoked, the closure
80 * and its parameters won't be freed until the invocation finishes.
82 * - g_closure_invalidate() and invalidation notifiers allow callbacks to be
83 * automatically removed when the objects they point to go away.
86 #define CLOSURE_MAX_REF_COUNT ((1 << 15) - 1)
87 #define CLOSURE_MAX_N_GUARDS ((1 << 1) - 1)
88 #define CLOSURE_MAX_N_FNOTIFIERS ((1 << 2) - 1)
89 #define CLOSURE_MAX_N_INOTIFIERS ((1 << 8) - 1)
90 #define CLOSURE_N_MFUNCS(cl) (((cl)->n_guards << 1L))
91 /* same as G_CLOSURE_N_NOTIFIERS() (keep in sync) */
92 #define CLOSURE_N_NOTIFIERS(cl) (CLOSURE_N_MFUNCS (cl) + \
93 (cl)->n_fnotifiers + \
94 (cl)->n_inotifiers)
96 typedef union {
97 GClosure closure;
98 volatile gint vint;
99 } ClosureInt;
101 #define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW) \
102 G_STMT_START { \
103 ClosureInt *cunion = (ClosureInt*) _closure; \
104 gint new_int, old_int, success; \
105 do \
107 ClosureInt tmp; \
108 tmp.vint = old_int = cunion->vint; \
109 _SET_OLD tmp.closure._field; \
110 tmp.closure._field _OP _value; \
111 _SET_NEW tmp.closure._field; \
112 new_int = tmp.vint; \
113 success = g_atomic_int_compare_and_exchange (&cunion->vint, old_int, new_int); \
115 while (!success && _must_set); \
116 } G_STMT_END
118 #define SWAP(_closure, _field, _value, _oldv) CHANGE_FIELD (_closure, _field, =, _value, TRUE, *(_oldv) =, (void) )
119 #define SET(_closure, _field, _value) CHANGE_FIELD (_closure, _field, =, _value, TRUE, (void), (void) )
120 #define INC(_closure, _field) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), (void) )
121 #define INC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, +=, 1, TRUE, (void), *(_newv) = )
122 #define DEC(_closure, _field) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), (void) )
123 #define DEC_ASSIGN(_closure, _field, _newv) CHANGE_FIELD (_closure, _field, -=, 1, TRUE, (void), *(_newv) = )
125 #if 0 /* for non-thread-safe closures */
126 #define SWAP(cl,f,v,o) (void) (*(o) = cl->f, cl->f = v)
127 #define SET(cl,f,v) (void) (cl->f = v)
128 #define INC(cl,f) (void) (cl->f += 1)
129 #define INC_ASSIGN(cl,f,n) (void) (cl->f += 1, *(n) = cl->f)
130 #define DEC(cl,f) (void) (cl->f -= 1)
131 #define DEC_ASSIGN(cl,f,n) (void) (cl->f -= 1, *(n) = cl->f)
132 #endif
134 enum {
135 FNOTIFY,
136 INOTIFY,
137 PRE_NOTIFY,
138 POST_NOTIFY
142 /* --- functions --- */
144 * g_closure_new_simple:
145 * @sizeof_closure: the size of the structure to allocate, must be at least
146 * `sizeof (GClosure)`
147 * @data: data to store in the @data field of the newly allocated #GClosure
149 * Allocates a struct of the given size and initializes the initial
150 * part as a #GClosure. This function is mainly useful when
151 * implementing new types of closures.
153 * |[<!-- language="C" -->
154 * typedef struct _MyClosure MyClosure;
155 * struct _MyClosure
157 * GClosure closure;
158 * // extra data goes here
159 * };
161 * static void
162 * my_closure_finalize (gpointer notify_data,
163 * GClosure *closure)
165 * MyClosure *my_closure = (MyClosure *)closure;
167 * // free extra data here
170 * MyClosure *my_closure_new (gpointer data)
172 * GClosure *closure;
173 * MyClosure *my_closure;
175 * closure = g_closure_new_simple (sizeof (MyClosure), data);
176 * my_closure = (MyClosure *) closure;
178 * // initialize extra data here
180 * g_closure_add_finalize_notifier (closure, notify_data,
181 * my_closure_finalize);
182 * return my_closure;
184 * ]|
186 * Returns: (transfer full): a newly allocated #GClosure
188 GClosure*
189 g_closure_new_simple (guint sizeof_closure,
190 gpointer data)
192 GRealClosure *real_closure;
193 GClosure *closure;
195 g_return_val_if_fail (sizeof_closure >= sizeof (GClosure), NULL);
196 sizeof_closure = sizeof_closure + sizeof (GRealClosure) - sizeof (GClosure);
198 real_closure = g_malloc0 (sizeof_closure);
199 closure = &real_closure->closure;
200 SET (closure, ref_count, 1);
201 SET (closure, floating, TRUE);
202 closure->data = data;
204 return closure;
207 static inline void
208 closure_invoke_notifiers (GClosure *closure,
209 guint notify_type)
211 /* notifier layout:
212 * n_guards n_guards n_fnotif. n_inotifiers
213 * ->[[pre_guards][post_guards][fnotifiers][inotifiers]]
215 * CLOSURE_N_MFUNCS(cl) = n_guards + n_guards;
216 * CLOSURE_N_NOTIFIERS(cl) = CLOSURE_N_MFUNCS(cl) + n_fnotifiers + n_inotifiers
218 * constrains/catches:
219 * - closure->notifiers may be reloacted during callback
220 * - closure->n_fnotifiers and closure->n_inotifiers may change during callback
221 * - i.e. callbacks can be removed/added during invocation
222 * - must prepare for callback removal during FNOTIFY and INOTIFY (done via ->marshal= & ->data=)
223 * - must distinguish (->marshal= & ->data=) for INOTIFY vs. FNOTIFY (via ->in_inotify)
224 * + closure->n_guards is const during PRE_NOTIFY & POST_NOTIFY
225 * + none of the callbacks can cause recursion
226 * + closure->n_inotifiers is const 0 during FNOTIFY
228 switch (notify_type)
230 GClosureNotifyData *ndata;
231 guint i, offs;
232 case FNOTIFY:
233 while (closure->n_fnotifiers)
235 guint n;
236 DEC_ASSIGN (closure, n_fnotifiers, &n);
238 ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n;
239 closure->marshal = (GClosureMarshal) ndata->notify;
240 closure->data = ndata->data;
241 ndata->notify (ndata->data, closure);
243 closure->marshal = NULL;
244 closure->data = NULL;
245 break;
246 case INOTIFY:
247 SET (closure, in_inotify, TRUE);
248 while (closure->n_inotifiers)
250 guint n;
251 DEC_ASSIGN (closure, n_inotifiers, &n);
253 ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n;
254 closure->marshal = (GClosureMarshal) ndata->notify;
255 closure->data = ndata->data;
256 ndata->notify (ndata->data, closure);
258 closure->marshal = NULL;
259 closure->data = NULL;
260 SET (closure, in_inotify, FALSE);
261 break;
262 case PRE_NOTIFY:
263 i = closure->n_guards;
264 offs = 0;
265 while (i--)
267 ndata = closure->notifiers + offs + i;
268 ndata->notify (ndata->data, closure);
270 break;
271 case POST_NOTIFY:
272 i = closure->n_guards;
273 offs = i;
274 while (i--)
276 ndata = closure->notifiers + offs + i;
277 ndata->notify (ndata->data, closure);
279 break;
283 static void
284 g_closure_set_meta_va_marshal (GClosure *closure,
285 GVaClosureMarshal va_meta_marshal)
287 GRealClosure *real_closure;
289 g_return_if_fail (closure != NULL);
290 g_return_if_fail (va_meta_marshal != NULL);
291 g_return_if_fail (closure->is_invalid == FALSE);
292 g_return_if_fail (closure->in_marshal == FALSE);
294 real_closure = G_REAL_CLOSURE (closure);
296 g_return_if_fail (real_closure->meta_marshal != NULL);
298 real_closure->va_meta_marshal = va_meta_marshal;
302 * g_closure_set_meta_marshal: (skip)
303 * @closure: a #GClosure
304 * @marshal_data: context-dependent data to pass to @meta_marshal
305 * @meta_marshal: a #GClosureMarshal function
307 * Sets the meta marshaller of @closure. A meta marshaller wraps
308 * @closure->marshal and modifies the way it is called in some
309 * fashion. The most common use of this facility is for C callbacks.
310 * The same marshallers (generated by [glib-genmarshal][glib-genmarshal]),
311 * are used everywhere, but the way that we get the callback function
312 * differs. In most cases we want to use @closure->callback, but in
313 * other cases we want to use some different technique to retrieve the
314 * callback function.
316 * For example, class closures for signals (see
317 * g_signal_type_cclosure_new()) retrieve the callback function from a
318 * fixed offset in the class structure. The meta marshaller retrieves
319 * the right callback and passes it to the marshaller as the
320 * @marshal_data argument.
322 void
323 g_closure_set_meta_marshal (GClosure *closure,
324 gpointer marshal_data,
325 GClosureMarshal meta_marshal)
327 GRealClosure *real_closure;
329 g_return_if_fail (closure != NULL);
330 g_return_if_fail (meta_marshal != NULL);
331 g_return_if_fail (closure->is_invalid == FALSE);
332 g_return_if_fail (closure->in_marshal == FALSE);
334 real_closure = G_REAL_CLOSURE (closure);
336 g_return_if_fail (real_closure->meta_marshal == NULL);
338 real_closure->meta_marshal = meta_marshal;
339 real_closure->meta_marshal_data = marshal_data;
343 * g_closure_add_marshal_guards: (skip)
344 * @closure: a #GClosure
345 * @pre_marshal_data: data to pass to @pre_marshal_notify
346 * @pre_marshal_notify: a function to call before the closure callback
347 * @post_marshal_data: data to pass to @post_marshal_notify
348 * @post_marshal_notify: a function to call after the closure callback
350 * Adds a pair of notifiers which get invoked before and after the
351 * closure callback, respectively. This is typically used to protect
352 * the extra arguments for the duration of the callback. See
353 * g_object_watch_closure() for an example of marshal guards.
355 void
356 g_closure_add_marshal_guards (GClosure *closure,
357 gpointer pre_marshal_data,
358 GClosureNotify pre_marshal_notify,
359 gpointer post_marshal_data,
360 GClosureNotify post_marshal_notify)
362 guint i;
364 g_return_if_fail (closure != NULL);
365 g_return_if_fail (pre_marshal_notify != NULL);
366 g_return_if_fail (post_marshal_notify != NULL);
367 g_return_if_fail (closure->is_invalid == FALSE);
368 g_return_if_fail (closure->in_marshal == FALSE);
369 g_return_if_fail (closure->n_guards < CLOSURE_MAX_N_GUARDS);
371 closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 2);
372 if (closure->n_inotifiers)
373 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
374 closure->n_fnotifiers +
375 closure->n_inotifiers + 1)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
376 closure->n_fnotifiers + 0)];
377 if (closure->n_inotifiers > 1)
378 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
379 closure->n_fnotifiers +
380 closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
381 closure->n_fnotifiers + 1)];
382 if (closure->n_fnotifiers)
383 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
384 closure->n_fnotifiers + 1)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 0];
385 if (closure->n_fnotifiers > 1)
386 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
387 closure->n_fnotifiers)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 1];
388 if (closure->n_guards)
389 closure->notifiers[(closure->n_guards +
390 closure->n_guards + 1)] = closure->notifiers[closure->n_guards];
391 i = closure->n_guards;
392 closure->notifiers[i].data = pre_marshal_data;
393 closure->notifiers[i].notify = pre_marshal_notify;
394 closure->notifiers[i + 1].data = post_marshal_data;
395 closure->notifiers[i + 1].notify = post_marshal_notify;
396 INC (closure, n_guards);
400 * g_closure_add_finalize_notifier: (skip)
401 * @closure: a #GClosure
402 * @notify_data: data to pass to @notify_func
403 * @notify_func: the callback function to register
405 * Registers a finalization notifier which will be called when the
406 * reference count of @closure goes down to 0. Multiple finalization
407 * notifiers on a single closure are invoked in unspecified order. If
408 * a single call to g_closure_unref() results in the closure being
409 * both invalidated and finalized, then the invalidate notifiers will
410 * be run before the finalize notifiers.
412 void
413 g_closure_add_finalize_notifier (GClosure *closure,
414 gpointer notify_data,
415 GClosureNotify notify_func)
417 guint i;
419 g_return_if_fail (closure != NULL);
420 g_return_if_fail (notify_func != NULL);
421 g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS);
423 closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
424 if (closure->n_inotifiers)
425 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
426 closure->n_fnotifiers +
427 closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
428 closure->n_fnotifiers + 0)];
429 i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers;
430 closure->notifiers[i].data = notify_data;
431 closure->notifiers[i].notify = notify_func;
432 INC (closure, n_fnotifiers);
436 * g_closure_add_invalidate_notifier: (skip)
437 * @closure: a #GClosure
438 * @notify_data: data to pass to @notify_func
439 * @notify_func: the callback function to register
441 * Registers an invalidation notifier which will be called when the
442 * @closure is invalidated with g_closure_invalidate(). Invalidation
443 * notifiers are invoked before finalization notifiers, in an
444 * unspecified order.
446 void
447 g_closure_add_invalidate_notifier (GClosure *closure,
448 gpointer notify_data,
449 GClosureNotify notify_func)
451 guint i;
453 g_return_if_fail (closure != NULL);
454 g_return_if_fail (notify_func != NULL);
455 g_return_if_fail (closure->is_invalid == FALSE);
456 g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS);
458 closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
459 i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers;
460 closure->notifiers[i].data = notify_data;
461 closure->notifiers[i].notify = notify_func;
462 INC (closure, n_inotifiers);
465 static inline gboolean
466 closure_try_remove_inotify (GClosure *closure,
467 gpointer notify_data,
468 GClosureNotify notify_func)
470 GClosureNotifyData *ndata, *nlast;
472 nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1;
473 for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++)
474 if (ndata->notify == notify_func && ndata->data == notify_data)
476 DEC (closure, n_inotifiers);
477 if (ndata < nlast)
478 *ndata = *nlast;
480 return TRUE;
482 return FALSE;
485 static inline gboolean
486 closure_try_remove_fnotify (GClosure *closure,
487 gpointer notify_data,
488 GClosureNotify notify_func)
490 GClosureNotifyData *ndata, *nlast;
492 nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - closure->n_inotifiers - 1;
493 for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++)
494 if (ndata->notify == notify_func && ndata->data == notify_data)
496 DEC (closure, n_fnotifiers);
497 if (ndata < nlast)
498 *ndata = *nlast;
499 if (closure->n_inotifiers)
500 closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
501 closure->n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
502 closure->n_fnotifiers +
503 closure->n_inotifiers)];
504 return TRUE;
506 return FALSE;
510 * g_closure_ref:
511 * @closure: #GClosure to increment the reference count on
513 * Increments the reference count on a closure to force it staying
514 * alive while the caller holds a pointer to it.
516 * Returns: (transfer none): The @closure passed in, for convenience
518 GClosure*
519 g_closure_ref (GClosure *closure)
521 guint new_ref_count;
522 g_return_val_if_fail (closure != NULL, NULL);
523 g_return_val_if_fail (closure->ref_count > 0, NULL);
524 g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
526 INC_ASSIGN (closure, ref_count, &new_ref_count);
527 g_return_val_if_fail (new_ref_count > 1, NULL);
529 return closure;
533 * g_closure_invalidate:
534 * @closure: GClosure to invalidate
536 * Sets a flag on the closure to indicate that its calling
537 * environment has become invalid, and thus causes any future
538 * invocations of g_closure_invoke() on this @closure to be
539 * ignored. Also, invalidation notifiers installed on the closure will
540 * be called at this point. Note that unless you are holding a
541 * reference to the closure yourself, the invalidation notifiers may
542 * unref the closure and cause it to be destroyed, so if you need to
543 * access the closure after calling g_closure_invalidate(), make sure
544 * that you've previously called g_closure_ref().
546 * Note that g_closure_invalidate() will also be called when the
547 * reference count of a closure drops to zero (unless it has already
548 * been invalidated before).
550 void
551 g_closure_invalidate (GClosure *closure)
553 g_return_if_fail (closure != NULL);
555 if (!closure->is_invalid)
557 gboolean was_invalid;
558 g_closure_ref (closure); /* preserve floating flag */
559 SWAP (closure, is_invalid, TRUE, &was_invalid);
560 /* invalidate only once */
561 if (!was_invalid)
562 closure_invoke_notifiers (closure, INOTIFY);
563 g_closure_unref (closure);
568 * g_closure_unref:
569 * @closure: #GClosure to decrement the reference count on
571 * Decrements the reference count of a closure after it was previously
572 * incremented by the same caller. If no other callers are using the
573 * closure, then the closure will be destroyed and freed.
575 void
576 g_closure_unref (GClosure *closure)
578 guint new_ref_count;
580 g_return_if_fail (closure != NULL);
581 g_return_if_fail (closure->ref_count > 0);
583 if (closure->ref_count == 1) /* last unref, invalidate first */
584 g_closure_invalidate (closure);
586 DEC_ASSIGN (closure, ref_count, &new_ref_count);
588 if (new_ref_count == 0)
590 closure_invoke_notifiers (closure, FNOTIFY);
591 g_free (closure->notifiers);
592 g_free (G_REAL_CLOSURE (closure));
597 * g_closure_sink:
598 * @closure: #GClosure to decrement the initial reference count on, if it's
599 * still being held
601 * Takes over the initial ownership of a closure. Each closure is
602 * initially created in a "floating" state, which means that the initial
603 * reference count is not owned by any caller. g_closure_sink() checks
604 * to see if the object is still floating, and if so, unsets the
605 * floating state and decreases the reference count. If the closure
606 * is not floating, g_closure_sink() does nothing. The reason for the
607 * existence of the floating state is to prevent cumbersome code
608 * sequences like:
609 * |[<!-- language="C" -->
610 * closure = g_cclosure_new (cb_func, cb_data);
611 * g_source_set_closure (source, closure);
612 * g_closure_unref (closure); // GObject doesn't really need this
613 * ]|
614 * Because g_source_set_closure() (and similar functions) take ownership of the
615 * initial reference count, if it is unowned, we instead can write:
616 * |[<!-- language="C" -->
617 * g_source_set_closure (source, g_cclosure_new (cb_func, cb_data));
618 * ]|
620 * Generally, this function is used together with g_closure_ref(). Ane example
621 * of storing a closure for later notification looks like:
622 * |[<!-- language="C" -->
623 * static GClosure *notify_closure = NULL;
624 * void
625 * foo_notify_set_closure (GClosure *closure)
627 * if (notify_closure)
628 * g_closure_unref (notify_closure);
629 * notify_closure = closure;
630 * if (notify_closure)
632 * g_closure_ref (notify_closure);
633 * g_closure_sink (notify_closure);
636 * ]|
638 * Because g_closure_sink() may decrement the reference count of a closure
639 * (if it hasn't been called on @closure yet) just like g_closure_unref(),
640 * g_closure_ref() should be called prior to this function.
642 void
643 g_closure_sink (GClosure *closure)
645 g_return_if_fail (closure != NULL);
646 g_return_if_fail (closure->ref_count > 0);
648 /* floating is basically a kludge to avoid creating closures
649 * with a ref_count of 0. so the initial ref_count a closure has
650 * is unowned. with invoking g_closure_sink() code may
651 * indicate that it takes over that intiial ref_count.
653 if (closure->floating)
655 gboolean was_floating;
656 SWAP (closure, floating, FALSE, &was_floating);
657 /* unref floating flag only once */
658 if (was_floating)
659 g_closure_unref (closure);
664 * g_closure_remove_invalidate_notifier: (skip)
665 * @closure: a #GClosure
666 * @notify_data: data which was passed to g_closure_add_invalidate_notifier()
667 * when registering @notify_func
668 * @notify_func: the callback function to remove
670 * Removes an invalidation notifier.
672 * Notice that notifiers are automatically removed after they are run.
674 void
675 g_closure_remove_invalidate_notifier (GClosure *closure,
676 gpointer notify_data,
677 GClosureNotify notify_func)
679 g_return_if_fail (closure != NULL);
680 g_return_if_fail (notify_func != NULL);
682 if (closure->is_invalid && closure->in_inotify && /* account removal of notify_func() while it's called */
683 ((gpointer) closure->marshal) == ((gpointer) notify_func) &&
684 closure->data == notify_data)
685 closure->marshal = NULL;
686 else if (!closure_try_remove_inotify (closure, notify_data, notify_func))
687 g_warning (G_STRLOC ": unable to remove uninstalled invalidation notifier: %p (%p)",
688 notify_func, notify_data);
692 * g_closure_remove_finalize_notifier: (skip)
693 * @closure: a #GClosure
694 * @notify_data: data which was passed to g_closure_add_finalize_notifier()
695 * when registering @notify_func
696 * @notify_func: the callback function to remove
698 * Removes a finalization notifier.
700 * Notice that notifiers are automatically removed after they are run.
702 void
703 g_closure_remove_finalize_notifier (GClosure *closure,
704 gpointer notify_data,
705 GClosureNotify notify_func)
707 g_return_if_fail (closure != NULL);
708 g_return_if_fail (notify_func != NULL);
710 if (closure->is_invalid && !closure->in_inotify && /* account removal of notify_func() while it's called */
711 ((gpointer) closure->marshal) == ((gpointer) notify_func) &&
712 closure->data == notify_data)
713 closure->marshal = NULL;
714 else if (!closure_try_remove_fnotify (closure, notify_data, notify_func))
715 g_warning (G_STRLOC ": unable to remove uninstalled finalization notifier: %p (%p)",
716 notify_func, notify_data);
720 * g_closure_invoke:
721 * @closure: a #GClosure
722 * @return_value: (allow-none): a #GValue to store the return
723 * value. May be %NULL if the callback of @closure
724 * doesn't return a value.
725 * @n_param_values: the length of the @param_values array
726 * @param_values: (array length=n_param_values): an array of
727 * #GValues holding the arguments on which to
728 * invoke the callback of @closure
729 * @invocation_hint: (allow-none): a context-dependent invocation hint
731 * Invokes the closure, i.e. executes the callback represented by the @closure.
733 void
734 g_closure_invoke (GClosure *closure,
735 GValue /*out*/ *return_value,
736 guint n_param_values,
737 const GValue *param_values,
738 gpointer invocation_hint)
740 GRealClosure *real_closure;
742 g_return_if_fail (closure != NULL);
744 real_closure = G_REAL_CLOSURE (closure);
746 g_closure_ref (closure); /* preserve floating flag */
747 if (!closure->is_invalid)
749 GClosureMarshal marshal;
750 gpointer marshal_data;
751 gboolean in_marshal = closure->in_marshal;
753 g_return_if_fail (closure->marshal || real_closure->meta_marshal);
755 SET (closure, in_marshal, TRUE);
756 if (real_closure->meta_marshal)
758 marshal_data = real_closure->meta_marshal_data;
759 marshal = real_closure->meta_marshal;
761 else
763 marshal_data = NULL;
764 marshal = closure->marshal;
766 if (!in_marshal)
767 closure_invoke_notifiers (closure, PRE_NOTIFY);
768 marshal (closure,
769 return_value,
770 n_param_values, param_values,
771 invocation_hint,
772 marshal_data);
773 if (!in_marshal)
774 closure_invoke_notifiers (closure, POST_NOTIFY);
775 SET (closure, in_marshal, in_marshal);
777 g_closure_unref (closure);
780 gboolean
781 _g_closure_supports_invoke_va (GClosure *closure)
783 GRealClosure *real_closure;
785 g_return_val_if_fail (closure != NULL, FALSE);
787 real_closure = G_REAL_CLOSURE (closure);
789 return
790 real_closure->va_marshal != NULL &&
791 (real_closure->meta_marshal == NULL ||
792 real_closure->va_meta_marshal != NULL);
795 void
796 _g_closure_invoke_va (GClosure *closure,
797 GValue /*out*/ *return_value,
798 gpointer instance,
799 va_list args,
800 int n_params,
801 GType *param_types)
803 GRealClosure *real_closure;
805 g_return_if_fail (closure != NULL);
807 real_closure = G_REAL_CLOSURE (closure);
809 g_closure_ref (closure); /* preserve floating flag */
810 if (!closure->is_invalid)
812 GVaClosureMarshal marshal;
813 gpointer marshal_data;
814 gboolean in_marshal = closure->in_marshal;
816 g_return_if_fail (closure->marshal || real_closure->meta_marshal);
818 SET (closure, in_marshal, TRUE);
819 if (real_closure->va_meta_marshal)
821 marshal_data = real_closure->meta_marshal_data;
822 marshal = real_closure->va_meta_marshal;
824 else
826 marshal_data = NULL;
827 marshal = real_closure->va_marshal;
829 if (!in_marshal)
830 closure_invoke_notifiers (closure, PRE_NOTIFY);
831 marshal (closure,
832 return_value,
833 instance, args,
834 marshal_data,
835 n_params, param_types);
836 if (!in_marshal)
837 closure_invoke_notifiers (closure, POST_NOTIFY);
838 SET (closure, in_marshal, in_marshal);
840 g_closure_unref (closure);
845 * g_closure_set_marshal: (skip)
846 * @closure: a #GClosure
847 * @marshal: a #GClosureMarshal function
849 * Sets the marshaller of @closure. The `marshal_data`
850 * of @marshal provides a way for a meta marshaller to provide additional
851 * information to the marshaller. (See g_closure_set_meta_marshal().) For
852 * GObject's C predefined marshallers (the g_cclosure_marshal_*()
853 * functions), what it provides is a callback function to use instead of
854 * @closure->callback.
856 void
857 g_closure_set_marshal (GClosure *closure,
858 GClosureMarshal marshal)
860 g_return_if_fail (closure != NULL);
861 g_return_if_fail (marshal != NULL);
863 if (closure->marshal && closure->marshal != marshal)
864 g_warning ("attempt to override closure->marshal (%p) with new marshal (%p)",
865 closure->marshal, marshal);
866 else
867 closure->marshal = marshal;
870 void
871 _g_closure_set_va_marshal (GClosure *closure,
872 GVaClosureMarshal marshal)
874 GRealClosure *real_closure;
876 g_return_if_fail (closure != NULL);
877 g_return_if_fail (marshal != NULL);
879 real_closure = G_REAL_CLOSURE (closure);
881 if (real_closure->va_marshal && real_closure->va_marshal != marshal)
882 g_warning ("attempt to override closure->va_marshal (%p) with new marshal (%p)",
883 real_closure->va_marshal, marshal);
884 else
885 real_closure->va_marshal = marshal;
889 * g_cclosure_new: (skip)
890 * @callback_func: the function to invoke
891 * @user_data: user data to pass to @callback_func
892 * @destroy_data: destroy notify to be called when @user_data is no longer used
894 * Creates a new closure which invokes @callback_func with @user_data as
895 * the last parameter.
897 * Returns: a new #GCClosure
899 GClosure*
900 g_cclosure_new (GCallback callback_func,
901 gpointer user_data,
902 GClosureNotify destroy_data)
904 GClosure *closure;
906 g_return_val_if_fail (callback_func != NULL, NULL);
908 closure = g_closure_new_simple (sizeof (GCClosure), user_data);
909 if (destroy_data)
910 g_closure_add_finalize_notifier (closure, user_data, destroy_data);
911 ((GCClosure*) closure)->callback = (gpointer) callback_func;
913 return closure;
917 * g_cclosure_new_swap: (skip)
918 * @callback_func: the function to invoke
919 * @user_data: user data to pass to @callback_func
920 * @destroy_data: destroy notify to be called when @user_data is no longer used
922 * Creates a new closure which invokes @callback_func with @user_data as
923 * the first parameter.
925 * Returns: (transfer full): a new #GCClosure
927 GClosure*
928 g_cclosure_new_swap (GCallback callback_func,
929 gpointer user_data,
930 GClosureNotify destroy_data)
932 GClosure *closure;
934 g_return_val_if_fail (callback_func != NULL, NULL);
936 closure = g_closure_new_simple (sizeof (GCClosure), user_data);
937 if (destroy_data)
938 g_closure_add_finalize_notifier (closure, user_data, destroy_data);
939 ((GCClosure*) closure)->callback = (gpointer) callback_func;
940 SET (closure, derivative_flag, TRUE);
942 return closure;
945 static void
946 g_type_class_meta_marshal (GClosure *closure,
947 GValue /*out*/ *return_value,
948 guint n_param_values,
949 const GValue *param_values,
950 gpointer invocation_hint,
951 gpointer marshal_data)
953 GTypeClass *class;
954 gpointer callback;
955 /* GType itype = (GType) closure->data; */
956 guint offset = GPOINTER_TO_UINT (marshal_data);
958 class = G_TYPE_INSTANCE_GET_CLASS (g_value_peek_pointer (param_values + 0), itype, GTypeClass);
959 callback = G_STRUCT_MEMBER (gpointer, class, offset);
960 if (callback)
961 closure->marshal (closure,
962 return_value,
963 n_param_values, param_values,
964 invocation_hint,
965 callback);
968 static void
969 g_type_class_meta_marshalv (GClosure *closure,
970 GValue *return_value,
971 gpointer instance,
972 va_list args,
973 gpointer marshal_data,
974 int n_params,
975 GType *param_types)
977 GRealClosure *real_closure;
978 GTypeClass *class;
979 gpointer callback;
980 /* GType itype = (GType) closure->data; */
981 guint offset = GPOINTER_TO_UINT (marshal_data);
983 real_closure = G_REAL_CLOSURE (closure);
985 class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass);
986 callback = G_STRUCT_MEMBER (gpointer, class, offset);
987 if (callback)
988 real_closure->va_marshal (closure,
989 return_value,
990 instance, args,
991 callback,
992 n_params,
993 param_types);
996 static void
997 g_type_iface_meta_marshal (GClosure *closure,
998 GValue /*out*/ *return_value,
999 guint n_param_values,
1000 const GValue *param_values,
1001 gpointer invocation_hint,
1002 gpointer marshal_data)
1004 GTypeClass *class;
1005 gpointer callback;
1006 GType itype = (GType) closure->data;
1007 guint offset = GPOINTER_TO_UINT (marshal_data);
1009 class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_peek_pointer (param_values + 0), itype, GTypeClass);
1010 callback = G_STRUCT_MEMBER (gpointer, class, offset);
1011 if (callback)
1012 closure->marshal (closure,
1013 return_value,
1014 n_param_values, param_values,
1015 invocation_hint,
1016 callback);
1019 gboolean
1020 _g_closure_is_void (GClosure *closure,
1021 gpointer instance)
1023 GRealClosure *real_closure;
1024 GTypeClass *class;
1025 gpointer callback;
1026 GType itype;
1027 guint offset;
1029 if (closure->is_invalid)
1030 return TRUE;
1032 real_closure = G_REAL_CLOSURE (closure);
1034 if (real_closure->meta_marshal == g_type_iface_meta_marshal)
1036 itype = (GType) closure->data;
1037 offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data);
1039 class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass);
1040 callback = G_STRUCT_MEMBER (gpointer, class, offset);
1041 return callback == NULL;
1043 else if (real_closure->meta_marshal == g_type_class_meta_marshal)
1045 offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data);
1047 class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass);
1048 callback = G_STRUCT_MEMBER (gpointer, class, offset);
1049 return callback == NULL;
1052 return FALSE;
1055 static void
1056 g_type_iface_meta_marshalv (GClosure *closure,
1057 GValue *return_value,
1058 gpointer instance,
1059 va_list args,
1060 gpointer marshal_data,
1061 int n_params,
1062 GType *param_types)
1064 GRealClosure *real_closure;
1065 GTypeClass *class;
1066 gpointer callback;
1067 GType itype = (GType) closure->data;
1068 guint offset = GPOINTER_TO_UINT (marshal_data);
1070 real_closure = G_REAL_CLOSURE (closure);
1072 class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass);
1073 callback = G_STRUCT_MEMBER (gpointer, class, offset);
1074 if (callback)
1075 real_closure->va_marshal (closure,
1076 return_value,
1077 instance, args,
1078 callback,
1079 n_params,
1080 param_types);
1084 * g_signal_type_cclosure_new:
1085 * @itype: the #GType identifier of an interface or classed type
1086 * @struct_offset: the offset of the member function of @itype's class
1087 * structure which is to be invoked by the new closure
1089 * Creates a new closure which invokes the function found at the offset
1090 * @struct_offset in the class structure of the interface or classed type
1091 * identified by @itype.
1093 * Returns: a new #GCClosure
1095 GClosure*
1096 g_signal_type_cclosure_new (GType itype,
1097 guint struct_offset)
1099 GClosure *closure;
1101 g_return_val_if_fail (G_TYPE_IS_CLASSED (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
1102 g_return_val_if_fail (struct_offset >= sizeof (GTypeClass), NULL);
1104 closure = g_closure_new_simple (sizeof (GClosure), (gpointer) itype);
1105 if (G_TYPE_IS_INTERFACE (itype))
1107 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_iface_meta_marshal);
1108 g_closure_set_meta_va_marshal (closure, g_type_iface_meta_marshalv);
1110 else
1112 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_class_meta_marshal);
1113 g_closure_set_meta_va_marshal (closure, g_type_class_meta_marshalv);
1115 return closure;
1118 #include <ffi.h>
1119 static ffi_type *
1120 value_to_ffi_type (const GValue *gvalue,
1121 gpointer *value,
1122 gint *enum_tmpval,
1123 gboolean *tmpval_used)
1125 ffi_type *rettype = NULL;
1126 GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
1127 g_assert (type != G_TYPE_INVALID);
1129 if (enum_tmpval)
1131 g_assert (tmpval_used != NULL);
1132 *tmpval_used = FALSE;
1135 switch (type)
1137 case G_TYPE_BOOLEAN:
1138 case G_TYPE_CHAR:
1139 case G_TYPE_INT:
1140 rettype = &ffi_type_sint;
1141 *value = (gpointer)&(gvalue->data[0].v_int);
1142 break;
1143 case G_TYPE_ENUM:
1144 /* enums are stored in v_long even though they are integers, which makes
1145 * marshalling through libffi somewhat complicated. They need to be
1146 * marshalled as signed ints, but we need to use a temporary int sized
1147 * value to pass to libffi otherwise it'll pull the wrong value on
1148 * BE machines with 32-bit integers when treating v_long as 32-bit int.
1150 g_assert (enum_tmpval != NULL);
1151 rettype = &ffi_type_sint;
1152 *enum_tmpval = g_value_get_enum (gvalue);
1153 *value = enum_tmpval;
1154 *tmpval_used = TRUE;
1155 break;
1156 case G_TYPE_UCHAR:
1157 case G_TYPE_UINT:
1158 case G_TYPE_FLAGS:
1159 rettype = &ffi_type_uint;
1160 *value = (gpointer)&(gvalue->data[0].v_uint);
1161 break;
1162 case G_TYPE_STRING:
1163 case G_TYPE_OBJECT:
1164 case G_TYPE_BOXED:
1165 case G_TYPE_PARAM:
1166 case G_TYPE_POINTER:
1167 case G_TYPE_INTERFACE:
1168 case G_TYPE_VARIANT:
1169 rettype = &ffi_type_pointer;
1170 *value = (gpointer)&(gvalue->data[0].v_pointer);
1171 break;
1172 case G_TYPE_FLOAT:
1173 rettype = &ffi_type_float;
1174 *value = (gpointer)&(gvalue->data[0].v_float);
1175 break;
1176 case G_TYPE_DOUBLE:
1177 rettype = &ffi_type_double;
1178 *value = (gpointer)&(gvalue->data[0].v_double);
1179 break;
1180 case G_TYPE_LONG:
1181 rettype = &ffi_type_slong;
1182 *value = (gpointer)&(gvalue->data[0].v_long);
1183 break;
1184 case G_TYPE_ULONG:
1185 rettype = &ffi_type_ulong;
1186 *value = (gpointer)&(gvalue->data[0].v_ulong);
1187 break;
1188 case G_TYPE_INT64:
1189 rettype = &ffi_type_sint64;
1190 *value = (gpointer)&(gvalue->data[0].v_int64);
1191 break;
1192 case G_TYPE_UINT64:
1193 rettype = &ffi_type_uint64;
1194 *value = (gpointer)&(gvalue->data[0].v_uint64);
1195 break;
1196 default:
1197 rettype = &ffi_type_pointer;
1198 *value = NULL;
1199 g_warning ("value_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type));
1200 break;
1202 return rettype;
1205 static void
1206 value_from_ffi_type (GValue *gvalue, gpointer *value)
1208 ffi_arg *int_val = (ffi_arg*) value;
1210 switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
1212 case G_TYPE_INT:
1213 g_value_set_int (gvalue, (gint) *int_val);
1214 break;
1215 case G_TYPE_FLOAT:
1216 g_value_set_float (gvalue, *(gfloat*)value);
1217 break;
1218 case G_TYPE_DOUBLE:
1219 g_value_set_double (gvalue, *(gdouble*)value);
1220 break;
1221 case G_TYPE_BOOLEAN:
1222 g_value_set_boolean (gvalue, (gboolean) *int_val);
1223 break;
1224 case G_TYPE_STRING:
1225 g_value_take_string (gvalue, *(gchar**)value);
1226 break;
1227 case G_TYPE_CHAR:
1228 g_value_set_schar (gvalue, (gint8) *int_val);
1229 break;
1230 case G_TYPE_UCHAR:
1231 g_value_set_uchar (gvalue, (guchar) *int_val);
1232 break;
1233 case G_TYPE_UINT:
1234 g_value_set_uint (gvalue, (guint) *int_val);
1235 break;
1236 case G_TYPE_POINTER:
1237 g_value_set_pointer (gvalue, *(gpointer*)value);
1238 break;
1239 case G_TYPE_LONG:
1240 g_value_set_long (gvalue, (glong) *int_val);
1241 break;
1242 case G_TYPE_ULONG:
1243 g_value_set_ulong (gvalue, (gulong) *int_val);
1244 break;
1245 case G_TYPE_INT64:
1246 g_value_set_int64 (gvalue, (gint64) *int_val);
1247 break;
1248 case G_TYPE_UINT64:
1249 g_value_set_uint64 (gvalue, (guint64) *int_val);
1250 break;
1251 case G_TYPE_BOXED:
1252 g_value_take_boxed (gvalue, *(gpointer*)value);
1253 break;
1254 case G_TYPE_ENUM:
1255 g_value_set_enum (gvalue, (gint) *int_val);
1256 break;
1257 case G_TYPE_FLAGS:
1258 g_value_set_flags (gvalue, (guint) *int_val);
1259 break;
1260 case G_TYPE_PARAM:
1261 g_value_take_param (gvalue, *(gpointer*)value);
1262 break;
1263 case G_TYPE_OBJECT:
1264 g_value_take_object (gvalue, *(gpointer*)value);
1265 break;
1266 case G_TYPE_VARIANT:
1267 g_value_take_variant (gvalue, *(gpointer*)value);
1268 break;
1269 default:
1270 g_warning ("value_from_ffi_type: Unsupported fundamental type: %s",
1271 g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
1275 typedef union {
1276 gpointer _gpointer;
1277 float _float;
1278 double _double;
1279 gint _gint;
1280 guint _guint;
1281 glong _glong;
1282 gulong _gulong;
1283 gint64 _gint64;
1284 guint64 _guint64;
1285 } va_arg_storage;
1287 static ffi_type *
1288 va_to_ffi_type (GType gtype,
1289 va_list *va,
1290 va_arg_storage *storage)
1292 ffi_type *rettype = NULL;
1293 GType type = g_type_fundamental (gtype);
1294 g_assert (type != G_TYPE_INVALID);
1296 switch (type)
1298 case G_TYPE_BOOLEAN:
1299 case G_TYPE_CHAR:
1300 case G_TYPE_INT:
1301 case G_TYPE_ENUM:
1302 rettype = &ffi_type_sint;
1303 storage->_gint = va_arg (*va, gint);
1304 break;
1305 case G_TYPE_UCHAR:
1306 case G_TYPE_UINT:
1307 case G_TYPE_FLAGS:
1308 rettype = &ffi_type_uint;
1309 storage->_guint = va_arg (*va, guint);
1310 break;
1311 case G_TYPE_STRING:
1312 case G_TYPE_OBJECT:
1313 case G_TYPE_BOXED:
1314 case G_TYPE_PARAM:
1315 case G_TYPE_POINTER:
1316 case G_TYPE_INTERFACE:
1317 case G_TYPE_VARIANT:
1318 rettype = &ffi_type_pointer;
1319 storage->_gpointer = va_arg (*va, gpointer);
1320 break;
1321 case G_TYPE_FLOAT:
1322 /* Float args are passed as doubles in varargs */
1323 rettype = &ffi_type_float;
1324 storage->_float = (float)va_arg (*va, double);
1325 break;
1326 case G_TYPE_DOUBLE:
1327 rettype = &ffi_type_double;
1328 storage->_double = va_arg (*va, double);
1329 break;
1330 case G_TYPE_LONG:
1331 rettype = &ffi_type_slong;
1332 storage->_glong = va_arg (*va, glong);
1333 break;
1334 case G_TYPE_ULONG:
1335 rettype = &ffi_type_ulong;
1336 storage->_gulong = va_arg (*va, gulong);
1337 break;
1338 case G_TYPE_INT64:
1339 rettype = &ffi_type_sint64;
1340 storage->_gint64 = va_arg (*va, gint64);
1341 break;
1342 case G_TYPE_UINT64:
1343 rettype = &ffi_type_uint64;
1344 storage->_guint64 = va_arg (*va, guint64);
1345 break;
1346 default:
1347 rettype = &ffi_type_pointer;
1348 storage->_guint64 = 0;
1349 g_warning ("va_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type));
1350 break;
1352 return rettype;
1356 * g_cclosure_marshal_generic:
1357 * @closure: A #GClosure.
1358 * @return_gvalue: A #GValue to store the return value. May be %NULL
1359 * if the callback of closure doesn't return a value.
1360 * @n_param_values: The length of the @param_values array.
1361 * @param_values: An array of #GValues holding the arguments
1362 * on which to invoke the callback of closure.
1363 * @invocation_hint: The invocation hint given as the last argument to
1364 * g_closure_invoke().
1365 * @marshal_data: Additional data specified when registering the
1366 * marshaller, see g_closure_set_marshal() and
1367 * g_closure_set_meta_marshal()
1369 * A generic marshaller function implemented via
1370 * [libffi](http://sourceware.org/libffi/).
1372 * Since: 2.30
1374 void
1375 g_cclosure_marshal_generic (GClosure *closure,
1376 GValue *return_gvalue,
1377 guint n_param_values,
1378 const GValue *param_values,
1379 gpointer invocation_hint,
1380 gpointer marshal_data)
1382 ffi_type *rtype;
1383 void *rvalue;
1384 int n_args;
1385 ffi_type **atypes;
1386 void **args;
1387 int i;
1388 ffi_cif cif;
1389 GCClosure *cc = (GCClosure*) closure;
1390 gint *enum_tmpval;
1391 gboolean tmpval_used = FALSE;
1393 enum_tmpval = g_alloca (sizeof (gint));
1394 if (return_gvalue && G_VALUE_TYPE (return_gvalue))
1396 rtype = value_to_ffi_type (return_gvalue, &rvalue, enum_tmpval, &tmpval_used);
1398 else
1400 rtype = &ffi_type_void;
1403 rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));
1405 n_args = n_param_values + 1;
1406 atypes = g_alloca (sizeof (ffi_type *) * n_args);
1407 args = g_alloca (sizeof (gpointer) * n_args);
1409 if (tmpval_used)
1410 enum_tmpval = g_alloca (sizeof (gint));
1412 if (G_CCLOSURE_SWAP_DATA (closure))
1414 atypes[n_args-1] = value_to_ffi_type (param_values + 0,
1415 &args[n_args-1],
1416 enum_tmpval,
1417 &tmpval_used);
1418 atypes[0] = &ffi_type_pointer;
1419 args[0] = &closure->data;
1421 else
1423 atypes[0] = value_to_ffi_type (param_values + 0,
1424 &args[0],
1425 enum_tmpval,
1426 &tmpval_used);
1427 atypes[n_args-1] = &ffi_type_pointer;
1428 args[n_args-1] = &closure->data;
1431 for (i = 1; i < n_args - 1; i++)
1433 if (tmpval_used)
1434 enum_tmpval = g_alloca (sizeof (gint));
1436 atypes[i] = value_to_ffi_type (param_values + i,
1437 &args[i],
1438 enum_tmpval,
1439 &tmpval_used);
1442 if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
1443 return;
1445 ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);
1447 if (return_gvalue && G_VALUE_TYPE (return_gvalue))
1448 value_from_ffi_type (return_gvalue, rvalue);
1451 void
1452 g_cclosure_marshal_generic_va (GClosure *closure,
1453 GValue *return_value,
1454 gpointer instance,
1455 va_list args_list,
1456 gpointer marshal_data,
1457 int n_params,
1458 GType *param_types)
1460 ffi_type *rtype;
1461 void *rvalue;
1462 int n_args;
1463 ffi_type **atypes;
1464 void **args;
1465 va_arg_storage *storage;
1466 int i;
1467 ffi_cif cif;
1468 GCClosure *cc = (GCClosure*) closure;
1469 gint *enum_tmpval;
1470 gboolean tmpval_used = FALSE;
1471 va_list args_copy;
1473 enum_tmpval = g_alloca (sizeof (gint));
1474 if (return_value && G_VALUE_TYPE (return_value))
1476 rtype = value_to_ffi_type (return_value, &rvalue, enum_tmpval, &tmpval_used);
1478 else
1480 rtype = &ffi_type_void;
1483 rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));
1485 n_args = n_params + 2;
1486 atypes = g_alloca (sizeof (ffi_type *) * n_args);
1487 args = g_alloca (sizeof (gpointer) * n_args);
1488 storage = g_alloca (sizeof (va_arg_storage) * n_params);
1490 if (tmpval_used)
1491 enum_tmpval = g_alloca (sizeof (gint));
1493 if (G_CCLOSURE_SWAP_DATA (closure))
1495 atypes[n_args-1] = &ffi_type_pointer;
1496 args[n_args-1] = &instance;
1497 atypes[0] = &ffi_type_pointer;
1498 args[0] = &closure->data;
1500 else
1502 atypes[0] = &ffi_type_pointer;
1503 args[0] = &instance;
1504 atypes[n_args-1] = &ffi_type_pointer;
1505 args[n_args-1] = &closure->data;
1508 G_VA_COPY (args_copy, args_list);
1510 /* Box non-primitive arguments */
1511 for (i = 0; i < n_params; i++)
1513 GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
1514 GType fundamental = G_TYPE_FUNDAMENTAL (type);
1516 atypes[i+1] = va_to_ffi_type (type,
1517 &args_copy,
1518 &storage[i]);
1519 args[i+1] = &storage[i];
1521 if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0)
1523 if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL)
1524 storage[i]._gpointer = g_strdup (storage[i]._gpointer);
1525 else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL)
1526 storage[i]._gpointer = g_param_spec_ref (storage[i]._gpointer);
1527 else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL)
1528 storage[i]._gpointer = g_boxed_copy (type, storage[i]._gpointer);
1529 else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL)
1530 storage[i]._gpointer = g_variant_ref_sink (storage[i]._gpointer);
1532 if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL)
1533 storage[i]._gpointer = g_object_ref (storage[i]._gpointer);
1536 va_end (args_copy);
1538 if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
1539 return;
1541 ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);
1543 /* Unbox non-primitive arguments */
1544 for (i = 0; i < n_params; i++)
1546 GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
1547 GType fundamental = G_TYPE_FUNDAMENTAL (type);
1549 if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0)
1551 if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL)
1552 g_free (storage[i]._gpointer);
1553 else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL)
1554 g_param_spec_unref (storage[i]._gpointer);
1555 else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL)
1556 g_boxed_free (type, storage[i]._gpointer);
1557 else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL)
1558 g_variant_unref (storage[i]._gpointer);
1560 if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL)
1561 g_object_unref (storage[i]._gpointer);
1564 if (return_value && G_VALUE_TYPE (return_value))
1565 value_from_ffi_type (return_value, rvalue);
1569 * g_cclosure_marshal_VOID__VOID:
1570 * @closure: the #GClosure to which the marshaller belongs
1571 * @return_value: ignored
1572 * @n_param_values: 1
1573 * @param_values: a #GValue array holding only the instance
1574 * @invocation_hint: the invocation hint given as the last argument
1575 * to g_closure_invoke()
1576 * @marshal_data: additional data specified when registering the marshaller
1578 * A marshaller for a #GCClosure with a callback of type
1579 * `void (*callback) (gpointer instance, gpointer user_data)`.
1583 * g_cclosure_marshal_VOID__BOOLEAN:
1584 * @closure: the #GClosure to which the marshaller belongs
1585 * @return_value: ignored
1586 * @n_param_values: 2
1587 * @param_values: a #GValue array holding the instance and the #gboolean parameter
1588 * @invocation_hint: the invocation hint given as the last argument
1589 * to g_closure_invoke()
1590 * @marshal_data: additional data specified when registering the marshaller
1592 * A marshaller for a #GCClosure with a callback of type
1593 * `void (*callback) (gpointer instance, gboolean arg1, gpointer user_data)`.
1597 * g_cclosure_marshal_VOID__CHAR:
1598 * @closure: the #GClosure to which the marshaller belongs
1599 * @return_value: ignored
1600 * @n_param_values: 2
1601 * @param_values: a #GValue array holding the instance and the #gchar parameter
1602 * @invocation_hint: the invocation hint given as the last argument
1603 * to g_closure_invoke()
1604 * @marshal_data: additional data specified when registering the marshaller
1606 * A marshaller for a #GCClosure with a callback of type
1607 * `void (*callback) (gpointer instance, gchar arg1, gpointer user_data)`.
1611 * g_cclosure_marshal_VOID__UCHAR:
1612 * @closure: the #GClosure to which the marshaller belongs
1613 * @return_value: ignored
1614 * @n_param_values: 2
1615 * @param_values: a #GValue array holding the instance and the #guchar parameter
1616 * @invocation_hint: the invocation hint given as the last argument
1617 * to g_closure_invoke()
1618 * @marshal_data: additional data specified when registering the marshaller
1620 * A marshaller for a #GCClosure with a callback of type
1621 * `void (*callback) (gpointer instance, guchar arg1, gpointer user_data)`.
1625 * g_cclosure_marshal_VOID__INT:
1626 * @closure: the #GClosure to which the marshaller belongs
1627 * @return_value: ignored
1628 * @n_param_values: 2
1629 * @param_values: a #GValue array holding the instance and the #gint parameter
1630 * @invocation_hint: the invocation hint given as the last argument
1631 * to g_closure_invoke()
1632 * @marshal_data: additional data specified when registering the marshaller
1634 * A marshaller for a #GCClosure with a callback of type
1635 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)`.
1639 * g_cclosure_marshal_VOID__UINT:
1640 * @closure: the #GClosure to which the marshaller belongs
1641 * @return_value: ignored
1642 * @n_param_values: 2
1643 * @param_values: a #GValue array holding the instance and the #guint parameter
1644 * @invocation_hint: the invocation hint given as the last argument
1645 * to g_closure_invoke()
1646 * @marshal_data: additional data specified when registering the marshaller
1648 * A marshaller for a #GCClosure with a callback of type
1649 * `void (*callback) (gpointer instance, guint arg1, gpointer user_data)`.
1653 * g_cclosure_marshal_VOID__LONG:
1654 * @closure: the #GClosure to which the marshaller belongs
1655 * @return_value: ignored
1656 * @n_param_values: 2
1657 * @param_values: a #GValue array holding the instance and the #glong parameter
1658 * @invocation_hint: the invocation hint given as the last argument
1659 * to g_closure_invoke()
1660 * @marshal_data: additional data specified when registering the marshaller
1662 * A marshaller for a #GCClosure with a callback of type
1663 * `void (*callback) (gpointer instance, glong arg1, gpointer user_data)`.
1667 * g_cclosure_marshal_VOID__ULONG:
1668 * @closure: the #GClosure to which the marshaller belongs
1669 * @return_value: ignored
1670 * @n_param_values: 2
1671 * @param_values: a #GValue array holding the instance and the #gulong parameter
1672 * @invocation_hint: the invocation hint given as the last argument
1673 * to g_closure_invoke()
1674 * @marshal_data: additional data specified when registering the marshaller
1676 * A marshaller for a #GCClosure with a callback of type
1677 * `void (*callback) (gpointer instance, gulong arg1, gpointer user_data)`.
1681 * g_cclosure_marshal_VOID__ENUM:
1682 * @closure: the #GClosure to which the marshaller belongs
1683 * @return_value: ignored
1684 * @n_param_values: 2
1685 * @param_values: a #GValue array holding the instance and the enumeration parameter
1686 * @invocation_hint: the invocation hint given as the last argument
1687 * to g_closure_invoke()
1688 * @marshal_data: additional data specified when registering the marshaller
1690 * A marshaller for a #GCClosure with a callback of type
1691 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes an enumeration type..
1695 * g_cclosure_marshal_VOID__FLAGS:
1696 * @closure: the #GClosure to which the marshaller belongs
1697 * @return_value: ignored
1698 * @n_param_values: 2
1699 * @param_values: a #GValue array holding the instance and the flags parameter
1700 * @invocation_hint: the invocation hint given as the last argument
1701 * to g_closure_invoke()
1702 * @marshal_data: additional data specified when registering the marshaller
1704 * A marshaller for a #GCClosure with a callback of type
1705 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes a flags type.
1709 * g_cclosure_marshal_VOID__FLOAT:
1710 * @closure: the #GClosure to which the marshaller belongs
1711 * @return_value: ignored
1712 * @n_param_values: 2
1713 * @param_values: a #GValue array holding the instance and the #gfloat parameter
1714 * @invocation_hint: the invocation hint given as the last argument
1715 * to g_closure_invoke()
1716 * @marshal_data: additional data specified when registering the marshaller
1718 * A marshaller for a #GCClosure with a callback of type
1719 * `void (*callback) (gpointer instance, gfloat arg1, gpointer user_data)`.
1723 * g_cclosure_marshal_VOID__DOUBLE:
1724 * @closure: the #GClosure to which the marshaller belongs
1725 * @return_value: ignored
1726 * @n_param_values: 2
1727 * @param_values: a #GValue array holding the instance and the #gdouble parameter
1728 * @invocation_hint: the invocation hint given as the last argument
1729 * to g_closure_invoke()
1730 * @marshal_data: additional data specified when registering the marshaller
1732 * A marshaller for a #GCClosure with a callback of type
1733 * `void (*callback) (gpointer instance, gdouble arg1, gpointer user_data)`.
1737 * g_cclosure_marshal_VOID__STRING:
1738 * @closure: the #GClosure to which the marshaller belongs
1739 * @return_value: ignored
1740 * @n_param_values: 2
1741 * @param_values: a #GValue array holding the instance and the #gchar* parameter
1742 * @invocation_hint: the invocation hint given as the last argument
1743 * to g_closure_invoke()
1744 * @marshal_data: additional data specified when registering the marshaller
1746 * A marshaller for a #GCClosure with a callback of type
1747 * `void (*callback) (gpointer instance, const gchar *arg1, gpointer user_data)`.
1751 * g_cclosure_marshal_VOID__PARAM:
1752 * @closure: the #GClosure to which the marshaller belongs
1753 * @return_value: ignored
1754 * @n_param_values: 2
1755 * @param_values: a #GValue array holding the instance and the #GParamSpec* parameter
1756 * @invocation_hint: the invocation hint given as the last argument
1757 * to g_closure_invoke()
1758 * @marshal_data: additional data specified when registering the marshaller
1760 * A marshaller for a #GCClosure with a callback of type
1761 * `void (*callback) (gpointer instance, GParamSpec *arg1, gpointer user_data)`.
1765 * g_cclosure_marshal_VOID__BOXED:
1766 * @closure: the #GClosure to which the marshaller belongs
1767 * @return_value: ignored
1768 * @n_param_values: 2
1769 * @param_values: a #GValue array holding the instance and the #GBoxed* parameter
1770 * @invocation_hint: the invocation hint given as the last argument
1771 * to g_closure_invoke()
1772 * @marshal_data: additional data specified when registering the marshaller
1774 * A marshaller for a #GCClosure with a callback of type
1775 * `void (*callback) (gpointer instance, GBoxed *arg1, gpointer user_data)`.
1779 * g_cclosure_marshal_VOID__POINTER:
1780 * @closure: the #GClosure to which the marshaller belongs
1781 * @return_value: ignored
1782 * @n_param_values: 2
1783 * @param_values: a #GValue array holding the instance and the #gpointer parameter
1784 * @invocation_hint: the invocation hint given as the last argument
1785 * to g_closure_invoke()
1786 * @marshal_data: additional data specified when registering the marshaller
1788 * A marshaller for a #GCClosure with a callback of type
1789 * `void (*callback) (gpointer instance, gpointer arg1, gpointer user_data)`.
1793 * g_cclosure_marshal_VOID__OBJECT:
1794 * @closure: the #GClosure to which the marshaller belongs
1795 * @return_value: ignored
1796 * @n_param_values: 2
1797 * @param_values: a #GValue array holding the instance and the #GObject* parameter
1798 * @invocation_hint: the invocation hint given as the last argument
1799 * to g_closure_invoke()
1800 * @marshal_data: additional data specified when registering the marshaller
1802 * A marshaller for a #GCClosure with a callback of type
1803 * `void (*callback) (gpointer instance, GObject *arg1, gpointer user_data)`.
1807 * g_cclosure_marshal_VOID__VARIANT:
1808 * @closure: the #GClosure to which the marshaller belongs
1809 * @return_value: ignored
1810 * @n_param_values: 2
1811 * @param_values: a #GValue array holding the instance and the #GVariant* parameter
1812 * @invocation_hint: the invocation hint given as the last argument
1813 * to g_closure_invoke()
1814 * @marshal_data: additional data specified when registering the marshaller
1816 * A marshaller for a #GCClosure with a callback of type
1817 * `void (*callback) (gpointer instance, GVariant *arg1, gpointer user_data)`.
1819 * Since: 2.26
1823 * g_cclosure_marshal_VOID__UINT_POINTER:
1824 * @closure: the #GClosure to which the marshaller belongs
1825 * @return_value: ignored
1826 * @n_param_values: 3
1827 * @param_values: a #GValue array holding instance, arg1 and arg2
1828 * @invocation_hint: the invocation hint given as the last argument
1829 * to g_closure_invoke()
1830 * @marshal_data: additional data specified when registering the marshaller
1832 * A marshaller for a #GCClosure with a callback of type
1833 * `void (*callback) (gpointer instance, guint arg1, gpointer arg2, gpointer user_data)`.
1837 * g_cclosure_marshal_BOOLEAN__FLAGS:
1838 * @closure: the #GClosure to which the marshaller belongs
1839 * @return_value: a #GValue which can store the returned #gboolean
1840 * @n_param_values: 2
1841 * @param_values: a #GValue array holding instance and arg1
1842 * @invocation_hint: the invocation hint given as the last argument
1843 * to g_closure_invoke()
1844 * @marshal_data: additional data specified when registering the marshaller
1846 * A marshaller for a #GCClosure with a callback of type
1847 * `gboolean (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter
1848 * denotes a flags type.
1852 * g_cclosure_marshal_BOOL__FLAGS:
1854 * Another name for g_cclosure_marshal_BOOLEAN__FLAGS().
1857 * g_cclosure_marshal_STRING__OBJECT_POINTER:
1858 * @closure: the #GClosure to which the marshaller belongs
1859 * @return_value: a #GValue, which can store the returned string
1860 * @n_param_values: 3
1861 * @param_values: a #GValue array holding instance, arg1 and arg2
1862 * @invocation_hint: the invocation hint given as the last argument
1863 * to g_closure_invoke()
1864 * @marshal_data: additional data specified when registering the marshaller
1866 * A marshaller for a #GCClosure with a callback of type
1867 * `gchar* (*callback) (gpointer instance, GObject *arg1, gpointer arg2, gpointer user_data)`.
1870 * g_cclosure_marshal_BOOLEAN__OBJECT_BOXED_BOXED:
1871 * @closure: the #GClosure to which the marshaller belongs
1872 * @return_value: a #GValue, which can store the returned string
1873 * @n_param_values: 3
1874 * @param_values: a #GValue array holding instance, arg1 and arg2
1875 * @invocation_hint: the invocation hint given as the last argument
1876 * to g_closure_invoke()
1877 * @marshal_data: additional data specified when registering the marshaller
1879 * A marshaller for a #GCClosure with a callback of type
1880 * `gboolean (*callback) (gpointer instance, GBoxed *arg1, GBoxed *arg2, gpointer user_data)`.
1882 * Since: 2.26