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