1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD 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 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.Task; 26 27 private import gio.AsyncResultIF; 28 private import gio.AsyncResultT; 29 private import gio.Cancellable; 30 private import glib.ConstructionException; 31 private import glib.ErrorG; 32 private import glib.GException; 33 private import glib.MainContext; 34 private import glib.Source; 35 private import glib.Str; 36 private import gobject.ObjectG; 37 private import gtkc.gio; 38 public import gtkc.giotypes; 39 40 41 /** 42 * A #GTask represents and manages a cancellable "task". 43 * 44 * ## Asynchronous operations 45 * 46 * The most common usage of #GTask is as a #GAsyncResult, to 47 * manage data during an asynchronous operation. You call 48 * g_task_new() in the "start" method, followed by 49 * g_task_set_task_data() and the like if you need to keep some 50 * additional data associated with the task, and then pass the 51 * task object around through your asynchronous operation. 52 * Eventually, you will call a method such as 53 * g_task_return_pointer() or g_task_return_error(), which will 54 * save the value you give it and then invoke the task's callback 55 * function (waiting until the next iteration of the main 56 * loop first, if necessary). The caller will pass the #GTask back 57 * to the operation's finish function (as a #GAsyncResult), and 58 * you can use g_task_propagate_pointer() or the like to extract 59 * the return value. 60 * 61 * Here is an example for using GTask as a GAsyncResult: 62 * |[<!-- language="C" --> 63 * typedef struct { 64 * CakeFrostingType frosting; 65 * char *message; 66 * } DecorationData; 67 * 68 * static void 69 * decoration_data_free (DecorationData *decoration) 70 * { 71 * g_free (decoration->message); 72 * g_slice_free (DecorationData, decoration); 73 * } 74 * 75 * static void 76 * baked_cb (Cake *cake, 77 * gpointer user_data) 78 * { 79 * GTask *task = user_data; 80 * DecorationData *decoration = g_task_get_task_data (task); 81 * GError *error = NULL; 82 * 83 * if (cake == NULL) 84 * { 85 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, 86 * "Go to the supermarket"); 87 * g_object_unref (task); 88 * return; 89 * } 90 * 91 * if (!cake_decorate (cake, decoration->frosting, decoration->message, &error)) 92 * { 93 * g_object_unref (cake); 94 * // g_task_return_error() takes ownership of error 95 * g_task_return_error (task, error); 96 * g_object_unref (task); 97 * return; 98 * } 99 * 100 * g_task_return_pointer (task, cake, g_object_unref); 101 * g_object_unref (task); 102 * } 103 * 104 * void 105 * baker_bake_cake_async (Baker *self, 106 * guint radius, 107 * CakeFlavor flavor, 108 * CakeFrostingType frosting, 109 * const char *message, 110 * GCancellable *cancellable, 111 * GAsyncReadyCallback callback, 112 * gpointer user_data) 113 * { 114 * GTask *task; 115 * DecorationData *decoration; 116 * Cake *cake; 117 * 118 * task = g_task_new (self, cancellable, callback, user_data); 119 * if (radius < 3) 120 * { 121 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL, 122 * "%ucm radius cakes are silly", 123 * radius); 124 * g_object_unref (task); 125 * return; 126 * } 127 * 128 * cake = _baker_get_cached_cake (self, radius, flavor, frosting, message); 129 * if (cake != NULL) 130 * { 131 * // _baker_get_cached_cake() returns a reffed cake 132 * g_task_return_pointer (task, cake, g_object_unref); 133 * g_object_unref (task); 134 * return; 135 * } 136 * 137 * decoration = g_slice_new (DecorationData); 138 * decoration->frosting = frosting; 139 * decoration->message = g_strdup (message); 140 * g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free); 141 * 142 * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); 143 * } 144 * 145 * Cake * 146 * baker_bake_cake_finish (Baker *self, 147 * GAsyncResult *result, 148 * GError **error) 149 * { 150 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 151 * 152 * return g_task_propagate_pointer (G_TASK (result), error); 153 * } 154 * ]| 155 * 156 * ## Chained asynchronous operations 157 * 158 * #GTask also tries to simplify asynchronous operations that 159 * internally chain together several smaller asynchronous 160 * operations. g_task_get_cancellable(), g_task_get_context(), 161 * and g_task_get_priority() allow you to get back the task's 162 * #GCancellable, #GMainContext, and [I/O priority][io-priority] 163 * when starting a new subtask, so you don't have to keep track 164 * of them yourself. g_task_attach_source() simplifies the case 165 * of waiting for a source to fire (automatically using the correct 166 * #GMainContext and priority). 167 * 168 * Here is an example for chained asynchronous operations: 169 * |[<!-- language="C" --> 170 * typedef struct { 171 * Cake *cake; 172 * CakeFrostingType frosting; 173 * char *message; 174 * } BakingData; 175 * 176 * static void 177 * decoration_data_free (BakingData *bd) 178 * { 179 * if (bd->cake) 180 * g_object_unref (bd->cake); 181 * g_free (bd->message); 182 * g_slice_free (BakingData, bd); 183 * } 184 * 185 * static void 186 * decorated_cb (Cake *cake, 187 * GAsyncResult *result, 188 * gpointer user_data) 189 * { 190 * GTask *task = user_data; 191 * GError *error = NULL; 192 * 193 * if (!cake_decorate_finish (cake, result, &error)) 194 * { 195 * g_object_unref (cake); 196 * g_task_return_error (task, error); 197 * g_object_unref (task); 198 * return; 199 * } 200 * 201 * // baking_data_free() will drop its ref on the cake, so we have to 202 * // take another here to give to the caller. 203 * g_task_return_pointer (task, g_object_ref (cake), g_object_unref); 204 * g_object_unref (task); 205 * } 206 * 207 * static gboolean 208 * decorator_ready (gpointer user_data) 209 * { 210 * GTask *task = user_data; 211 * BakingData *bd = g_task_get_task_data (task); 212 * 213 * cake_decorate_async (bd->cake, bd->frosting, bd->message, 214 * g_task_get_cancellable (task), 215 * decorated_cb, task); 216 * 217 * return G_SOURCE_REMOVE; 218 * } 219 * 220 * static void 221 * baked_cb (Cake *cake, 222 * gpointer user_data) 223 * { 224 * GTask *task = user_data; 225 * BakingData *bd = g_task_get_task_data (task); 226 * GError *error = NULL; 227 * 228 * if (cake == NULL) 229 * { 230 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, 231 * "Go to the supermarket"); 232 * g_object_unref (task); 233 * return; 234 * } 235 * 236 * bd->cake = cake; 237 * 238 * // Bail out now if the user has already cancelled 239 * if (g_task_return_error_if_cancelled (task)) 240 * { 241 * g_object_unref (task); 242 * return; 243 * } 244 * 245 * if (cake_decorator_available (cake)) 246 * decorator_ready (task); 247 * else 248 * { 249 * GSource *source; 250 * 251 * source = cake_decorator_wait_source_new (cake); 252 * // Attach @source to @task's GMainContext and have it call 253 * // decorator_ready() when it is ready. 254 * g_task_attach_source (task, source, decorator_ready); 255 * g_source_unref (source); 256 * } 257 * } 258 * 259 * void 260 * baker_bake_cake_async (Baker *self, 261 * guint radius, 262 * CakeFlavor flavor, 263 * CakeFrostingType frosting, 264 * const char *message, 265 * gint priority, 266 * GCancellable *cancellable, 267 * GAsyncReadyCallback callback, 268 * gpointer user_data) 269 * { 270 * GTask *task; 271 * BakingData *bd; 272 * 273 * task = g_task_new (self, cancellable, callback, user_data); 274 * g_task_set_priority (task, priority); 275 * 276 * bd = g_slice_new0 (BakingData); 277 * bd->frosting = frosting; 278 * bd->message = g_strdup (message); 279 * g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free); 280 * 281 * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); 282 * } 283 * 284 * Cake * 285 * baker_bake_cake_finish (Baker *self, 286 * GAsyncResult *result, 287 * GError **error) 288 * { 289 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 290 * 291 * return g_task_propagate_pointer (G_TASK (result), error); 292 * } 293 * ]| 294 * 295 * ## Asynchronous operations from synchronous ones 296 * 297 * You can use g_task_run_in_thread() to turn a synchronous 298 * operation into an asynchronous one, by running it in a thread 299 * which will then dispatch the result back to the caller's 300 * #GMainContext when it completes. 301 * 302 * Running a task in a thread: 303 * |[<!-- language="C" --> 304 * typedef struct { 305 * guint radius; 306 * CakeFlavor flavor; 307 * CakeFrostingType frosting; 308 * char *message; 309 * } CakeData; 310 * 311 * static void 312 * cake_data_free (CakeData *cake_data) 313 * { 314 * g_free (cake_data->message); 315 * g_slice_free (CakeData, cake_data); 316 * } 317 * 318 * static void 319 * bake_cake_thread (GTask *task, 320 * gpointer source_object, 321 * gpointer task_data, 322 * GCancellable *cancellable) 323 * { 324 * Baker *self = source_object; 325 * CakeData *cake_data = task_data; 326 * Cake *cake; 327 * GError *error = NULL; 328 * 329 * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, 330 * cake_data->frosting, cake_data->message, 331 * cancellable, &error); 332 * if (cake) 333 * g_task_return_pointer (task, cake, g_object_unref); 334 * else 335 * g_task_return_error (task, error); 336 * } 337 * 338 * void 339 * baker_bake_cake_async (Baker *self, 340 * guint radius, 341 * CakeFlavor flavor, 342 * CakeFrostingType frosting, 343 * const char *message, 344 * GCancellable *cancellable, 345 * GAsyncReadyCallback callback, 346 * gpointer user_data) 347 * { 348 * CakeData *cake_data; 349 * GTask *task; 350 * 351 * cake_data = g_slice_new (CakeData); 352 * cake_data->radius = radius; 353 * cake_data->flavor = flavor; 354 * cake_data->frosting = frosting; 355 * cake_data->message = g_strdup (message); 356 * task = g_task_new (self, cancellable, callback, user_data); 357 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 358 * g_task_run_in_thread (task, bake_cake_thread); 359 * g_object_unref (task); 360 * } 361 * 362 * Cake * 363 * baker_bake_cake_finish (Baker *self, 364 * GAsyncResult *result, 365 * GError **error) 366 * { 367 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 368 * 369 * return g_task_propagate_pointer (G_TASK (result), error); 370 * } 371 * ]| 372 * 373 * ## Adding cancellability to uncancellable tasks 374 * 375 * Finally, g_task_run_in_thread() and g_task_run_in_thread_sync() 376 * can be used to turn an uncancellable operation into a 377 * cancellable one. If you call g_task_set_return_on_cancel(), 378 * passing %TRUE, then if the task's #GCancellable is cancelled, 379 * it will return control back to the caller immediately, while 380 * allowing the task thread to continue running in the background 381 * (and simply discarding its result when it finally does finish). 382 * Provided that the task thread is careful about how it uses 383 * locks and other externally-visible resources, this allows you 384 * to make "GLib-friendly" asynchronous and cancellable 385 * synchronous variants of blocking APIs. 386 * 387 * Cancelling a task: 388 * |[<!-- language="C" --> 389 * static void 390 * bake_cake_thread (GTask *task, 391 * gpointer source_object, 392 * gpointer task_data, 393 * GCancellable *cancellable) 394 * { 395 * Baker *self = source_object; 396 * CakeData *cake_data = task_data; 397 * Cake *cake; 398 * GError *error = NULL; 399 * 400 * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, 401 * cake_data->frosting, cake_data->message, 402 * &error); 403 * if (error) 404 * { 405 * g_task_return_error (task, error); 406 * return; 407 * } 408 * 409 * // If the task has already been cancelled, then we don't want to add 410 * // the cake to the cake cache. Likewise, we don't want to have the 411 * // task get cancelled in the middle of updating the cache. 412 * // g_task_set_return_on_cancel() will return %TRUE here if it managed 413 * // to disable return-on-cancel, or %FALSE if the task was cancelled 414 * // before it could. 415 * if (g_task_set_return_on_cancel (task, FALSE)) 416 * { 417 * // If the caller cancels at this point, their 418 * // GAsyncReadyCallback won't be invoked until we return, 419 * // so we don't have to worry that this code will run at 420 * // the same time as that code does. But if there were 421 * // other functions that might look at the cake cache, 422 * // then we'd probably need a GMutex here as well. 423 * baker_add_cake_to_cache (baker, cake); 424 * g_task_return_pointer (task, cake, g_object_unref); 425 * } 426 * } 427 * 428 * void 429 * baker_bake_cake_async (Baker *self, 430 * guint radius, 431 * CakeFlavor flavor, 432 * CakeFrostingType frosting, 433 * const char *message, 434 * GCancellable *cancellable, 435 * GAsyncReadyCallback callback, 436 * gpointer user_data) 437 * { 438 * CakeData *cake_data; 439 * GTask *task; 440 * 441 * cake_data = g_slice_new (CakeData); 442 * 443 * ... 444 * 445 * task = g_task_new (self, cancellable, callback, user_data); 446 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 447 * g_task_set_return_on_cancel (task, TRUE); 448 * g_task_run_in_thread (task, bake_cake_thread); 449 * } 450 * 451 * Cake * 452 * baker_bake_cake_sync (Baker *self, 453 * guint radius, 454 * CakeFlavor flavor, 455 * CakeFrostingType frosting, 456 * const char *message, 457 * GCancellable *cancellable, 458 * GError **error) 459 * { 460 * CakeData *cake_data; 461 * GTask *task; 462 * Cake *cake; 463 * 464 * cake_data = g_slice_new (CakeData); 465 * 466 * ... 467 * 468 * task = g_task_new (self, cancellable, NULL, NULL); 469 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 470 * g_task_set_return_on_cancel (task, TRUE); 471 * g_task_run_in_thread_sync (task, bake_cake_thread); 472 * 473 * cake = g_task_propagate_pointer (task, error); 474 * g_object_unref (task); 475 * return cake; 476 * } 477 * ]| 478 * 479 * ## Porting from GSimpleAsyncResult 480 * 481 * #GTask's API attempts to be simpler than #GSimpleAsyncResult's 482 * in several ways: 483 * - You can save task-specific data with g_task_set_task_data(), and 484 * retrieve it later with g_task_get_task_data(). This replaces the 485 * abuse of g_simple_async_result_set_op_res_gpointer() for the same 486 * purpose with #GSimpleAsyncResult. 487 * - In addition to the task data, #GTask also keeps track of the 488 * [priority][io-priority], #GCancellable, and 489 * #GMainContext associated with the task, so tasks that consist of 490 * a chain of simpler asynchronous operations will have easy access 491 * to those values when starting each sub-task. 492 * - g_task_return_error_if_cancelled() provides simplified 493 * handling for cancellation. In addition, cancellation 494 * overrides any other #GTask return value by default, like 495 * #GSimpleAsyncResult does when 496 * g_simple_async_result_set_check_cancellable() is called. 497 * (You can use g_task_set_check_cancellable() to turn off that 498 * behavior.) On the other hand, g_task_run_in_thread() 499 * guarantees that it will always run your 500 * `task_func`, even if the task's #GCancellable 501 * is already cancelled before the task gets a chance to run; 502 * you can start your `task_func` with a 503 * g_task_return_error_if_cancelled() check if you need the 504 * old behavior. 505 * - The "return" methods (eg, g_task_return_pointer()) 506 * automatically cause the task to be "completed" as well, and 507 * there is no need to worry about the "complete" vs "complete 508 * in idle" distinction. (#GTask automatically figures out 509 * whether the task's callback can be invoked directly, or 510 * if it needs to be sent to another #GMainContext, or delayed 511 * until the next iteration of the current #GMainContext.) 512 * - The "finish" functions for #GTask-based operations are generally 513 * much simpler than #GSimpleAsyncResult ones, normally consisting 514 * of only a single call to g_task_propagate_pointer() or the like. 515 * Since g_task_propagate_pointer() "steals" the return value from 516 * the #GTask, it is not necessary to juggle pointers around to 517 * prevent it from being freed twice. 518 * - With #GSimpleAsyncResult, it was common to call 519 * g_simple_async_result_propagate_error() from the 520 * `_finish()` wrapper function, and have 521 * virtual method implementations only deal with successful 522 * returns. This behavior is deprecated, because it makes it 523 * difficult for a subclass to chain to a parent class's async 524 * methods. Instead, the wrapper function should just be a 525 * simple wrapper, and the virtual method should call an 526 * appropriate `g_task_propagate_` function. 527 * Note that wrapper methods can now use 528 * g_async_result_legacy_propagate_error() to do old-style 529 * #GSimpleAsyncResult error-returning behavior, and 530 * g_async_result_is_tagged() to check if a result is tagged as 531 * having come from the `_async()` wrapper 532 * function (for "short-circuit" results, such as when passing 533 * 0 to g_input_stream_read_async()). 534 */ 535 public class Task : ObjectG, AsyncResultIF 536 { 537 /** the main Gtk struct */ 538 protected GTask* gTask; 539 540 /** Get the main Gtk struct */ 541 public GTask* getTaskStruct(bool transferOwnership = false) 542 { 543 if (transferOwnership) 544 ownedRef = false; 545 return gTask; 546 } 547 548 /** the main Gtk struct as a void* */ 549 protected override void* getStruct() 550 { 551 return cast(void*)gTask; 552 } 553 554 protected override void setStruct(GObject* obj) 555 { 556 gTask = cast(GTask*)obj; 557 super.setStruct(obj); 558 } 559 560 /** 561 * Sets our main struct and passes it to the parent class. 562 */ 563 public this (GTask* gTask, bool ownedRef = false) 564 { 565 this.gTask = gTask; 566 super(cast(GObject*)gTask, ownedRef); 567 } 568 569 // add the AsyncResult capabilities 570 mixin AsyncResultT!(GTask); 571 572 573 /** */ 574 public static GType getType() 575 { 576 return g_task_get_type(); 577 } 578 579 /** 580 * Creates a #GTask acting on @source_object, which will eventually be 581 * used to invoke @callback in the current 582 * [thread-default main context][g-main-context-push-thread-default]. 583 * 584 * Call this in the "start" method of your asynchronous method, and 585 * pass the #GTask around throughout the asynchronous operation. You 586 * can use g_task_set_task_data() to attach task-specific data to the 587 * object, which you can retrieve later via g_task_get_task_data(). 588 * 589 * By default, if @cancellable is cancelled, then the return value of 590 * the task will always be %G_IO_ERROR_CANCELLED, even if the task had 591 * already completed before the cancellation. This allows for 592 * simplified handling in cases where cancellation may imply that 593 * other objects that the task depends on have been destroyed. If you 594 * do not want this behavior, you can use 595 * g_task_set_check_cancellable() to change it. 596 * 597 * Params: 598 * sourceObject = the #GObject that owns 599 * this task, or %NULL. 600 * cancellable = optional #GCancellable object, %NULL to ignore. 601 * callback = a #GAsyncReadyCallback. 602 * callbackData = user data passed to @callback. 603 * 604 * Returns: a #GTask. 605 * 606 * Since: 2.36 607 * 608 * Throws: ConstructionException GTK+ fails to create the object. 609 */ 610 public this(ObjectG sourceObject, Cancellable cancellable, GAsyncReadyCallback callback, void* callbackData) 611 { 612 auto p = g_task_new((sourceObject is null) ? null : sourceObject.getObjectGStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, callbackData); 613 614 if(p is null) 615 { 616 throw new ConstructionException("null returned by new"); 617 } 618 619 this(cast(GTask*) p, true); 620 } 621 622 /** 623 * Checks that @result is a #GTask, and that @source_object is its 624 * source object (or that @source_object is %NULL and @result has no 625 * source object). This can be used in g_return_if_fail() checks. 626 * 627 * Params: 628 * result = A #GAsyncResult 629 * sourceObject = the source object 630 * expected to be associated with the task 631 * 632 * Returns: %TRUE if @result and @source_object are valid, %FALSE 633 * if not 634 * 635 * Since: 2.36 636 */ 637 public static bool isValid(AsyncResultIF result, ObjectG sourceObject) 638 { 639 return g_task_is_valid((result is null) ? null : result.getAsyncResultStruct(), (sourceObject is null) ? null : sourceObject.getObjectGStruct()) != 0; 640 } 641 642 /** 643 * Creates a #GTask and then immediately calls g_task_return_error() 644 * on it. Use this in the wrapper function of an asynchronous method 645 * when you want to avoid even calling the virtual method. You can 646 * then use g_async_result_is_tagged() in the finish method wrapper to 647 * check if the result there is tagged as having been created by the 648 * wrapper method, and deal with it appropriately if so. 649 * 650 * See also g_task_report_new_error(). 651 * 652 * Params: 653 * sourceObject = the #GObject that owns 654 * this task, or %NULL. 655 * callback = a #GAsyncReadyCallback. 656 * callbackData = user data passed to @callback. 657 * sourceTag = an opaque pointer indicating the source of this task 658 * error = error to report 659 * 660 * Since: 2.36 661 */ 662 public static void reportError(ObjectG sourceObject, GAsyncReadyCallback callback, void* callbackData, void* sourceTag, ErrorG error) 663 { 664 g_task_report_error((sourceObject is null) ? null : sourceObject.getObjectGStruct(), callback, callbackData, sourceTag, (error is null) ? null : error.getErrorGStruct(true)); 665 } 666 667 /** 668 * A utility function for dealing with async operations where you need 669 * to wait for a #GSource to trigger. Attaches @source to @task's 670 * #GMainContext with @task's [priority][io-priority], and sets @source's 671 * callback to @callback, with @task as the callback's `user_data`. 672 * 673 * This takes a reference on @task until @source is destroyed. 674 * 675 * Params: 676 * source = the source to attach 677 * callback = the callback to invoke when @source triggers 678 * 679 * Since: 2.36 680 */ 681 public void attachSource(Source source, GSourceFunc callback) 682 { 683 g_task_attach_source(gTask, (source is null) ? null : source.getSourceStruct(), callback); 684 } 685 686 /** 687 * Gets @task's #GCancellable 688 * 689 * Returns: @task's #GCancellable 690 * 691 * Since: 2.36 692 */ 693 public Cancellable getCancellable() 694 { 695 auto p = g_task_get_cancellable(gTask); 696 697 if(p is null) 698 { 699 return null; 700 } 701 702 return ObjectG.getDObject!(Cancellable)(cast(GCancellable*) p); 703 } 704 705 /** 706 * Gets @task's check-cancellable flag. See 707 * g_task_set_check_cancellable() for more details. 708 * 709 * Since: 2.36 710 */ 711 public bool getCheckCancellable() 712 { 713 return g_task_get_check_cancellable(gTask) != 0; 714 } 715 716 /** 717 * Gets the value of #GTask:completed. This changes from %FALSE to %TRUE after 718 * the task’s callback is invoked, and will return %FALSE if called from inside 719 * the callback. 720 * 721 * Returns: %TRUE if the task has completed, %FALSE otherwise. 722 * 723 * Since: 2.44 724 */ 725 public bool getCompleted() 726 { 727 return g_task_get_completed(gTask) != 0; 728 } 729 730 /** 731 * Gets the #GMainContext that @task will return its result in (that 732 * is, the context that was the 733 * [thread-default main context][g-main-context-push-thread-default] 734 * at the point when @task was created). 735 * 736 * This will always return a non-%NULL value, even if the task's 737 * context is the default #GMainContext. 738 * 739 * Returns: @task's #GMainContext 740 * 741 * Since: 2.36 742 */ 743 public MainContext getContext() 744 { 745 auto p = g_task_get_context(gTask); 746 747 if(p is null) 748 { 749 return null; 750 } 751 752 return new MainContext(cast(GMainContext*) p); 753 } 754 755 /** 756 * Gets @task's priority 757 * 758 * Returns: @task's priority 759 * 760 * Since: 2.36 761 */ 762 public int getPriority() 763 { 764 return g_task_get_priority(gTask); 765 } 766 767 /** 768 * Gets @task's return-on-cancel flag. See 769 * g_task_set_return_on_cancel() for more details. 770 * 771 * Since: 2.36 772 */ 773 public bool getReturnOnCancel() 774 { 775 return g_task_get_return_on_cancel(gTask) != 0; 776 } 777 778 /** 779 * Gets the source object from @task. Like 780 * g_async_result_get_source_object(), but does not ref the object. 781 * 782 * Returns: @task's source object, or %NULL 783 * 784 * Since: 2.36 785 */ 786 public ObjectG getSourceObject() 787 { 788 auto p = g_task_get_source_object(gTask); 789 790 if(p is null) 791 { 792 return null; 793 } 794 795 return ObjectG.getDObject!(ObjectG)(cast(GObject*) p); 796 } 797 798 /** 799 * Gets @task's source tag. See g_task_set_source_tag(). 800 * 801 * Returns: @task's source tag 802 * 803 * Since: 2.36 804 */ 805 public void* getSourceTag() 806 { 807 return g_task_get_source_tag(gTask); 808 } 809 810 /** 811 * Gets @task's `task_data`. 812 * 813 * Returns: @task's `task_data`. 814 * 815 * Since: 2.36 816 */ 817 public void* getTaskData() 818 { 819 return g_task_get_task_data(gTask); 820 } 821 822 /** 823 * Tests if @task resulted in an error. 824 * 825 * Returns: %TRUE if the task resulted in an error, %FALSE otherwise. 826 * 827 * Since: 2.36 828 */ 829 public bool hadError() 830 { 831 return g_task_had_error(gTask) != 0; 832 } 833 834 /** 835 * Gets the result of @task as a #gboolean. 836 * 837 * If the task resulted in an error, or was cancelled, then this will 838 * instead return %FALSE and set @error. 839 * 840 * Since this method transfers ownership of the return value (or 841 * error) to the caller, you may only call it once. 842 * 843 * Returns: the task result, or %FALSE on error 844 * 845 * Since: 2.36 846 * 847 * Throws: GException on failure. 848 */ 849 public bool propagateBoolean() 850 { 851 GError* err = null; 852 853 auto p = g_task_propagate_boolean(gTask, &err) != 0; 854 855 if (err !is null) 856 { 857 throw new GException( new ErrorG(err) ); 858 } 859 860 return p; 861 } 862 863 /** 864 * Gets the result of @task as an integer (#gssize). 865 * 866 * If the task resulted in an error, or was cancelled, then this will 867 * instead return -1 and set @error. 868 * 869 * Since this method transfers ownership of the return value (or 870 * error) to the caller, you may only call it once. 871 * 872 * Returns: the task result, or -1 on error 873 * 874 * Since: 2.36 875 * 876 * Throws: GException on failure. 877 */ 878 public ptrdiff_t propagateInt() 879 { 880 GError* err = null; 881 882 auto p = g_task_propagate_int(gTask, &err); 883 884 if (err !is null) 885 { 886 throw new GException( new ErrorG(err) ); 887 } 888 889 return p; 890 } 891 892 /** 893 * Gets the result of @task as a pointer, and transfers ownership 894 * of that value to the caller. 895 * 896 * If the task resulted in an error, or was cancelled, then this will 897 * instead return %NULL and set @error. 898 * 899 * Since this method transfers ownership of the return value (or 900 * error) to the caller, you may only call it once. 901 * 902 * Returns: the task result, or %NULL on error 903 * 904 * Since: 2.36 905 * 906 * Throws: GException on failure. 907 */ 908 public void* propagatePointer() 909 { 910 GError* err = null; 911 912 auto p = g_task_propagate_pointer(gTask, &err); 913 914 if (err !is null) 915 { 916 throw new GException( new ErrorG(err) ); 917 } 918 919 return p; 920 } 921 922 /** 923 * Sets @task's result to @result and completes the task (see 924 * g_task_return_pointer() for more discussion of exactly what this 925 * means). 926 * 927 * Params: 928 * result = the #gboolean result of a task function. 929 * 930 * Since: 2.36 931 */ 932 public void returnBoolean(bool result) 933 { 934 g_task_return_boolean(gTask, result); 935 } 936 937 /** 938 * Sets @task's result to @error (which @task assumes ownership of) 939 * and completes the task (see g_task_return_pointer() for more 940 * discussion of exactly what this means). 941 * 942 * Note that since the task takes ownership of @error, and since the 943 * task may be completed before returning from g_task_return_error(), 944 * you cannot assume that @error is still valid after calling this. 945 * Call g_error_copy() on the error if you need to keep a local copy 946 * as well. 947 * 948 * See also g_task_return_new_error(). 949 * 950 * Params: 951 * error = the #GError result of a task function. 952 * 953 * Since: 2.36 954 */ 955 public void returnError(ErrorG error) 956 { 957 g_task_return_error(gTask, (error is null) ? null : error.getErrorGStruct(true)); 958 } 959 960 /** 961 * Checks if @task's #GCancellable has been cancelled, and if so, sets 962 * @task's error accordingly and completes the task (see 963 * g_task_return_pointer() for more discussion of exactly what this 964 * means). 965 * 966 * Returns: %TRUE if @task has been cancelled, %FALSE if not 967 * 968 * Since: 2.36 969 */ 970 public bool returnErrorIfCancelled() 971 { 972 return g_task_return_error_if_cancelled(gTask) != 0; 973 } 974 975 /** 976 * Sets @task's result to @result and completes the task (see 977 * g_task_return_pointer() for more discussion of exactly what this 978 * means). 979 * 980 * Params: 981 * result = the integer (#gssize) result of a task function. 982 * 983 * Since: 2.36 984 */ 985 public void returnInt(ptrdiff_t result) 986 { 987 g_task_return_int(gTask, result); 988 } 989 990 /** 991 * Sets @task's result to @result and completes the task. If @result 992 * is not %NULL, then @result_destroy will be used to free @result if 993 * the caller does not take ownership of it with 994 * g_task_propagate_pointer(). 995 * 996 * "Completes the task" means that for an ordinary asynchronous task 997 * it will either invoke the task's callback, or else queue that 998 * callback to be invoked in the proper #GMainContext, or in the next 999 * iteration of the current #GMainContext. For a task run via 1000 * g_task_run_in_thread() or g_task_run_in_thread_sync(), calling this 1001 * method will save @result to be returned to the caller later, but 1002 * the task will not actually be completed until the #GTaskThreadFunc 1003 * exits. 1004 * 1005 * Note that since the task may be completed before returning from 1006 * g_task_return_pointer(), you cannot assume that @result is still 1007 * valid after calling this, unless you are still holding another 1008 * reference on it. 1009 * 1010 * Params: 1011 * result = the pointer result of a task 1012 * function 1013 * resultDestroy = a #GDestroyNotify function. 1014 * 1015 * Since: 2.36 1016 */ 1017 public void returnPointer(void* result, GDestroyNotify resultDestroy) 1018 { 1019 g_task_return_pointer(gTask, result, resultDestroy); 1020 } 1021 1022 /** 1023 * Runs @task_func in another thread. When @task_func returns, @task's 1024 * #GAsyncReadyCallback will be invoked in @task's #GMainContext. 1025 * 1026 * This takes a ref on @task until the task completes. 1027 * 1028 * See #GTaskThreadFunc for more details about how @task_func is handled. 1029 * 1030 * Although GLib currently rate-limits the tasks queued via 1031 * g_task_run_in_thread(), you should not assume that it will always 1032 * do this. If you have a very large number of tasks to run, but don't 1033 * want them to all run at once, you should only queue a limited 1034 * number of them at a time. 1035 * 1036 * Params: 1037 * taskFunc = a #GTaskThreadFunc 1038 * 1039 * Since: 2.36 1040 */ 1041 public void runInThread(GTaskThreadFunc taskFunc) 1042 { 1043 g_task_run_in_thread(gTask, taskFunc); 1044 } 1045 1046 /** 1047 * Runs @task_func in another thread, and waits for it to return or be 1048 * cancelled. You can use g_task_propagate_pointer(), etc, afterward 1049 * to get the result of @task_func. 1050 * 1051 * See #GTaskThreadFunc for more details about how @task_func is handled. 1052 * 1053 * Normally this is used with tasks created with a %NULL 1054 * `callback`, but note that even if the task does 1055 * have a callback, it will not be invoked when @task_func returns. 1056 * #GTask:completed will be set to %TRUE just before this function returns. 1057 * 1058 * Although GLib currently rate-limits the tasks queued via 1059 * g_task_run_in_thread_sync(), you should not assume that it will 1060 * always do this. If you have a very large number of tasks to run, 1061 * but don't want them to all run at once, you should only queue a 1062 * limited number of them at a time. 1063 * 1064 * Params: 1065 * taskFunc = a #GTaskThreadFunc 1066 * 1067 * Since: 2.36 1068 */ 1069 public void runInThreadSync(GTaskThreadFunc taskFunc) 1070 { 1071 g_task_run_in_thread_sync(gTask, taskFunc); 1072 } 1073 1074 /** 1075 * Sets or clears @task's check-cancellable flag. If this is %TRUE 1076 * (the default), then g_task_propagate_pointer(), etc, and 1077 * g_task_had_error() will check the task's #GCancellable first, and 1078 * if it has been cancelled, then they will consider the task to have 1079 * returned an "Operation was cancelled" error 1080 * (%G_IO_ERROR_CANCELLED), regardless of any other error or return 1081 * value the task may have had. 1082 * 1083 * If @check_cancellable is %FALSE, then the #GTask will not check the 1084 * cancellable itself, and it is up to @task's owner to do this (eg, 1085 * via g_task_return_error_if_cancelled()). 1086 * 1087 * If you are using g_task_set_return_on_cancel() as well, then 1088 * you must leave check-cancellable set %TRUE. 1089 * 1090 * Params: 1091 * checkCancellable = whether #GTask will check the state of 1092 * its #GCancellable for you. 1093 * 1094 * Since: 2.36 1095 */ 1096 public void setCheckCancellable(bool checkCancellable) 1097 { 1098 g_task_set_check_cancellable(gTask, checkCancellable); 1099 } 1100 1101 /** 1102 * Sets @task's priority. If you do not call this, it will default to 1103 * %G_PRIORITY_DEFAULT. 1104 * 1105 * This will affect the priority of #GSources created with 1106 * g_task_attach_source() and the scheduling of tasks run in threads, 1107 * and can also be explicitly retrieved later via 1108 * g_task_get_priority(). 1109 * 1110 * Params: 1111 * priority = the [priority][io-priority] of the request 1112 * 1113 * Since: 2.36 1114 */ 1115 public void setPriority(int priority) 1116 { 1117 g_task_set_priority(gTask, priority); 1118 } 1119 1120 /** 1121 * Sets or clears @task's return-on-cancel flag. This is only 1122 * meaningful for tasks run via g_task_run_in_thread() or 1123 * g_task_run_in_thread_sync(). 1124 * 1125 * If @return_on_cancel is %TRUE, then cancelling @task's 1126 * #GCancellable will immediately cause it to return, as though the 1127 * task's #GTaskThreadFunc had called 1128 * g_task_return_error_if_cancelled() and then returned. 1129 * 1130 * This allows you to create a cancellable wrapper around an 1131 * uninterruptable function. The #GTaskThreadFunc just needs to be 1132 * careful that it does not modify any externally-visible state after 1133 * it has been cancelled. To do that, the thread should call 1134 * g_task_set_return_on_cancel() again to (atomically) set 1135 * return-on-cancel %FALSE before making externally-visible changes; 1136 * if the task gets cancelled before the return-on-cancel flag could 1137 * be changed, g_task_set_return_on_cancel() will indicate this by 1138 * returning %FALSE. 1139 * 1140 * You can disable and re-enable this flag multiple times if you wish. 1141 * If the task's #GCancellable is cancelled while return-on-cancel is 1142 * %FALSE, then calling g_task_set_return_on_cancel() to set it %TRUE 1143 * again will cause the task to be cancelled at that point. 1144 * 1145 * If the task's #GCancellable is already cancelled before you call 1146 * g_task_run_in_thread()/g_task_run_in_thread_sync(), then the 1147 * #GTaskThreadFunc will still be run (for consistency), but the task 1148 * will also be completed right away. 1149 * 1150 * Params: 1151 * returnOnCancel = whether the task returns automatically when 1152 * it is cancelled. 1153 * 1154 * Returns: %TRUE if @task's return-on-cancel flag was changed to 1155 * match @return_on_cancel. %FALSE if @task has already been 1156 * cancelled. 1157 * 1158 * Since: 2.36 1159 */ 1160 public bool setReturnOnCancel(bool returnOnCancel) 1161 { 1162 return g_task_set_return_on_cancel(gTask, returnOnCancel) != 0; 1163 } 1164 1165 /** 1166 * Sets @task's source tag. You can use this to tag a task return 1167 * value with a particular pointer (usually a pointer to the function 1168 * doing the tagging) and then later check it using 1169 * g_task_get_source_tag() (or g_async_result_is_tagged()) in the 1170 * task's "finish" function, to figure out if the response came from a 1171 * particular place. 1172 * 1173 * Params: 1174 * sourceTag = an opaque pointer indicating the source of this task 1175 * 1176 * Since: 2.36 1177 */ 1178 public void setSourceTag(void* sourceTag) 1179 { 1180 g_task_set_source_tag(gTask, sourceTag); 1181 } 1182 1183 /** 1184 * Sets @task's task data (freeing the existing task data, if any). 1185 * 1186 * Params: 1187 * taskData = task-specific data 1188 * taskDataDestroy = #GDestroyNotify for @task_data 1189 * 1190 * Since: 2.36 1191 */ 1192 public void setTaskData(void* taskData, GDestroyNotify taskDataDestroy) 1193 { 1194 g_task_set_task_data(gTask, taskData, taskDataDestroy); 1195 } 1196 }