1 /* GIO - GLib Input, Output and Streaming Library 2 * 3 * Copyright (C) 2006-2007 Red Hat, Inc. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General 16 * Public License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 18 * Boston, MA 02111-1307, USA. 19 * 20 * Author: Alexander Larsson <alexl (at) redhat.com> 21 */ 22 23 #include "config.h" 24 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <string.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #ifdef HAVE_UNISTD_H 31 #include <unistd.h> 32 #endif 33 34 #include "gsimpleasyncresult.h" 35 #include "gasyncresult.h" 36 #include "gcancellable.h" 37 #include "gioscheduler.h" 38 #include <gio/gioerror.h> 39 #include "glibintl.h" 40 41 #include "gioalias.h" 42 43 /** 44 * SECTION:gsimpleasyncresult 45 * @short_description: Simple asynchronous results implementation 46 * @include: gio/gio.h 47 * @see_also: #GAsyncResult 48 * 49 * Implements #GAsyncResult for simple cases. Most of the time, this 50 * will be all an application needs, and will be used transparently. 51 * Because of this, #GSimpleAsyncResult is used throughout GIO for 52 * handling asynchronous functions. 53 * 54 * GSimpleAsyncResult handles #GAsyncReadyCallback<!-- -->s, error 55 * reporting, operation cancellation and the final state of an operation, 56 * completely transparent to the application. Results can be returned 57 * as a pointer e.g. for functions that return data that is collected 58 * asynchronously, a boolean value for checking the success or failure 59 * of an operation, or a #gssize for operations which return the number 60 * of bytes modified by the operation; all of the simple return cases 61 * are covered. 62 * 63 * Most of the time, an application will not need to know of the details 64 * of this API; it is handled transparently, and any necessary operations 65 * are handled by #GAsyncResult's interface. However, if implementing a 66 * new GIO module, for writing language bindings, or for complex 67 * applications that need better control of how asynchronous operations 68 * are completed, it is important to understand this functionality. 69 * 70 * GSimpleAsyncResults are tagged with the calling function to ensure 71 * that asynchronous functions and their finishing functions are used 72 * together correctly. 73 * 74 * To create a new #GSimpleAsyncResult, call g_simple_async_result_new(). 75 * If the result needs to be created for a #GError, use 76 * g_simple_async_result_new_from_error(). If a #GError is not available 77 * (e.g. the asynchronous operation's doesn't take a #GError argument), 78 * but the result still needs to be created for an error condition, use 79 * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va() 80 * if your application or binding requires passing a variable argument list 81 * directly), and the error can then be propegated through the use of 82 * g_simple_async_result_propagate_error(). 83 * 84 * An asynchronous operation can be made to ignore a cancellation event by 85 * calling g_simple_async_result_set_handle_cancellation() with a 86 * #GSimpleAsyncResult for the operation and %FALSE. This is useful for 87 * operations that are dangerous to cancel, such as close (which would 88 * cause a leak if cancelled before being run). 89 * 90 * GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop, 91 * or it can use #GThread<!-- -->s if available. 92 * g_simple_async_result_complete() will finish an I/O task directly within 93 * the main event loop. g_simple_async_result_complete_in_idle() will 94 * integrate the I/O task into the main event loop as an idle function and 95 * g_simple_async_result_run_in_thread() will run the job in a separate 96 * thread. 97 * 98 * To set the results of an asynchronous function, 99 * g_simple_async_result_set_op_res_gpointer(), 100 * g_simple_async_result_set_op_res_gboolean(), and 101 * g_simple_async_result_set_op_res_gssize() 102 * are provided, setting the operation's result to a gpointer, gboolean, or 103 * gssize, respectively. 104 * 105 * Likewise, to get the result of an asynchronous function, 106 * g_simple_async_result_get_op_res_gpointer(), 107 * g_simple_async_result_get_op_res_gboolean(), and 108 * g_simple_async_result_get_op_res_gssize() are 109 * provided, getting the operation's result as a gpointer, gboolean, and 110 * gssize, respectively. 111 **/ 112 113 static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface); 114 115 struct _GSimpleAsyncResult 116 { 117 GObject parent_instance; 118 119 GObject *source_object; 120 GAsyncReadyCallback callback; 121 gpointer user_data; 122 GError *error; 123 gboolean failed; 124 gboolean handle_cancellation; 125 126 gpointer source_tag; 127 128 union { 129 gpointer v_pointer; 130 gboolean v_boolean; 131 gssize v_ssize; 132 } op_res; 133 134 GDestroyNotify destroy_op_res; 135 }; 136 137 struct _GSimpleAsyncResultClass 138 { 139 GObjectClass parent_class; 140 }; 141 142 143 G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT, 144 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, 145 g_simple_async_result_async_result_iface_init)) 146 147 static void 148 g_simple_async_result_finalize (GObject *object) 149 { 150 GSimpleAsyncResult *simple; 151 152 simple = G_SIMPLE_ASYNC_RESULT (object); 153 154 if (simple->source_object) 155 g_object_unref (simple->source_object); 156 157 if (simple->destroy_op_res) 158 simple->destroy_op_res (simple->op_res.v_pointer); 159 160 if (simple->error) 161 g_error_free (simple->error); 162 163 G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object); 164 } 165 166 static void 167 g_simple_async_result_class_init (GSimpleAsyncResultClass *klass) 168 { 169 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 170 171 gobject_class->finalize = g_simple_async_result_finalize; 172 } 173 174 static void 175 g_simple_async_result_init (GSimpleAsyncResult *simple) 176 { 177 simple->handle_cancellation = TRUE; 178 } 179 180 /** 181 * g_simple_async_result_new: 182 * @source_object: a #GObject the asynchronous function was called with, 183 * or %NULL. 184 * @callback: a #GAsyncReadyCallback. 185 * @user_data: user data passed to @callback. 186 * @source_tag: the asynchronous function. 187 * 188 * Creates a #GSimpleAsyncResult. 189 * 190 * Returns: a #GSimpleAsyncResult. 191 **/ 192 GSimpleAsyncResult * 193 g_simple_async_result_new (GObject *source_object, 194 GAsyncReadyCallback callback, 195 gpointer user_data, 196 gpointer source_tag) 197 { 198 GSimpleAsyncResult *simple; 199 200 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); 201 202 simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL); 203 simple->callback = callback; 204 if (source_object) 205 simple->source_object = g_object_ref (source_object); 206 else 207 simple->source_object = NULL; 208 simple->user_data = user_data; 209 simple->source_tag = source_tag; 210 211 return simple; 212 } 213 214 /** 215 * g_simple_async_result_new_from_error: 216 * @source_object: a #GObject, or %NULL. 217 * @callback: a #GAsyncReadyCallback. 218 * @user_data: user data passed to @callback. 219 * @error: a #GError location. 220 * 221 * Creates a #GSimpleAsyncResult from an error condition. 222 * 223 * Returns: a #GSimpleAsyncResult. 224 **/ 225 GSimpleAsyncResult * 226 g_simple_async_result_new_from_error (GObject *source_object, 227 GAsyncReadyCallback callback, 228 gpointer user_data, 229 GError *error) 230 { 231 GSimpleAsyncResult *simple; 232 233 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); 234 235 simple = g_simple_async_result_new (source_object, 236 callback, 237 user_data, NULL); 238 g_simple_async_result_set_from_error (simple, error); 239 240 return simple; 241 } 242 243 /** 244 * g_simple_async_result_new_error: 245 * @source_object: a #GObject, or %NULL. 246 * @callback: a #GAsyncReadyCallback. 247 * @user_data: user data passed to @callback. 248 * @domain: a #GQuark. 249 * @code: an error code. 250 * @format: a string with format characters. 251 * @...: a list of values to insert into @format. 252 * 253 * Creates a new #GSimpleAsyncResult with a set error. 254 * 255 * Returns: a #GSimpleAsyncResult. 256 **/ 257 GSimpleAsyncResult * 258 g_simple_async_result_new_error (GObject *source_object, 259 GAsyncReadyCallback callback, 260 gpointer user_data, 261 GQuark domain, 262 gint code, 263 const char *format, 264 ...) 265 { 266 GSimpleAsyncResult *simple; 267 va_list args; 268 269 g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL); 270 g_return_val_if_fail (domain != 0, NULL); 271 g_return_val_if_fail (format != NULL, NULL); 272 273 simple = g_simple_async_result_new (source_object, 274 callback, 275 user_data, NULL); 276 277 va_start (args, format); 278 g_simple_async_result_set_error_va (simple, domain, code, format, args); 279 va_end (args); 280 281 return simple; 282 } 283 284 285 static gpointer 286 g_simple_async_result_get_user_data (GAsyncResult *res) 287 { 288 return G_SIMPLE_ASYNC_RESULT (res)->user_data; 289 } 290 291 static GObject * 292 g_simple_async_result_get_source_object (GAsyncResult *res) 293 { 294 if (G_SIMPLE_ASYNC_RESULT (res)->source_object) 295 return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object); 296 return NULL; 297 } 298 299 static void 300 g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface) 301 { 302 iface->get_user_data = g_simple_async_result_get_user_data; 303 iface->get_source_object = g_simple_async_result_get_source_object; 304 } 305 306 /** 307 * g_simple_async_result_set_handle_cancellation: 308 * @simple: a #GSimpleAsyncResult. 309 * @handle_cancellation: a #gboolean. 310 * 311 * Sets whether to handle cancellation within the asynchronous operation. 312 * 313 **/ 314 void 315 g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple, 316 gboolean handle_cancellation) 317 { 318 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 319 simple->handle_cancellation = handle_cancellation; 320 } 321 322 /** 323 * g_simple_async_result_get_source_tag: 324 * @simple: a #GSimpleAsyncResult. 325 * 326 * Gets the source tag for the #GSimpleAsyncResult. 327 * 328 * Returns: a #gpointer to the source object for the #GSimpleAsyncResult. 329 **/ 330 gpointer 331 g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple) 332 { 333 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL); 334 return simple->source_tag; 335 } 336 337 /** 338 * g_simple_async_result_propagate_error: 339 * @simple: a #GSimpleAsyncResult. 340 * @dest: a location to propegate the error to. 341 * 342 * Propagates an error from within the simple asynchronous result to 343 * a given destination. 344 * 345 * Returns: %TRUE if the error was propegated to @dest. %FALSE otherwise. 346 **/ 347 gboolean 348 g_simple_async_result_propagate_error (GSimpleAsyncResult *simple, 349 GError **dest) 350 { 351 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE); 352 353 if (simple->failed) 354 { 355 g_propagate_error (dest, simple->error); 356 simple->error = NULL; 357 return TRUE; 358 } 359 360 return FALSE; 361 } 362 363 /** 364 * g_simple_async_result_set_op_res_gpointer: 365 * @simple: a #GSimpleAsyncResult. 366 * @op_res: a pointer result from an asynchronous function. 367 * @destroy_op_res: a #GDestroyNotify function. 368 * 369 * Sets the operation result within the asynchronous result to a pointer. 370 **/ 371 void 372 g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple, 373 gpointer op_res, 374 GDestroyNotify destroy_op_res) 375 { 376 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 377 378 simple->op_res.v_pointer = op_res; 379 simple->destroy_op_res = destroy_op_res; 380 } 381 382 /** 383 * g_simple_async_result_get_op_res_gpointer: 384 * @simple: a #GSimpleAsyncResult. 385 * 386 * Gets a pointer result as returned by the asynchronous function. 387 * 388 * Returns: a pointer from the result. 389 **/ 390 gpointer 391 g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple) 392 { 393 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL); 394 return simple->op_res.v_pointer; 395 } 396 397 /** 398 * g_simple_async_result_set_op_res_gssize: 399 * @simple: a #GSimpleAsyncResult. 400 * @op_res: a #gssize. 401 * 402 * Sets the operation result within the asynchronous result to 403 * the given @op_res. 404 **/ 405 void 406 g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple, 407 gssize op_res) 408 { 409 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 410 simple->op_res.v_ssize = op_res; 411 } 412 413 /** 414 * g_simple_async_result_get_op_res_gssize: 415 * @simple: a #GSimpleAsyncResult. 416 * 417 * Gets a gssize from the asynchronous result. 418 * 419 * Returns: a gssize returned from the asynchronous function. 420 **/ 421 gssize 422 g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple) 423 { 424 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0); 425 return simple->op_res.v_ssize; 426 } 427 428 /** 429 * g_simple_async_result_set_op_res_gboolean: 430 * @simple: a #GSimpleAsyncResult. 431 * @op_res: a #gboolean. 432 * 433 * Sets the operation result to a boolean within the asynchronous result. 434 **/ 435 void 436 g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple, 437 gboolean op_res) 438 { 439 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 440 simple->op_res.v_boolean = !!op_res; 441 } 442 443 /** 444 * g_simple_async_result_get_op_res_gboolean: 445 * @simple: a #GSimpleAsyncResult. 446 * 447 * Gets the operation result boolean from within the asynchronous result. 448 * 449 * Returns: %TRUE if the operation's result was %TRUE, %FALSE 450 * if the operation's result was %FALSE. 451 **/ 452 gboolean 453 g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple) 454 { 455 g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE); 456 return simple->op_res.v_boolean; 457 } 458 459 /** 460 * g_simple_async_result_set_from_error: 461 * @simple: a #GSimpleAsyncResult. 462 * @error: #GError. 463 * 464 * Sets the result from a #GError. 465 **/ 466 void 467 g_simple_async_result_set_from_error (GSimpleAsyncResult *simple, 468 GError *error) 469 { 470 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 471 g_return_if_fail (error != NULL); 472 473 if (simple->error) 474 g_error_free (simple->error); 475 simple->error = g_error_copy (error); 476 simple->failed = TRUE; 477 } 478 479 static GError* 480 _g_error_new_valist (GQuark domain, 481 gint code, 482 const char *format, 483 va_list args) 484 { 485 GError *error; 486 char *message; 487 488 message = g_strdup_vprintf (format, args); 489 490 error = g_error_new_literal (domain, code, message); 491 g_free (message); 492 493 return error; 494 } 495 496 /** 497 * g_simple_async_result_set_error_va: 498 * @simple: a #GSimpleAsyncResult. 499 * @domain: a #GQuark (usually #G_IO_ERROR). 500 * @code: an error code. 501 * @format: a formatted error reporting string. 502 * @args: va_list of arguments. 503 * 504 * Sets an error within the asynchronous result without a #GError. 505 * Unless writing a binding, see g_simple_async_result_set_error(). 506 **/ 507 void 508 g_simple_async_result_set_error_va (GSimpleAsyncResult *simple, 509 GQuark domain, 510 gint code, 511 const char *format, 512 va_list args) 513 { 514 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 515 g_return_if_fail (domain != 0); 516 g_return_if_fail (format != NULL); 517 518 if (simple->error) 519 g_error_free (simple->error); 520 simple->error = _g_error_new_valist (domain, code, format, args); 521 simple->failed = TRUE; 522 } 523 524 /** 525 * g_simple_async_result_set_error: 526 * @simple: a #GSimpleAsyncResult. 527 * @domain: a #GQuark (usually #G_IO_ERROR). 528 * @code: an error code. 529 * @format: a formatted error reporting string. 530 * @...: a list of variables to fill in @format. 531 * 532 * Sets an error within the asynchronous result without a #GError. 533 **/ 534 void 535 g_simple_async_result_set_error (GSimpleAsyncResult *simple, 536 GQuark domain, 537 gint code, 538 const char *format, 539 ...) 540 { 541 va_list args; 542 543 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 544 g_return_if_fail (domain != 0); 545 g_return_if_fail (format != NULL); 546 547 va_start (args, format); 548 g_simple_async_result_set_error_va (simple, domain, code, format, args); 549 va_end (args); 550 } 551 552 /** 553 * g_simple_async_result_complete: 554 * @simple: a #GSimpleAsyncResult. 555 * 556 * Completes an asynchronous I/O job. 557 * Must be called in the main thread, as it invokes the callback that 558 * should be called in the main thread. If you are in a different thread 559 * use g_simple_async_result_complete_in_idle(). 560 **/ 561 void 562 g_simple_async_result_complete (GSimpleAsyncResult *simple) 563 { 564 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 565 566 if (simple->callback) 567 simple->callback (simple->source_object, 568 G_ASYNC_RESULT (simple), 569 simple->user_data); 570 } 571 572 static gboolean 573 complete_in_idle_cb (gpointer data) 574 { 575 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data); 576 577 g_simple_async_result_complete (simple); 578 579 return FALSE; 580 } 581 582 /** 583 * g_simple_async_result_complete_in_idle: 584 * @simple: a #GSimpleAsyncResult. 585 * 586 * Completes an asynchronous function in the main event loop using 587 * an idle function. 588 **/ 589 void 590 g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple) 591 { 592 GSource *source; 593 guint id; 594 595 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 596 597 g_object_ref (simple); 598 599 source = g_idle_source_new (); 600 g_source_set_priority (source, G_PRIORITY_DEFAULT); 601 g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref); 602 603 id = g_source_attach (source, NULL); 604 g_source_unref (source); 605 } 606 607 typedef struct { 608 GSimpleAsyncResult *simple; 609 GCancellable *cancellable; 610 GSimpleAsyncThreadFunc func; 611 } RunInThreadData; 612 613 614 static gboolean 615 complete_in_idle_cb_for_thread (gpointer _data) 616 { 617 RunInThreadData *data = _data; 618 GSimpleAsyncResult *simple; 619 620 simple = data->simple; 621 622 if (simple->handle_cancellation && 623 g_cancellable_is_cancelled (data->cancellable)) 624 g_simple_async_result_set_error (simple, 625 G_IO_ERROR, 626 G_IO_ERROR_CANCELLED, 627 "%s", _("Operation was cancelled")); 628 629 g_simple_async_result_complete (simple); 630 631 if (data->cancellable) 632 g_object_unref (data->cancellable); 633 g_object_unref (data->simple); 634 g_free (data); 635 636 return FALSE; 637 } 638 639 static gboolean 640 run_in_thread (GIOSchedulerJob *job, 641 GCancellable *c, 642 gpointer _data) 643 { 644 RunInThreadData *data = _data; 645 GSimpleAsyncResult *simple = data->simple; 646 GSource *source; 647 guint id; 648 649 if (simple->handle_cancellation && 650 g_cancellable_is_cancelled (c)) 651 g_simple_async_result_set_error (simple, 652 G_IO_ERROR, 653 G_IO_ERROR_CANCELLED, 654 "%s", _("Operation was cancelled")); 655 else 656 data->func (simple, 657 simple->source_object, 658 c); 659 660 source = g_idle_source_new (); 661 g_source_set_priority (source, G_PRIORITY_DEFAULT); 662 g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL); 663 664 id = g_source_attach (source, NULL); 665 g_source_unref (source); 666 667 return FALSE; 668 } 669 670 /** 671 * g_simple_async_result_run_in_thread: 672 * @simple: a #GSimpleAsyncResult. 673 * @func: a #GSimpleAsyncThreadFunc. 674 * @io_priority: the io priority of the request. 675 * @cancellable: optional #GCancellable object, %NULL to ignore. 676 * 677 * Runs the asynchronous job in a separated thread. 678 **/ 679 void 680 g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple, 681 GSimpleAsyncThreadFunc func, 682 int io_priority, 683 GCancellable *cancellable) 684 { 685 RunInThreadData *data; 686 687 g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple)); 688 g_return_if_fail (func != NULL); 689 690 data = g_new (RunInThreadData, 1); 691 data->func = func; 692 data->simple = g_object_ref (simple); 693 data->cancellable = cancellable; 694 if (cancellable) 695 g_object_ref (cancellable); 696 g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable); 697 } 698 699 /** 700 * g_simple_async_result_is_valid: 701 * @result: the #GAsyncResult passed to the _finish function. 702 * @source: the #GObject passed to the _finish function. 703 * @source_tag: the asynchronous function. 704 * 705 * Ensures that the data passed to the _finish function of an async 706 * operation is consistent. Three checks are performed. 707 * 708 * First, @result is checked to ensure that it is really a 709 * #GSimpleAsyncResult. Second, @source is checked to ensure that it 710 * matches the source object of @result. Third, @source_tag is 711 * checked to ensure that it is equal to the source_tag argument given 712 * to g_simple_async_result_new() (which, by convention, is a pointer 713 * to the _async function corresponding to the _finish function from 714 * which this function is called). 715 * 716 * Returns: #TRUE if all checks passed or #FALSE if any failed. 717 **/ 718 gboolean 719 g_simple_async_result_is_valid (GAsyncResult *result, 720 GObject *source, 721 gpointer source_tag) 722 { 723 GSimpleAsyncResult *simple; 724 GObject *cmp_source; 725 726 if (!G_IS_SIMPLE_ASYNC_RESULT (result)) 727 return FALSE; 728 simple = (GSimpleAsyncResult *)result; 729 730 cmp_source = g_async_result_get_source_object (result); 731 if (cmp_source != source) 732 { 733 g_object_unref (cmp_source); 734 return FALSE; 735 } 736 g_object_unref (cmp_source); 737 738 return source_tag == g_simple_async_result_get_source_tag (simple); 739 } 740 741 /** 742 * g_simple_async_report_error_in_idle: 743 * @object: a #GObject. 744 * @callback: a #GAsyncReadyCallback. 745 * @user_data: user data passed to @callback. 746 * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR). 747 * @code: a specific error code. 748 * @format: a formatted error reporting string. 749 * @...: a list of variables to fill in @format. 750 * 751 * Reports an error in an asynchronous function in an idle function by 752 * directly setting the contents of the #GAsyncResult with the given error 753 * information. 754 **/ 755 void 756 g_simple_async_report_error_in_idle (GObject *object, 757 GAsyncReadyCallback callback, 758 gpointer user_data, 759 GQuark domain, 760 gint code, 761 const char *format, 762 ...) 763 { 764 GSimpleAsyncResult *simple; 765 va_list args; 766 767 g_return_if_fail (G_IS_OBJECT (object)); 768 g_return_if_fail (domain != 0); 769 g_return_if_fail (format != NULL); 770 771 simple = g_simple_async_result_new (object, 772 callback, 773 user_data, NULL); 774 775 va_start (args, format); 776 g_simple_async_result_set_error_va (simple, domain, code, format, args); 777 va_end (args); 778 g_simple_async_result_complete_in_idle (simple); 779 g_object_unref (simple); 780 } 781 782 /** 783 * g_simple_async_report_gerror_in_idle: 784 * @object: a #GObject. 785 * @callback: a #GAsyncReadyCallback. 786 * @user_data: user data passed to @callback. 787 * @error: the #GError to report 788 * 789 * Reports an error in an idle function. Similar to 790 * g_simple_async_report_error_in_idle(), but takes a #GError rather 791 * than building a new one. 792 **/ 793 void 794 g_simple_async_report_gerror_in_idle (GObject *object, 795 GAsyncReadyCallback callback, 796 gpointer user_data, 797 GError *error) 798 { 799 GSimpleAsyncResult *simple; 800 801 g_return_if_fail (G_IS_OBJECT (object)); 802 g_return_if_fail (error != NULL); 803 804 simple = g_simple_async_result_new_from_error (object, 805 callback, 806 user_data, 807 error); 808 g_simple_async_result_complete_in_idle (simple); 809 g_object_unref (simple); 810 } 811 812 #define __G_SIMPLE_ASYNC_RESULT_C__ 813 #include "gioaliasdef.c" 814