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, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* 20 * MT safe with regards to reference counting. 21 */ 22 23 #include "config.h" 24 25 #include <string.h> 26 27 #include <ffi.h> 28 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" 36 37 38 /** 39 * SECTION:gclosure 40 * @short_description: Functions as first-class objects 41 * @title: Closures 42 * 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 responsibility 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. 49 * 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. 57 * 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. 70 * 71 * Using closures has a number of important advantages over a simple 72 * callback function/data pointer combination: 73 * 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. 77 * 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. 81 * 82 * - g_closure_invalidate() and invalidation notifiers allow callbacks to be 83 * automatically removed when the objects they point to go away. 84 */ 85 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) 95 96 typedef union { 97 GClosure closure; 98 volatile gint vint; 99 } ClosureInt; 100 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 \ 106 { \ 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); \ 114 } \ 115 while (!success && _must_set); \ 116 } G_STMT_END 117 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) = ) 124 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 133 134 enum { 135 FNOTIFY, 136 INOTIFY, 137 PRE_NOTIFY, 138 POST_NOTIFY 139 }; 140 141 142 /* --- functions --- */ 143 /** 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 148 * 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. 152 * 153 * |[<!-- language="C" --> 154 * typedef struct _MyClosure MyClosure; 155 * struct _MyClosure 156 * { 157 * GClosure closure; 158 * // extra data goes here 159 * }; 160 * 161 * static void 162 * my_closure_finalize (gpointer notify_data, 163 * GClosure *closure) 164 * { 165 * MyClosure *my_closure = (MyClosure *)closure; 166 * 167 * // free extra data here 168 * } 169 * 170 * MyClosure *my_closure_new (gpointer data) 171 * { 172 * GClosure *closure; 173 * MyClosure *my_closure; 174 * 175 * closure = g_closure_new_simple (sizeof (MyClosure), data); 176 * my_closure = (MyClosure *) closure; 177 * 178 * // initialize extra data here 179 * 180 * g_closure_add_finalize_notifier (closure, notify_data, 181 * my_closure_finalize); 182 * return my_closure; 183 * } 184 * ]| 185 * 186 * Returns: (transfer full): a newly allocated #GClosure 187 */ 188 GClosure* 189 g_closure_new_simple (guint sizeof_closure, 190 gpointer data) 191 { 192 GRealClosure *real_closure; 193 GClosure *closure; 194 195 g_return_val_if_fail (sizeof_closure >= sizeof (GClosure), NULL); 196 sizeof_closure = sizeof_closure + sizeof (GRealClosure) - sizeof (GClosure); 197 198 real_closure = g_malloc0 (sizeof_closure); 199 #ifdef GSTREAMER_LITE 200 if (real_closure == NULL) 201 return NULL; 202 #endif // GSTREAMER_LITE 203 closure = &real_closure->closure; 204 SET (closure, ref_count, 1); 205 SET (closure, floating, TRUE); 206 closure->data = data; 207 208 return closure; 209 } 210 211 static inline void 212 closure_invoke_notifiers (GClosure *closure, 213 guint notify_type) 214 { 215 /* notifier layout: 216 * n_guards n_guards n_fnotif. n_inotifiers 217 * ->[[pre_guards][post_guards][fnotifiers][inotifiers]] 218 * 219 * CLOSURE_N_MFUNCS(cl) = n_guards + n_guards; 220 * CLOSURE_N_NOTIFIERS(cl) = CLOSURE_N_MFUNCS(cl) + n_fnotifiers + n_inotifiers 221 * 222 * constrains/catches: 223 * - closure->notifiers may be reloacted during callback 224 * - closure->n_fnotifiers and closure->n_inotifiers may change during callback 225 * - i.e. callbacks can be removed/added during invocation 226 * - must prepare for callback removal during FNOTIFY and INOTIFY (done via ->marshal= & ->data=) 227 * - must distinguish (->marshal= & ->data=) for INOTIFY vs. FNOTIFY (via ->in_inotify) 228 * + closure->n_guards is const during PRE_NOTIFY & POST_NOTIFY 229 * + none of the callbacks can cause recursion 230 * + closure->n_inotifiers is const 0 during FNOTIFY 231 */ 232 switch (notify_type) 233 { 234 GClosureNotifyData *ndata; 235 guint i, offs; 236 case FNOTIFY: 237 while (closure->n_fnotifiers) 238 { 239 guint n; 240 DEC_ASSIGN (closure, n_fnotifiers, &n); 241 242 ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n; 243 closure->marshal = (GClosureMarshal) ndata->notify; 244 closure->data = ndata->data; 245 ndata->notify (ndata->data, closure); 246 } 247 closure->marshal = NULL; 248 closure->data = NULL; 249 break; 250 case INOTIFY: 251 SET (closure, in_inotify, TRUE); 252 while (closure->n_inotifiers) 253 { 254 guint n; 255 DEC_ASSIGN (closure, n_inotifiers, &n); 256 257 ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n; 258 closure->marshal = (GClosureMarshal) ndata->notify; 259 closure->data = ndata->data; 260 ndata->notify (ndata->data, closure); 261 } 262 closure->marshal = NULL; 263 closure->data = NULL; 264 SET (closure, in_inotify, FALSE); 265 break; 266 case PRE_NOTIFY: 267 i = closure->n_guards; 268 offs = 0; 269 while (i--) 270 { 271 ndata = closure->notifiers + offs + i; 272 ndata->notify (ndata->data, closure); 273 } 274 break; 275 case POST_NOTIFY: 276 i = closure->n_guards; 277 offs = i; 278 while (i--) 279 { 280 ndata = closure->notifiers + offs + i; 281 ndata->notify (ndata->data, closure); 282 } 283 break; 284 } 285 } 286 287 static void 288 g_closure_set_meta_va_marshal (GClosure *closure, 289 GVaClosureMarshal va_meta_marshal) 290 { 291 GRealClosure *real_closure; 292 293 g_return_if_fail (closure != NULL); 294 g_return_if_fail (va_meta_marshal != NULL); 295 g_return_if_fail (closure->is_invalid == FALSE); 296 g_return_if_fail (closure->in_marshal == FALSE); 297 298 real_closure = G_REAL_CLOSURE (closure); 299 300 g_return_if_fail (real_closure->meta_marshal != NULL); 301 302 real_closure->va_meta_marshal = va_meta_marshal; 303 } 304 305 /** 306 * g_closure_set_meta_marshal: (skip) 307 * @closure: a #GClosure 308 * @marshal_data: context-dependent data to pass to @meta_marshal 309 * @meta_marshal: a #GClosureMarshal function 310 * 311 * Sets the meta marshaller of @closure. A meta marshaller wraps 312 * @closure->marshal and modifies the way it is called in some 313 * fashion. The most common use of this facility is for C callbacks. 314 * The same marshallers (generated by [glib-genmarshal][glib-genmarshal]), 315 * are used everywhere, but the way that we get the callback function 316 * differs. In most cases we want to use @closure->callback, but in 317 * other cases we want to use some different technique to retrieve the 318 * callback function. 319 * 320 * For example, class closures for signals (see 321 * g_signal_type_cclosure_new()) retrieve the callback function from a 322 * fixed offset in the class structure. The meta marshaller retrieves 323 * the right callback and passes it to the marshaller as the 324 * @marshal_data argument. 325 */ 326 void 327 g_closure_set_meta_marshal (GClosure *closure, 328 gpointer marshal_data, 329 GClosureMarshal meta_marshal) 330 { 331 GRealClosure *real_closure; 332 333 g_return_if_fail (closure != NULL); 334 g_return_if_fail (meta_marshal != NULL); 335 g_return_if_fail (closure->is_invalid == FALSE); 336 g_return_if_fail (closure->in_marshal == FALSE); 337 338 real_closure = G_REAL_CLOSURE (closure); 339 340 g_return_if_fail (real_closure->meta_marshal == NULL); 341 342 real_closure->meta_marshal = meta_marshal; 343 real_closure->meta_marshal_data = marshal_data; 344 } 345 346 /** 347 * g_closure_add_marshal_guards: (skip) 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 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->n_guards + 394 closure->n_guards + 1)] = closure->notifiers[closure->n_guards]; 395 i = closure->n_guards; 396 closure->notifiers[i].data = pre_marshal_data; 397 closure->notifiers[i].notify = pre_marshal_notify; 398 closure->notifiers[i + 1].data = post_marshal_data; 399 closure->notifiers[i + 1].notify = post_marshal_notify; 400 INC (closure, n_guards); 401 } 402 403 /** 404 * g_closure_add_finalize_notifier: (skip) 405 * @closure: a #GClosure 406 * @notify_data: data to pass to @notify_func 407 * @notify_func: the callback function to register 408 * 409 * Registers a finalization notifier which will be called when the 410 * reference count of @closure goes down to 0. Multiple finalization 411 * notifiers on a single closure are invoked in unspecified order. If 412 * a single call to g_closure_unref() results in the closure being 413 * both invalidated and finalized, then the invalidate notifiers will 414 * be run before the finalize notifiers. 415 */ 416 void 417 g_closure_add_finalize_notifier (GClosure *closure, 418 gpointer notify_data, 419 GClosureNotify notify_func) 420 { 421 guint i; 422 423 g_return_if_fail (closure != NULL); 424 g_return_if_fail (notify_func != NULL); 425 g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS); 426 427 closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); 428 if (closure->n_inotifiers) 429 closure->notifiers[(CLOSURE_N_MFUNCS (closure) + 430 closure->n_fnotifiers + 431 closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + 432 closure->n_fnotifiers + 0)]; 433 i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers; 434 closure->notifiers[i].data = notify_data; 435 closure->notifiers[i].notify = notify_func; 436 INC (closure, n_fnotifiers); 437 } 438 439 /** 440 * g_closure_add_invalidate_notifier: (skip) 441 * @closure: a #GClosure 442 * @notify_data: data to pass to @notify_func 443 * @notify_func: the callback function to register 444 * 445 * Registers an invalidation notifier which will be called when the 446 * @closure is invalidated with g_closure_invalidate(). Invalidation 447 * notifiers are invoked before finalization notifiers, in an 448 * unspecified order. 449 */ 450 void 451 g_closure_add_invalidate_notifier (GClosure *closure, 452 gpointer notify_data, 453 GClosureNotify notify_func) 454 { 455 guint i; 456 457 g_return_if_fail (closure != NULL); 458 g_return_if_fail (notify_func != NULL); 459 g_return_if_fail (closure->is_invalid == FALSE); 460 g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS); 461 462 closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1); 463 i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers; 464 closure->notifiers[i].data = notify_data; 465 closure->notifiers[i].notify = notify_func; 466 INC (closure, n_inotifiers); 467 } 468 469 static inline gboolean 470 closure_try_remove_inotify (GClosure *closure, 471 gpointer notify_data, 472 GClosureNotify notify_func) 473 { 474 GClosureNotifyData *ndata, *nlast; 475 476 nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1; 477 for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++) 478 if (ndata->notify == notify_func && ndata->data == notify_data) 479 { 480 DEC (closure, n_inotifiers); 481 if (ndata < nlast) 482 *ndata = *nlast; 483 484 return TRUE; 485 } 486 return FALSE; 487 } 488 489 static inline gboolean 490 closure_try_remove_fnotify (GClosure *closure, 491 gpointer notify_data, 492 GClosureNotify notify_func) 493 { 494 GClosureNotifyData *ndata, *nlast; 495 496 nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - closure->n_inotifiers - 1; 497 for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++) 498 if (ndata->notify == notify_func && ndata->data == notify_data) 499 { 500 DEC (closure, n_fnotifiers); 501 if (ndata < nlast) 502 *ndata = *nlast; 503 if (closure->n_inotifiers) 504 closure->notifiers[(CLOSURE_N_MFUNCS (closure) + 505 closure->n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) + 506 closure->n_fnotifiers + 507 closure->n_inotifiers)]; 508 return TRUE; 509 } 510 return FALSE; 511 } 512 513 /** 514 * g_closure_ref: 515 * @closure: #GClosure to increment the reference count on 516 * 517 * Increments the reference count on a closure to force it staying 518 * alive while the caller holds a pointer to it. 519 * 520 * Returns: (transfer none): The @closure passed in, for convenience 521 */ 522 GClosure* 523 g_closure_ref (GClosure *closure) 524 { 525 guint new_ref_count; 526 g_return_val_if_fail (closure != NULL, NULL); 527 g_return_val_if_fail (closure->ref_count > 0, NULL); 528 g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL); 529 530 INC_ASSIGN (closure, ref_count, &new_ref_count); 531 g_return_val_if_fail (new_ref_count > 1, NULL); 532 533 return closure; 534 } 535 536 /** 537 * g_closure_invalidate: 538 * @closure: GClosure to invalidate 539 * 540 * Sets a flag on the closure to indicate that its calling 541 * environment has become invalid, and thus causes any future 542 * invocations of g_closure_invoke() on this @closure to be 543 * ignored. Also, invalidation notifiers installed on the closure will 544 * be called at this point. Note that unless you are holding a 545 * reference to the closure yourself, the invalidation notifiers may 546 * unref the closure and cause it to be destroyed, so if you need to 547 * access the closure after calling g_closure_invalidate(), make sure 548 * that you've previously called g_closure_ref(). 549 * 550 * Note that g_closure_invalidate() will also be called when the 551 * reference count of a closure drops to zero (unless it has already 552 * been invalidated before). 553 */ 554 void 555 g_closure_invalidate (GClosure *closure) 556 { 557 g_return_if_fail (closure != NULL); 558 559 if (!closure->is_invalid) 560 { 561 gboolean was_invalid; 562 g_closure_ref (closure); /* preserve floating flag */ 563 SWAP (closure, is_invalid, TRUE, &was_invalid); 564 /* invalidate only once */ 565 if (!was_invalid) 566 closure_invoke_notifiers (closure, INOTIFY); 567 g_closure_unref (closure); 568 } 569 } 570 571 /** 572 * g_closure_unref: 573 * @closure: #GClosure to decrement the reference count on 574 * 575 * Decrements the reference count of a closure after it was previously 576 * incremented by the same caller. If no other callers are using the 577 * closure, then the closure will be destroyed and freed. 578 */ 579 void 580 g_closure_unref (GClosure *closure) 581 { 582 guint new_ref_count; 583 584 g_return_if_fail (closure != NULL); 585 g_return_if_fail (closure->ref_count > 0); 586 587 if (closure->ref_count == 1) /* last unref, invalidate first */ 588 g_closure_invalidate (closure); 589 590 DEC_ASSIGN (closure, ref_count, &new_ref_count); 591 592 if (new_ref_count == 0) 593 { 594 closure_invoke_notifiers (closure, FNOTIFY); 595 g_free (closure->notifiers); 596 g_free (G_REAL_CLOSURE (closure)); 597 } 598 } 599 600 /** 601 * g_closure_sink: 602 * @closure: #GClosure to decrement the initial reference count on, if it's 603 * still being held 604 * 605 * Takes over the initial ownership of a closure. Each closure is 606 * initially created in a "floating" state, which means that the initial 607 * reference count is not owned by any caller. g_closure_sink() checks 608 * to see if the object is still floating, and if so, unsets the 609 * floating state and decreases the reference count. If the closure 610 * is not floating, g_closure_sink() does nothing. The reason for the 611 * existence of the floating state is to prevent cumbersome code 612 * sequences like: 613 * |[<!-- language="C" --> 614 * closure = g_cclosure_new (cb_func, cb_data); 615 * g_source_set_closure (source, closure); 616 * g_closure_unref (closure); // GObject doesn't really need this 617 * ]| 618 * Because g_source_set_closure() (and similar functions) take ownership of the 619 * initial reference count, if it is unowned, we instead can write: 620 * |[<!-- language="C" --> 621 * g_source_set_closure (source, g_cclosure_new (cb_func, cb_data)); 622 * ]| 623 * 624 * Generally, this function is used together with g_closure_ref(). Ane example 625 * of storing a closure for later notification looks like: 626 * |[<!-- language="C" --> 627 * static GClosure *notify_closure = NULL; 628 * void 629 * foo_notify_set_closure (GClosure *closure) 630 * { 631 * if (notify_closure) 632 * g_closure_unref (notify_closure); 633 * notify_closure = closure; 634 * if (notify_closure) 635 * { 636 * g_closure_ref (notify_closure); 637 * g_closure_sink (notify_closure); 638 * } 639 * } 640 * ]| 641 * 642 * Because g_closure_sink() may decrement the reference count of a closure 643 * (if it hasn't been called on @closure yet) just like g_closure_unref(), 644 * g_closure_ref() should be called prior to this function. 645 */ 646 void 647 g_closure_sink (GClosure *closure) 648 { 649 g_return_if_fail (closure != NULL); 650 g_return_if_fail (closure->ref_count > 0); 651 652 /* floating is basically a kludge to avoid creating closures 653 * with a ref_count of 0. so the initial ref_count a closure has 654 * is unowned. with invoking g_closure_sink() code may 655 * indicate that it takes over that intiial ref_count. 656 */ 657 if (closure->floating) 658 { 659 gboolean was_floating; 660 SWAP (closure, floating, FALSE, &was_floating); 661 /* unref floating flag only once */ 662 if (was_floating) 663 g_closure_unref (closure); 664 } 665 } 666 667 /** 668 * g_closure_remove_invalidate_notifier: (skip) 669 * @closure: a #GClosure 670 * @notify_data: data which was passed to g_closure_add_invalidate_notifier() 671 * when registering @notify_func 672 * @notify_func: the callback function to remove 673 * 674 * Removes an invalidation notifier. 675 * 676 * Notice that notifiers are automatically removed after they are run. 677 */ 678 void 679 g_closure_remove_invalidate_notifier (GClosure *closure, 680 gpointer notify_data, 681 GClosureNotify notify_func) 682 { 683 g_return_if_fail (closure != NULL); 684 g_return_if_fail (notify_func != NULL); 685 686 if (closure->is_invalid && closure->in_inotify && /* account removal of notify_func() while it's called */ 687 ((gpointer) closure->marshal) == ((gpointer) notify_func) && 688 closure->data == notify_data) 689 closure->marshal = NULL; 690 else if (!closure_try_remove_inotify (closure, notify_data, notify_func)) 691 g_warning (G_STRLOC ": unable to remove uninstalled invalidation notifier: %p (%p)", 692 notify_func, notify_data); 693 } 694 695 /** 696 * g_closure_remove_finalize_notifier: (skip) 697 * @closure: a #GClosure 698 * @notify_data: data which was passed to g_closure_add_finalize_notifier() 699 * when registering @notify_func 700 * @notify_func: the callback function to remove 701 * 702 * Removes a finalization notifier. 703 * 704 * Notice that notifiers are automatically removed after they are run. 705 */ 706 void 707 g_closure_remove_finalize_notifier (GClosure *closure, 708 gpointer notify_data, 709 GClosureNotify notify_func) 710 { 711 g_return_if_fail (closure != NULL); 712 g_return_if_fail (notify_func != NULL); 713 714 if (closure->is_invalid && !closure->in_inotify && /* account removal of notify_func() while it's called */ 715 ((gpointer) closure->marshal) == ((gpointer) notify_func) && 716 closure->data == notify_data) 717 closure->marshal = NULL; 718 else if (!closure_try_remove_fnotify (closure, notify_data, notify_func)) 719 g_warning (G_STRLOC ": unable to remove uninstalled finalization notifier: %p (%p)", 720 notify_func, notify_data); 721 } 722 723 /** 724 * g_closure_invoke: 725 * @closure: a #GClosure 726 * @return_value: (allow-none): a #GValue to store the return 727 * value. May be %NULL if the callback of @closure 728 * doesn't return a value. 729 * @n_param_values: the length of the @param_values array 730 * @param_values: (array length=n_param_values): an array of 731 * #GValues holding the arguments on which to 732 * invoke the callback of @closure 733 * @invocation_hint: (allow-none): a context-dependent invocation hint 734 * 735 * Invokes the closure, i.e. executes the callback represented by the @closure. 736 */ 737 void 738 g_closure_invoke (GClosure *closure, 739 GValue /*out*/ *return_value, 740 guint n_param_values, 741 const GValue *param_values, 742 gpointer invocation_hint) 743 { 744 GRealClosure *real_closure; 745 746 g_return_if_fail (closure != NULL); 747 748 real_closure = G_REAL_CLOSURE (closure); 749 750 g_closure_ref (closure); /* preserve floating flag */ 751 if (!closure->is_invalid) 752 { 753 GClosureMarshal marshal; 754 gpointer marshal_data; 755 gboolean in_marshal = closure->in_marshal; 756 757 g_return_if_fail (closure->marshal || real_closure->meta_marshal); 758 759 SET (closure, in_marshal, TRUE); 760 if (real_closure->meta_marshal) 761 { 762 marshal_data = real_closure->meta_marshal_data; 763 marshal = real_closure->meta_marshal; 764 } 765 else 766 { 767 marshal_data = NULL; 768 marshal = closure->marshal; 769 } 770 if (!in_marshal) 771 closure_invoke_notifiers (closure, PRE_NOTIFY); 772 marshal (closure, 773 return_value, 774 n_param_values, param_values, 775 invocation_hint, 776 marshal_data); 777 if (!in_marshal) 778 closure_invoke_notifiers (closure, POST_NOTIFY); 779 SET (closure, in_marshal, in_marshal); 780 } 781 g_closure_unref (closure); 782 } 783 784 gboolean 785 _g_closure_supports_invoke_va (GClosure *closure) 786 { 787 GRealClosure *real_closure; 788 789 g_return_val_if_fail (closure != NULL, FALSE); 790 791 real_closure = G_REAL_CLOSURE (closure); 792 793 return 794 real_closure->va_marshal != NULL && 795 (real_closure->meta_marshal == NULL || 796 real_closure->va_meta_marshal != NULL); 797 } 798 799 void 800 _g_closure_invoke_va (GClosure *closure, 801 GValue /*out*/ *return_value, 802 gpointer instance, 803 va_list args, 804 int n_params, 805 GType *param_types) 806 { 807 GRealClosure *real_closure; 808 809 g_return_if_fail (closure != NULL); 810 811 real_closure = G_REAL_CLOSURE (closure); 812 813 g_closure_ref (closure); /* preserve floating flag */ 814 if (!closure->is_invalid) 815 { 816 GVaClosureMarshal marshal; 817 gpointer marshal_data; 818 gboolean in_marshal = closure->in_marshal; 819 820 g_return_if_fail (closure->marshal || real_closure->meta_marshal); 821 822 SET (closure, in_marshal, TRUE); 823 if (real_closure->va_meta_marshal) 824 { 825 marshal_data = real_closure->meta_marshal_data; 826 marshal = real_closure->va_meta_marshal; 827 } 828 else 829 { 830 marshal_data = NULL; 831 marshal = real_closure->va_marshal; 832 } 833 if (!in_marshal) 834 closure_invoke_notifiers (closure, PRE_NOTIFY); 835 marshal (closure, 836 return_value, 837 instance, args, 838 marshal_data, 839 n_params, param_types); 840 if (!in_marshal) 841 closure_invoke_notifiers (closure, POST_NOTIFY); 842 SET (closure, in_marshal, in_marshal); 843 } 844 g_closure_unref (closure); 845 } 846 847 848 /** 849 * g_closure_set_marshal: (skip) 850 * @closure: a #GClosure 851 * @marshal: a #GClosureMarshal function 852 * 853 * Sets the marshaller of @closure. The `marshal_data` 854 * of @marshal provides a way for a meta marshaller to provide additional 855 * information to the marshaller. (See g_closure_set_meta_marshal().) For 856 * GObject's C predefined marshallers (the g_cclosure_marshal_*() 857 * functions), what it provides is a callback function to use instead of 858 * @closure->callback. 859 */ 860 void 861 g_closure_set_marshal (GClosure *closure, 862 GClosureMarshal marshal) 863 { 864 g_return_if_fail (closure != NULL); 865 g_return_if_fail (marshal != NULL); 866 867 if (closure->marshal && closure->marshal != marshal) 868 g_warning ("attempt to override closure->marshal (%p) with new marshal (%p)", 869 closure->marshal, marshal); 870 else 871 closure->marshal = marshal; 872 } 873 874 void 875 _g_closure_set_va_marshal (GClosure *closure, 876 GVaClosureMarshal marshal) 877 { 878 GRealClosure *real_closure; 879 880 g_return_if_fail (closure != NULL); 881 g_return_if_fail (marshal != NULL); 882 883 real_closure = G_REAL_CLOSURE (closure); 884 885 if (real_closure->va_marshal && real_closure->va_marshal != marshal) 886 g_warning ("attempt to override closure->va_marshal (%p) with new marshal (%p)", 887 real_closure->va_marshal, marshal); 888 else 889 real_closure->va_marshal = marshal; 890 } 891 892 /** 893 * g_cclosure_new: (skip) 894 * @callback_func: the function to invoke 895 * @user_data: user data to pass to @callback_func 896 * @destroy_data: destroy notify to be called when @user_data is no longer used 897 * 898 * Creates a new closure which invokes @callback_func with @user_data as 899 * the last parameter. 900 * 901 * Returns: a new #GCClosure 902 */ 903 GClosure* 904 g_cclosure_new (GCallback callback_func, 905 gpointer user_data, 906 GClosureNotify destroy_data) 907 { 908 GClosure *closure; 909 910 g_return_val_if_fail (callback_func != NULL, NULL); 911 912 closure = g_closure_new_simple (sizeof (GCClosure), user_data); 913 if (destroy_data) 914 g_closure_add_finalize_notifier (closure, user_data, destroy_data); 915 ((GCClosure*) closure)->callback = (gpointer) callback_func; 916 917 return closure; 918 } 919 920 /** 921 * g_cclosure_new_swap: (skip) 922 * @callback_func: the function to invoke 923 * @user_data: user data to pass to @callback_func 924 * @destroy_data: destroy notify to be called when @user_data is no longer used 925 * 926 * Creates a new closure which invokes @callback_func with @user_data as 927 * the first parameter. 928 * 929 * Returns: (transfer full): a new #GCClosure 930 */ 931 GClosure* 932 g_cclosure_new_swap (GCallback callback_func, 933 gpointer user_data, 934 GClosureNotify destroy_data) 935 { 936 GClosure *closure; 937 938 g_return_val_if_fail (callback_func != NULL, NULL); 939 940 closure = g_closure_new_simple (sizeof (GCClosure), user_data); 941 if (destroy_data) 942 g_closure_add_finalize_notifier (closure, user_data, destroy_data); 943 ((GCClosure*) closure)->callback = (gpointer) callback_func; 944 SET (closure, derivative_flag, TRUE); 945 946 return closure; 947 } 948 949 static void 950 g_type_class_meta_marshal (GClosure *closure, 951 GValue /*out*/ *return_value, 952 guint n_param_values, 953 const GValue *param_values, 954 gpointer invocation_hint, 955 gpointer marshal_data) 956 { 957 GTypeClass *class; 958 gpointer callback; 959 /* GType itype = (GType) closure->data; */ 960 guint offset = GPOINTER_TO_UINT (marshal_data); 961 962 class = G_TYPE_INSTANCE_GET_CLASS (g_value_peek_pointer (param_values + 0), itype, GTypeClass); 963 callback = G_STRUCT_MEMBER (gpointer, class, offset); 964 if (callback) 965 closure->marshal (closure, 966 return_value, 967 n_param_values, param_values, 968 invocation_hint, 969 callback); 970 } 971 972 static void 973 g_type_class_meta_marshalv (GClosure *closure, 974 GValue *return_value, 975 gpointer instance, 976 va_list args, 977 gpointer marshal_data, 978 int n_params, 979 GType *param_types) 980 { 981 GRealClosure *real_closure; 982 GTypeClass *class; 983 gpointer callback; 984 /* GType itype = (GType) closure->data; */ 985 guint offset = GPOINTER_TO_UINT (marshal_data); 986 987 real_closure = G_REAL_CLOSURE (closure); 988 989 class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass); 990 callback = G_STRUCT_MEMBER (gpointer, class, offset); 991 if (callback) 992 real_closure->va_marshal (closure, 993 return_value, 994 instance, args, 995 callback, 996 n_params, 997 param_types); 998 } 999 1000 static void 1001 g_type_iface_meta_marshal (GClosure *closure, 1002 GValue /*out*/ *return_value, 1003 guint n_param_values, 1004 const GValue *param_values, 1005 gpointer invocation_hint, 1006 gpointer marshal_data) 1007 { 1008 GTypeClass *class; 1009 gpointer callback; 1010 GType itype = (GType) closure->data; 1011 guint offset = GPOINTER_TO_UINT (marshal_data); 1012 1013 class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_peek_pointer (param_values + 0), itype, GTypeClass); 1014 callback = G_STRUCT_MEMBER (gpointer, class, offset); 1015 if (callback) 1016 closure->marshal (closure, 1017 return_value, 1018 n_param_values, param_values, 1019 invocation_hint, 1020 callback); 1021 } 1022 1023 gboolean 1024 _g_closure_is_void (GClosure *closure, 1025 gpointer instance) 1026 { 1027 GRealClosure *real_closure; 1028 GTypeClass *class; 1029 gpointer callback; 1030 GType itype; 1031 guint offset; 1032 1033 if (closure->is_invalid) 1034 return TRUE; 1035 1036 real_closure = G_REAL_CLOSURE (closure); 1037 1038 if (real_closure->meta_marshal == g_type_iface_meta_marshal) 1039 { 1040 itype = (GType) closure->data; 1041 offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data); 1042 1043 class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass); 1044 callback = G_STRUCT_MEMBER (gpointer, class, offset); 1045 return callback == NULL; 1046 } 1047 else if (real_closure->meta_marshal == g_type_class_meta_marshal) 1048 { 1049 offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data); 1050 1051 class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass); 1052 callback = G_STRUCT_MEMBER (gpointer, class, offset); 1053 return callback == NULL; 1054 } 1055 1056 return FALSE; 1057 } 1058 1059 static void 1060 g_type_iface_meta_marshalv (GClosure *closure, 1061 GValue *return_value, 1062 gpointer instance, 1063 va_list args, 1064 gpointer marshal_data, 1065 int n_params, 1066 GType *param_types) 1067 { 1068 GRealClosure *real_closure; 1069 GTypeClass *class; 1070 gpointer callback; 1071 GType itype = (GType) closure->data; 1072 guint offset = GPOINTER_TO_UINT (marshal_data); 1073 1074 real_closure = G_REAL_CLOSURE (closure); 1075 1076 class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass); 1077 callback = G_STRUCT_MEMBER (gpointer, class, offset); 1078 if (callback) 1079 real_closure->va_marshal (closure, 1080 return_value, 1081 instance, args, 1082 callback, 1083 n_params, 1084 param_types); 1085 } 1086 1087 /** 1088 * g_signal_type_cclosure_new: 1089 * @itype: the #GType identifier of an interface or classed type 1090 * @struct_offset: the offset of the member function of @itype's class 1091 * structure which is to be invoked by the new closure 1092 * 1093 * Creates a new closure which invokes the function found at the offset 1094 * @struct_offset in the class structure of the interface or classed type 1095 * identified by @itype. 1096 * 1097 * Returns: a new #GCClosure 1098 */ 1099 GClosure* 1100 g_signal_type_cclosure_new (GType itype, 1101 guint struct_offset) 1102 { 1103 GClosure *closure; 1104 1105 g_return_val_if_fail (G_TYPE_IS_CLASSED (itype) || G_TYPE_IS_INTERFACE (itype), NULL); 1106 g_return_val_if_fail (struct_offset >= sizeof (GTypeClass), NULL); 1107 1108 closure = g_closure_new_simple (sizeof (GClosure), (gpointer) itype); 1109 if (G_TYPE_IS_INTERFACE (itype)) 1110 { 1111 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_iface_meta_marshal); 1112 g_closure_set_meta_va_marshal (closure, g_type_iface_meta_marshalv); 1113 } 1114 else 1115 { 1116 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_class_meta_marshal); 1117 g_closure_set_meta_va_marshal (closure, g_type_class_meta_marshalv); 1118 } 1119 return closure; 1120 } 1121 1122 #include <ffi.h> 1123 static ffi_type * 1124 value_to_ffi_type (const GValue *gvalue, 1125 gpointer *value, 1126 gint *enum_tmpval, 1127 gboolean *tmpval_used) 1128 { 1129 ffi_type *rettype = NULL; 1130 GType type = g_type_fundamental (G_VALUE_TYPE (gvalue)); 1131 g_assert (type != G_TYPE_INVALID); 1132 1133 if (enum_tmpval) 1134 { 1135 g_assert (tmpval_used != NULL); 1136 *tmpval_used = FALSE; 1137 } 1138 1139 switch (type) 1140 { 1141 case G_TYPE_BOOLEAN: 1142 case G_TYPE_CHAR: 1143 case G_TYPE_INT: 1144 rettype = &ffi_type_sint; 1145 *value = (gpointer)&(gvalue->data[0].v_int); 1146 break; 1147 case G_TYPE_ENUM: 1148 /* enums are stored in v_long even though they are integers, which makes 1149 * marshalling through libffi somewhat complicated. They need to be 1150 * marshalled as signed ints, but we need to use a temporary int sized 1151 * value to pass to libffi otherwise it'll pull the wrong value on 1152 * BE machines with 32-bit integers when treating v_long as 32-bit int. 1153 */ 1154 g_assert (enum_tmpval != NULL); 1155 rettype = &ffi_type_sint; 1156 *enum_tmpval = g_value_get_enum (gvalue); 1157 *value = enum_tmpval; 1158 *tmpval_used = TRUE; 1159 break; 1160 case G_TYPE_UCHAR: 1161 case G_TYPE_UINT: 1162 case G_TYPE_FLAGS: 1163 rettype = &ffi_type_uint; 1164 *value = (gpointer)&(gvalue->data[0].v_uint); 1165 break; 1166 case G_TYPE_STRING: 1167 case G_TYPE_OBJECT: 1168 case G_TYPE_BOXED: 1169 case G_TYPE_PARAM: 1170 case G_TYPE_POINTER: 1171 case G_TYPE_INTERFACE: 1172 case G_TYPE_VARIANT: 1173 rettype = &ffi_type_pointer; 1174 *value = (gpointer)&(gvalue->data[0].v_pointer); 1175 break; 1176 case G_TYPE_FLOAT: 1177 rettype = &ffi_type_float; 1178 *value = (gpointer)&(gvalue->data[0].v_float); 1179 break; 1180 case G_TYPE_DOUBLE: 1181 rettype = &ffi_type_double; 1182 *value = (gpointer)&(gvalue->data[0].v_double); 1183 break; 1184 case G_TYPE_LONG: 1185 rettype = &ffi_type_slong; 1186 *value = (gpointer)&(gvalue->data[0].v_long); 1187 break; 1188 case G_TYPE_ULONG: 1189 rettype = &ffi_type_ulong; 1190 *value = (gpointer)&(gvalue->data[0].v_ulong); 1191 break; 1192 case G_TYPE_INT64: 1193 rettype = &ffi_type_sint64; 1194 *value = (gpointer)&(gvalue->data[0].v_int64); 1195 break; 1196 case G_TYPE_UINT64: 1197 rettype = &ffi_type_uint64; 1198 *value = (gpointer)&(gvalue->data[0].v_uint64); 1199 break; 1200 default: 1201 rettype = &ffi_type_pointer; 1202 *value = NULL; 1203 g_warning ("value_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type)); 1204 break; 1205 } 1206 return rettype; 1207 } 1208 1209 static void 1210 value_from_ffi_type (GValue *gvalue, gpointer *value) 1211 { 1212 ffi_arg *int_val = (ffi_arg*) value; 1213 1214 switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) 1215 { 1216 case G_TYPE_INT: 1217 g_value_set_int (gvalue, (gint) *int_val); 1218 break; 1219 case G_TYPE_FLOAT: 1220 g_value_set_float (gvalue, *(gfloat*)value); 1221 break; 1222 case G_TYPE_DOUBLE: 1223 g_value_set_double (gvalue, *(gdouble*)value); 1224 break; 1225 case G_TYPE_BOOLEAN: 1226 g_value_set_boolean (gvalue, (gboolean) *int_val); 1227 break; 1228 case G_TYPE_STRING: 1229 g_value_take_string (gvalue, *(gchar**)value); 1230 break; 1231 case G_TYPE_CHAR: 1232 g_value_set_schar (gvalue, (gint8) *int_val); 1233 break; 1234 case G_TYPE_UCHAR: 1235 g_value_set_uchar (gvalue, (guchar) *int_val); 1236 break; 1237 case G_TYPE_UINT: 1238 g_value_set_uint (gvalue, (guint) *int_val); 1239 break; 1240 case G_TYPE_POINTER: 1241 g_value_set_pointer (gvalue, *(gpointer*)value); 1242 break; 1243 case G_TYPE_LONG: 1244 g_value_set_long (gvalue, (glong) *int_val); 1245 break; 1246 case G_TYPE_ULONG: 1247 g_value_set_ulong (gvalue, (gulong) *int_val); 1248 break; 1249 case G_TYPE_INT64: 1250 g_value_set_int64 (gvalue, (gint64) *int_val); 1251 break; 1252 case G_TYPE_UINT64: 1253 g_value_set_uint64 (gvalue, (guint64) *int_val); 1254 break; 1255 case G_TYPE_BOXED: 1256 g_value_take_boxed (gvalue, *(gpointer*)value); 1257 break; 1258 case G_TYPE_ENUM: 1259 g_value_set_enum (gvalue, (gint) *int_val); 1260 break; 1261 case G_TYPE_FLAGS: 1262 g_value_set_flags (gvalue, (guint) *int_val); 1263 break; 1264 case G_TYPE_PARAM: 1265 g_value_take_param (gvalue, *(gpointer*)value); 1266 break; 1267 case G_TYPE_OBJECT: 1268 g_value_take_object (gvalue, *(gpointer*)value); 1269 break; 1270 case G_TYPE_VARIANT: 1271 g_value_take_variant (gvalue, *(gpointer*)value); 1272 break; 1273 default: 1274 g_warning ("value_from_ffi_type: Unsupported fundamental type: %s", 1275 g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue)))); 1276 } 1277 } 1278 1279 typedef union { 1280 gpointer _gpointer; 1281 float _float; 1282 double _double; 1283 gint _gint; 1284 guint _guint; 1285 glong _glong; 1286 gulong _gulong; 1287 gint64 _gint64; 1288 guint64 _guint64; 1289 } va_arg_storage; 1290 1291 static ffi_type * 1292 va_to_ffi_type (GType gtype, 1293 va_list *va, 1294 va_arg_storage *storage) 1295 { 1296 ffi_type *rettype = NULL; 1297 GType type = g_type_fundamental (gtype); 1298 g_assert (type != G_TYPE_INVALID); 1299 1300 switch (type) 1301 { 1302 case G_TYPE_BOOLEAN: 1303 case G_TYPE_CHAR: 1304 case G_TYPE_INT: 1305 case G_TYPE_ENUM: 1306 rettype = &ffi_type_sint; 1307 storage->_gint = va_arg (*va, gint); 1308 break; 1309 case G_TYPE_UCHAR: 1310 case G_TYPE_UINT: 1311 case G_TYPE_FLAGS: 1312 rettype = &ffi_type_uint; 1313 storage->_guint = va_arg (*va, guint); 1314 break; 1315 case G_TYPE_STRING: 1316 case G_TYPE_OBJECT: 1317 case G_TYPE_BOXED: 1318 case G_TYPE_PARAM: 1319 case G_TYPE_POINTER: 1320 case G_TYPE_INTERFACE: 1321 case G_TYPE_VARIANT: 1322 rettype = &ffi_type_pointer; 1323 storage->_gpointer = va_arg (*va, gpointer); 1324 break; 1325 case G_TYPE_FLOAT: 1326 /* Float args are passed as doubles in varargs */ 1327 rettype = &ffi_type_float; 1328 storage->_float = (float)va_arg (*va, double); 1329 break; 1330 case G_TYPE_DOUBLE: 1331 rettype = &ffi_type_double; 1332 storage->_double = va_arg (*va, double); 1333 break; 1334 case G_TYPE_LONG: 1335 rettype = &ffi_type_slong; 1336 storage->_glong = va_arg (*va, glong); 1337 break; 1338 case G_TYPE_ULONG: 1339 rettype = &ffi_type_ulong; 1340 storage->_gulong = va_arg (*va, gulong); 1341 break; 1342 case G_TYPE_INT64: 1343 rettype = &ffi_type_sint64; 1344 storage->_gint64 = va_arg (*va, gint64); 1345 break; 1346 case G_TYPE_UINT64: 1347 rettype = &ffi_type_uint64; 1348 storage->_guint64 = va_arg (*va, guint64); 1349 break; 1350 default: 1351 rettype = &ffi_type_pointer; 1352 storage->_guint64 = 0; 1353 g_warning ("va_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type)); 1354 break; 1355 } 1356 return rettype; 1357 } 1358 1359 /** 1360 * g_cclosure_marshal_generic: 1361 * @closure: A #GClosure. 1362 * @return_gvalue: A #GValue to store the return value. May be %NULL 1363 * if the callback of closure doesn't return a value. 1364 * @n_param_values: The length of the @param_values array. 1365 * @param_values: An array of #GValues holding the arguments 1366 * on which to invoke the callback of closure. 1367 * @invocation_hint: The invocation hint given as the last argument to 1368 * g_closure_invoke(). 1369 * @marshal_data: Additional data specified when registering the 1370 * marshaller, see g_closure_set_marshal() and 1371 * g_closure_set_meta_marshal() 1372 * 1373 * A generic marshaller function implemented via 1374 * [libffi](http://sourceware.org/libffi/). 1375 * 1376 * Normally this function is not passed explicitly to g_signal_new(), 1377 * but used automatically by GLib when specifying a %NULL marshaller. 1378 * 1379 * Since: 2.30 1380 */ 1381 void 1382 g_cclosure_marshal_generic (GClosure *closure, 1383 GValue *return_gvalue, 1384 guint n_param_values, 1385 const GValue *param_values, 1386 gpointer invocation_hint, 1387 gpointer marshal_data) 1388 { 1389 ffi_type *rtype; 1390 void *rvalue; 1391 int n_args; 1392 ffi_type **atypes; 1393 void **args; 1394 int i; 1395 ffi_cif cif; 1396 GCClosure *cc = (GCClosure*) closure; 1397 gint *enum_tmpval; 1398 gboolean tmpval_used = FALSE; 1399 1400 enum_tmpval = g_alloca (sizeof (gint)); 1401 if (return_gvalue && G_VALUE_TYPE (return_gvalue)) 1402 { 1403 rtype = value_to_ffi_type (return_gvalue, &rvalue, enum_tmpval, &tmpval_used); 1404 } 1405 else 1406 { 1407 rtype = &ffi_type_void; 1408 } 1409 1410 rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); 1411 1412 n_args = n_param_values + 1; 1413 atypes = g_alloca (sizeof (ffi_type *) * n_args); 1414 args = g_alloca (sizeof (gpointer) * n_args); 1415 1416 if (tmpval_used) 1417 enum_tmpval = g_alloca (sizeof (gint)); 1418 1419 if (G_CCLOSURE_SWAP_DATA (closure)) 1420 { 1421 atypes[n_args-1] = value_to_ffi_type (param_values + 0, 1422 &args[n_args-1], 1423 enum_tmpval, 1424 &tmpval_used); 1425 atypes[0] = &ffi_type_pointer; 1426 args[0] = &closure->data; 1427 } 1428 else 1429 { 1430 atypes[0] = value_to_ffi_type (param_values + 0, 1431 &args[0], 1432 enum_tmpval, 1433 &tmpval_used); 1434 atypes[n_args-1] = &ffi_type_pointer; 1435 args[n_args-1] = &closure->data; 1436 } 1437 1438 for (i = 1; i < n_args - 1; i++) 1439 { 1440 if (tmpval_used) 1441 enum_tmpval = g_alloca (sizeof (gint)); 1442 1443 atypes[i] = value_to_ffi_type (param_values + i, 1444 &args[i], 1445 enum_tmpval, 1446 &tmpval_used); 1447 } 1448 1449 if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) 1450 return; 1451 1452 ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); 1453 1454 if (return_gvalue && G_VALUE_TYPE (return_gvalue)) 1455 value_from_ffi_type (return_gvalue, rvalue); 1456 } 1457 1458 void 1459 g_cclosure_marshal_generic_va (GClosure *closure, 1460 GValue *return_value, 1461 gpointer instance, 1462 va_list args_list, 1463 gpointer marshal_data, 1464 int n_params, 1465 GType *param_types) 1466 { 1467 ffi_type *rtype; 1468 void *rvalue; 1469 int n_args; 1470 ffi_type **atypes; 1471 void **args; 1472 va_arg_storage *storage; 1473 int i; 1474 ffi_cif cif; 1475 GCClosure *cc = (GCClosure*) closure; 1476 gint *enum_tmpval; 1477 gboolean tmpval_used = FALSE; 1478 va_list args_copy; 1479 1480 enum_tmpval = g_alloca (sizeof (gint)); 1481 if (return_value && G_VALUE_TYPE (return_value)) 1482 { 1483 rtype = value_to_ffi_type (return_value, &rvalue, enum_tmpval, &tmpval_used); 1484 } 1485 else 1486 { 1487 rtype = &ffi_type_void; 1488 } 1489 1490 rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); 1491 1492 n_args = n_params + 2; 1493 atypes = g_alloca (sizeof (ffi_type *) * n_args); 1494 args = g_alloca (sizeof (gpointer) * n_args); 1495 storage = g_alloca (sizeof (va_arg_storage) * n_params); 1496 1497 if (G_CCLOSURE_SWAP_DATA (closure)) 1498 { 1499 atypes[n_args-1] = &ffi_type_pointer; 1500 args[n_args-1] = &instance; 1501 atypes[0] = &ffi_type_pointer; 1502 args[0] = &closure->data; 1503 } 1504 else 1505 { 1506 atypes[0] = &ffi_type_pointer; 1507 args[0] = &instance; 1508 atypes[n_args-1] = &ffi_type_pointer; 1509 args[n_args-1] = &closure->data; 1510 } 1511 1512 G_VA_COPY (args_copy, args_list); 1513 1514 /* Box non-primitive arguments */ 1515 for (i = 0; i < n_params; i++) 1516 { 1517 GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; 1518 GType fundamental = G_TYPE_FUNDAMENTAL (type); 1519 1520 atypes[i+1] = va_to_ffi_type (type, 1521 &args_copy, 1522 &storage[i]); 1523 args[i+1] = &storage[i]; 1524 1525 if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0) 1526 { 1527 if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL) 1528 storage[i]._gpointer = g_strdup (storage[i]._gpointer); 1529 else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL) 1530 storage[i]._gpointer = g_param_spec_ref (storage[i]._gpointer); 1531 else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL) 1532 storage[i]._gpointer = g_boxed_copy (type, storage[i]._gpointer); 1533 else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL) 1534 storage[i]._gpointer = g_variant_ref_sink (storage[i]._gpointer); 1535 } 1536 if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL) 1537 storage[i]._gpointer = g_object_ref (storage[i]._gpointer); 1538 } 1539 1540 va_end (args_copy); 1541 1542 if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) 1543 return; 1544 1545 ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); 1546 1547 /* Unbox non-primitive arguments */ 1548 for (i = 0; i < n_params; i++) 1549 { 1550 GType type = param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; 1551 GType fundamental = G_TYPE_FUNDAMENTAL (type); 1552 1553 if ((param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0) 1554 { 1555 if (fundamental == G_TYPE_STRING && storage[i]._gpointer != NULL) 1556 g_free (storage[i]._gpointer); 1557 else if (fundamental == G_TYPE_PARAM && storage[i]._gpointer != NULL) 1558 g_param_spec_unref (storage[i]._gpointer); 1559 else if (fundamental == G_TYPE_BOXED && storage[i]._gpointer != NULL) 1560 g_boxed_free (type, storage[i]._gpointer); 1561 else if (fundamental == G_TYPE_VARIANT && storage[i]._gpointer != NULL) 1562 g_variant_unref (storage[i]._gpointer); 1563 } 1564 if (fundamental == G_TYPE_OBJECT && storage[i]._gpointer != NULL) 1565 g_object_unref (storage[i]._gpointer); 1566 } 1567 1568 if (return_value && G_VALUE_TYPE (return_value)) 1569 value_from_ffi_type (return_value, rvalue); 1570 } 1571 1572 /** 1573 * g_cclosure_marshal_VOID__VOID: 1574 * @closure: the #GClosure to which the marshaller belongs 1575 * @return_value: ignored 1576 * @n_param_values: 1 1577 * @param_values: a #GValue array holding only the instance 1578 * @invocation_hint: the invocation hint given as the last argument 1579 * to g_closure_invoke() 1580 * @marshal_data: additional data specified when registering the marshaller 1581 * 1582 * A marshaller for a #GCClosure with a callback of type 1583 * `void (*callback) (gpointer instance, gpointer user_data)`. 1584 */ 1585 1586 /** 1587 * g_cclosure_marshal_VOID__BOOLEAN: 1588 * @closure: the #GClosure to which the marshaller belongs 1589 * @return_value: ignored 1590 * @n_param_values: 2 1591 * @param_values: a #GValue array holding the instance and the #gboolean parameter 1592 * @invocation_hint: the invocation hint given as the last argument 1593 * to g_closure_invoke() 1594 * @marshal_data: additional data specified when registering the marshaller 1595 * 1596 * A marshaller for a #GCClosure with a callback of type 1597 * `void (*callback) (gpointer instance, gboolean arg1, gpointer user_data)`. 1598 */ 1599 1600 /** 1601 * g_cclosure_marshal_VOID__CHAR: 1602 * @closure: the #GClosure to which the marshaller belongs 1603 * @return_value: ignored 1604 * @n_param_values: 2 1605 * @param_values: a #GValue array holding the instance and the #gchar parameter 1606 * @invocation_hint: the invocation hint given as the last argument 1607 * to g_closure_invoke() 1608 * @marshal_data: additional data specified when registering the marshaller 1609 * 1610 * A marshaller for a #GCClosure with a callback of type 1611 * `void (*callback) (gpointer instance, gchar arg1, gpointer user_data)`. 1612 */ 1613 1614 /** 1615 * g_cclosure_marshal_VOID__UCHAR: 1616 * @closure: the #GClosure to which the marshaller belongs 1617 * @return_value: ignored 1618 * @n_param_values: 2 1619 * @param_values: a #GValue array holding the instance and the #guchar parameter 1620 * @invocation_hint: the invocation hint given as the last argument 1621 * to g_closure_invoke() 1622 * @marshal_data: additional data specified when registering the marshaller 1623 * 1624 * A marshaller for a #GCClosure with a callback of type 1625 * `void (*callback) (gpointer instance, guchar arg1, gpointer user_data)`. 1626 */ 1627 1628 /** 1629 * g_cclosure_marshal_VOID__INT: 1630 * @closure: the #GClosure to which the marshaller belongs 1631 * @return_value: ignored 1632 * @n_param_values: 2 1633 * @param_values: a #GValue array holding the instance and the #gint parameter 1634 * @invocation_hint: the invocation hint given as the last argument 1635 * to g_closure_invoke() 1636 * @marshal_data: additional data specified when registering the marshaller 1637 * 1638 * A marshaller for a #GCClosure with a callback of type 1639 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)`. 1640 */ 1641 1642 /** 1643 * g_cclosure_marshal_VOID__UINT: 1644 * @closure: the #GClosure to which the marshaller belongs 1645 * @return_value: ignored 1646 * @n_param_values: 2 1647 * @param_values: a #GValue array holding the instance and the #guint parameter 1648 * @invocation_hint: the invocation hint given as the last argument 1649 * to g_closure_invoke() 1650 * @marshal_data: additional data specified when registering the marshaller 1651 * 1652 * A marshaller for a #GCClosure with a callback of type 1653 * `void (*callback) (gpointer instance, guint arg1, gpointer user_data)`. 1654 */ 1655 1656 /** 1657 * g_cclosure_marshal_VOID__LONG: 1658 * @closure: the #GClosure to which the marshaller belongs 1659 * @return_value: ignored 1660 * @n_param_values: 2 1661 * @param_values: a #GValue array holding the instance and the #glong parameter 1662 * @invocation_hint: the invocation hint given as the last argument 1663 * to g_closure_invoke() 1664 * @marshal_data: additional data specified when registering the marshaller 1665 * 1666 * A marshaller for a #GCClosure with a callback of type 1667 * `void (*callback) (gpointer instance, glong arg1, gpointer user_data)`. 1668 */ 1669 1670 /** 1671 * g_cclosure_marshal_VOID__ULONG: 1672 * @closure: the #GClosure to which the marshaller belongs 1673 * @return_value: ignored 1674 * @n_param_values: 2 1675 * @param_values: a #GValue array holding the instance and the #gulong parameter 1676 * @invocation_hint: the invocation hint given as the last argument 1677 * to g_closure_invoke() 1678 * @marshal_data: additional data specified when registering the marshaller 1679 * 1680 * A marshaller for a #GCClosure with a callback of type 1681 * `void (*callback) (gpointer instance, gulong arg1, gpointer user_data)`. 1682 */ 1683 1684 /** 1685 * g_cclosure_marshal_VOID__ENUM: 1686 * @closure: the #GClosure to which the marshaller belongs 1687 * @return_value: ignored 1688 * @n_param_values: 2 1689 * @param_values: a #GValue array holding the instance and the enumeration parameter 1690 * @invocation_hint: the invocation hint given as the last argument 1691 * to g_closure_invoke() 1692 * @marshal_data: additional data specified when registering the marshaller 1693 * 1694 * A marshaller for a #GCClosure with a callback of type 1695 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes an enumeration type.. 1696 */ 1697 1698 /** 1699 * g_cclosure_marshal_VOID__FLAGS: 1700 * @closure: the #GClosure to which the marshaller belongs 1701 * @return_value: ignored 1702 * @n_param_values: 2 1703 * @param_values: a #GValue array holding the instance and the flags parameter 1704 * @invocation_hint: the invocation hint given as the last argument 1705 * to g_closure_invoke() 1706 * @marshal_data: additional data specified when registering the marshaller 1707 * 1708 * A marshaller for a #GCClosure with a callback of type 1709 * `void (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter denotes a flags type. 1710 */ 1711 1712 /** 1713 * g_cclosure_marshal_VOID__FLOAT: 1714 * @closure: the #GClosure to which the marshaller belongs 1715 * @return_value: ignored 1716 * @n_param_values: 2 1717 * @param_values: a #GValue array holding the instance and the #gfloat parameter 1718 * @invocation_hint: the invocation hint given as the last argument 1719 * to g_closure_invoke() 1720 * @marshal_data: additional data specified when registering the marshaller 1721 * 1722 * A marshaller for a #GCClosure with a callback of type 1723 * `void (*callback) (gpointer instance, gfloat arg1, gpointer user_data)`. 1724 */ 1725 1726 /** 1727 * g_cclosure_marshal_VOID__DOUBLE: 1728 * @closure: the #GClosure to which the marshaller belongs 1729 * @return_value: ignored 1730 * @n_param_values: 2 1731 * @param_values: a #GValue array holding the instance and the #gdouble parameter 1732 * @invocation_hint: the invocation hint given as the last argument 1733 * to g_closure_invoke() 1734 * @marshal_data: additional data specified when registering the marshaller 1735 * 1736 * A marshaller for a #GCClosure with a callback of type 1737 * `void (*callback) (gpointer instance, gdouble arg1, gpointer user_data)`. 1738 */ 1739 1740 /** 1741 * g_cclosure_marshal_VOID__STRING: 1742 * @closure: the #GClosure to which the marshaller belongs 1743 * @return_value: ignored 1744 * @n_param_values: 2 1745 * @param_values: a #GValue array holding the instance and the #gchar* parameter 1746 * @invocation_hint: the invocation hint given as the last argument 1747 * to g_closure_invoke() 1748 * @marshal_data: additional data specified when registering the marshaller 1749 * 1750 * A marshaller for a #GCClosure with a callback of type 1751 * `void (*callback) (gpointer instance, const gchar *arg1, gpointer user_data)`. 1752 */ 1753 1754 /** 1755 * g_cclosure_marshal_VOID__PARAM: 1756 * @closure: the #GClosure to which the marshaller belongs 1757 * @return_value: ignored 1758 * @n_param_values: 2 1759 * @param_values: a #GValue array holding the instance and the #GParamSpec* parameter 1760 * @invocation_hint: the invocation hint given as the last argument 1761 * to g_closure_invoke() 1762 * @marshal_data: additional data specified when registering the marshaller 1763 * 1764 * A marshaller for a #GCClosure with a callback of type 1765 * `void (*callback) (gpointer instance, GParamSpec *arg1, gpointer user_data)`. 1766 */ 1767 1768 /** 1769 * g_cclosure_marshal_VOID__BOXED: 1770 * @closure: the #GClosure to which the marshaller belongs 1771 * @return_value: ignored 1772 * @n_param_values: 2 1773 * @param_values: a #GValue array holding the instance and the #GBoxed* parameter 1774 * @invocation_hint: the invocation hint given as the last argument 1775 * to g_closure_invoke() 1776 * @marshal_data: additional data specified when registering the marshaller 1777 * 1778 * A marshaller for a #GCClosure with a callback of type 1779 * `void (*callback) (gpointer instance, GBoxed *arg1, gpointer user_data)`. 1780 */ 1781 1782 /** 1783 * g_cclosure_marshal_VOID__POINTER: 1784 * @closure: the #GClosure to which the marshaller belongs 1785 * @return_value: ignored 1786 * @n_param_values: 2 1787 * @param_values: a #GValue array holding the instance and the #gpointer parameter 1788 * @invocation_hint: the invocation hint given as the last argument 1789 * to g_closure_invoke() 1790 * @marshal_data: additional data specified when registering the marshaller 1791 * 1792 * A marshaller for a #GCClosure with a callback of type 1793 * `void (*callback) (gpointer instance, gpointer arg1, gpointer user_data)`. 1794 */ 1795 1796 /** 1797 * g_cclosure_marshal_VOID__OBJECT: 1798 * @closure: the #GClosure to which the marshaller belongs 1799 * @return_value: ignored 1800 * @n_param_values: 2 1801 * @param_values: a #GValue array holding the instance and the #GObject* parameter 1802 * @invocation_hint: the invocation hint given as the last argument 1803 * to g_closure_invoke() 1804 * @marshal_data: additional data specified when registering the marshaller 1805 * 1806 * A marshaller for a #GCClosure with a callback of type 1807 * `void (*callback) (gpointer instance, GObject *arg1, gpointer user_data)`. 1808 */ 1809 1810 /** 1811 * g_cclosure_marshal_VOID__VARIANT: 1812 * @closure: the #GClosure to which the marshaller belongs 1813 * @return_value: ignored 1814 * @n_param_values: 2 1815 * @param_values: a #GValue array holding the instance and the #GVariant* parameter 1816 * @invocation_hint: the invocation hint given as the last argument 1817 * to g_closure_invoke() 1818 * @marshal_data: additional data specified when registering the marshaller 1819 * 1820 * A marshaller for a #GCClosure with a callback of type 1821 * `void (*callback) (gpointer instance, GVariant *arg1, gpointer user_data)`. 1822 * 1823 * Since: 2.26 1824 */ 1825 1826 /** 1827 * g_cclosure_marshal_VOID__UINT_POINTER: 1828 * @closure: the #GClosure to which the marshaller belongs 1829 * @return_value: ignored 1830 * @n_param_values: 3 1831 * @param_values: a #GValue array holding instance, arg1 and arg2 1832 * @invocation_hint: the invocation hint given as the last argument 1833 * to g_closure_invoke() 1834 * @marshal_data: additional data specified when registering the marshaller 1835 * 1836 * A marshaller for a #GCClosure with a callback of type 1837 * `void (*callback) (gpointer instance, guint arg1, gpointer arg2, gpointer user_data)`. 1838 */ 1839 1840 /** 1841 * g_cclosure_marshal_BOOLEAN__FLAGS: 1842 * @closure: the #GClosure to which the marshaller belongs 1843 * @return_value: a #GValue which can store the returned #gboolean 1844 * @n_param_values: 2 1845 * @param_values: a #GValue array holding instance and arg1 1846 * @invocation_hint: the invocation hint given as the last argument 1847 * to g_closure_invoke() 1848 * @marshal_data: additional data specified when registering the marshaller 1849 * 1850 * A marshaller for a #GCClosure with a callback of type 1851 * `gboolean (*callback) (gpointer instance, gint arg1, gpointer user_data)` where the #gint parameter 1852 * denotes a flags type. 1853 */ 1854 1855 /** 1856 * g_cclosure_marshal_BOOL__FLAGS: 1857 * 1858 * Another name for g_cclosure_marshal_BOOLEAN__FLAGS(). 1859 */ 1860 /** 1861 * g_cclosure_marshal_STRING__OBJECT_POINTER: 1862 * @closure: the #GClosure to which the marshaller belongs 1863 * @return_value: a #GValue, which can store the returned string 1864 * @n_param_values: 3 1865 * @param_values: a #GValue array holding instance, arg1 and arg2 1866 * @invocation_hint: the invocation hint given as the last argument 1867 * to g_closure_invoke() 1868 * @marshal_data: additional data specified when registering the marshaller 1869 * 1870 * A marshaller for a #GCClosure with a callback of type 1871 * `gchar* (*callback) (gpointer instance, GObject *arg1, gpointer arg2, gpointer user_data)`. 1872 */ 1873 /** 1874 * g_cclosure_marshal_BOOLEAN__OBJECT_BOXED_BOXED: 1875 * @closure: the #GClosure to which the marshaller belongs 1876 * @return_value: a #GValue, which can store the returned string 1877 * @n_param_values: 3 1878 * @param_values: a #GValue array holding instance, arg1 and arg2 1879 * @invocation_hint: the invocation hint given as the last argument 1880 * to g_closure_invoke() 1881 * @marshal_data: additional data specified when registering the marshaller 1882 * 1883 * A marshaller for a #GCClosure with a callback of type 1884 * `gboolean (*callback) (gpointer instance, GBoxed *arg1, GBoxed *arg2, gpointer user_data)`. 1885 * 1886 * Since: 2.26 1887 */