gsimpleasyncresult.c 36.5 KB
Newer Older
1
/* GIO - GLib Input, Output and Streaming Library
2
 *
3 4 5 6 7
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9 10 11 12 13 14 15
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
16
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 18 19 20
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

21
#include "config.h"
22 23 24 25

#include <string.h>

#include "gsimpleasyncresult.h"
26 27
#include "gasyncresult.h"
#include "gcancellable.h"
28 29 30 31
#include "gioscheduler.h"
#include <gio/gioerror.h>
#include "glibintl.h"

32

33 34
/**
 * SECTION:gsimpleasyncresult
Matthias Clasen's avatar
Matthias Clasen committed
35
 * @short_description: Simple asynchronous results implementation
Matthias Clasen's avatar
Matthias Clasen committed
36
 * @include: gio/gio.h
37
 * @see_also: #GAsyncResult, #GTask
38
 *
Matthias Clasen's avatar
Matthias Clasen committed
39
 * As of GLib 2.46, #GSimpleAsyncResult is deprecated in favor of
40
 * #GTask, which provides a simpler API.
41 42
 *
 * #GSimpleAsyncResult implements #GAsyncResult.
43
 *
44
 * GSimpleAsyncResult handles #GAsyncReadyCallbacks, error
45 46 47 48 49 50
 * reporting, operation cancellation and the final state of an operation,
 * completely transparent to the application. Results can be returned
 * as a pointer e.g. for functions that return data that is collected
 * asynchronously, a boolean value for checking the success or failure
 * of an operation, or a #gssize for operations which return the number
 * of bytes modified by the operation; all of the simple return cases
51
 * are covered.
52 53 54 55 56 57
 *
 * Most of the time, an application will not need to know of the details
 * of this API; it is handled transparently, and any necessary operations
 * are handled by #GAsyncResult's interface. However, if implementing a
 * new GIO module, for writing language bindings, or for complex
 * applications that need better control of how asynchronous operations
58
 * are completed, it is important to understand this functionality.
59 60 61
 *
 * GSimpleAsyncResults are tagged with the calling function to ensure
 * that asynchronous functions and their finishing functions are used
62
 * together correctly.
63 64 65
 *
 * To create a new #GSimpleAsyncResult, call g_simple_async_result_new().
 * If the result needs to be created for a #GError, use
66 67
 * g_simple_async_result_new_from_error() or
 * g_simple_async_result_new_take_error(). If a #GError is not available
68
 * (e.g. the asynchronous operation's doesn't take a #GError argument),
69
 * but the result still needs to be created for an error condition, use
70
 * g_simple_async_result_new_error() (or g_simple_async_result_set_error_va()
71
 * if your application or binding requires passing a variable argument list
Matthias Clasen's avatar
Matthias Clasen committed
72
 * directly), and the error can then be propagated through the use of
Matthias Clasen's avatar
Matthias Clasen committed
73
 * g_simple_async_result_propagate_error().
74 75 76
 *
 * An asynchronous operation can be made to ignore a cancellation event by
 * calling g_simple_async_result_set_handle_cancellation() with a
77 78 79
 * #GSimpleAsyncResult for the operation and %FALSE. This is useful for
 * operations that are dangerous to cancel, such as close (which would
 * cause a leak if cancelled before being run).
80 81
 *
 * GSimpleAsyncResult can integrate into GLib's event loop, #GMainLoop,
82
 * or it can use #GThreads.
83 84
 * g_simple_async_result_complete() will finish an I/O task directly
 * from the point where it is called. g_simple_async_result_complete_in_idle()
85 86
 * will finish it from an idle handler in the 
 * [thread-default main context][g-main-context-push-thread-default]
87 88 89 90
 * where the #GSimpleAsyncResult was created.
 * g_simple_async_result_run_in_thread() will run the job in a
 * separate thread and then use
 * g_simple_async_result_complete_in_idle() to deliver the result.
91 92 93 94
 *
 * To set the results of an asynchronous function,
 * g_simple_async_result_set_op_res_gpointer(),
 * g_simple_async_result_set_op_res_gboolean(), and
Matthias Clasen's avatar
Matthias Clasen committed
95
 * g_simple_async_result_set_op_res_gssize()
96
 * are provided, setting the operation's result to a gpointer, gboolean, or
Matthias Clasen's avatar
Matthias Clasen committed
97
 * gssize, respectively.
98 99
 *
 * Likewise, to get the result of an asynchronous function,
Matthias Clasen's avatar
Matthias Clasen committed
100
 * g_simple_async_result_get_op_res_gpointer(),
101 102 103
 * g_simple_async_result_get_op_res_gboolean(), and
 * g_simple_async_result_get_op_res_gssize() are
 * provided, getting the operation's result as a gpointer, gboolean, and
Matthias Clasen's avatar
Matthias Clasen committed
104
 * gssize, respectively.
105 106 107 108 109
 *
 * For the details of the requirements implementations must respect, see
 * #GAsyncResult.  A typical implementation of an asynchronous operation
 * using GSimpleAsyncResult looks something like this:
 *
110
 * |[<!-- language="C" -->
111 112 113 114
 * static void
 * baked_cb (Cake    *cake,
 *           gpointer user_data)
 * {
Matthias Clasen's avatar
Matthias Clasen committed
115 116
 *   // In this example, this callback is not given a reference to the cake,
 *   // so the GSimpleAsyncResult has to take a reference to it.
117 118 119 120 121 122 123 124 125 126 127 128 129
 *   GSimpleAsyncResult *result = user_data;
 *
 *   if (cake == NULL)
 *     g_simple_async_result_set_error (result,
 *                                      BAKER_ERRORS,
 *                                      BAKER_ERROR_NO_FLOUR,
 *                                      "Go to the supermarket");
 *   else
 *     g_simple_async_result_set_op_res_gpointer (result,
 *                                                g_object_ref (cake),
 *                                                g_object_unref);
 *
 *
Matthias Clasen's avatar
Matthias Clasen committed
130 131 132 133 134
 *   // In this example, we assume that baked_cb is called as a callback from
 *   // the mainloop, so it's safe to complete the operation synchronously here.
 *   // If, however, _baker_prepare_cake () might call its callback without
 *   // first returning to the mainloop — inadvisable, but some APIs do so —
 *   // we would need to use g_simple_async_result_complete_in_idle().
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
 *   g_simple_async_result_complete (result);
 *   g_object_unref (result);
 * }
 *
 * void
 * baker_bake_cake_async (Baker              *self,
 *                        guint               radius,
 *                        GAsyncReadyCallback callback,
 *                        gpointer            user_data)
 * {
 *   GSimpleAsyncResult *simple;
 *   Cake               *cake;
 *
 *   if (radius < 3)
 *     {
 *       g_simple_async_report_error_in_idle (G_OBJECT (self),
 *                                            callback,
 *                                            user_data,
 *                                            BAKER_ERRORS,
 *                                            BAKER_ERROR_TOO_SMALL,
 *                                            "%ucm radius cakes are silly",
 *                                            radius);
 *       return;
 *     }
 *
 *   simple = g_simple_async_result_new (G_OBJECT (self),
 *                                       callback,
 *                                       user_data,
 *                                       baker_bake_cake_async);
 *   cake = _baker_get_cached_cake (self, radius);
 *
 *   if (cake != NULL)
 *     {
 *       g_simple_async_result_set_op_res_gpointer (simple,
 *                                                  g_object_ref (cake),
 *                                                  g_object_unref);
 *       g_simple_async_result_complete_in_idle (simple);
 *       g_object_unref (simple);
Matthias Clasen's avatar
Matthias Clasen committed
173 174
 *       // Drop the reference returned by _baker_get_cached_cake();
 *       // the GSimpleAsyncResult has taken its own reference.
175 176 177 178
 *       g_object_unref (cake);
 *       return;
 *     }
 *
179
 *   _baker_prepare_cake (self, radius, baked_cb, simple);
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
 * }
 *
 * Cake *
 * baker_bake_cake_finish (Baker        *self,
 *                         GAsyncResult *result,
 *                         GError      **error)
 * {
 *   GSimpleAsyncResult *simple;
 *   Cake               *cake;
 *
 *   g_return_val_if_fail (g_simple_async_result_is_valid (result,
 *                                                         G_OBJECT (self),
 *                                                         baker_bake_cake_async),
 *                         NULL);
 *
 *   simple = (GSimpleAsyncResult *) result;
 *
 *   if (g_simple_async_result_propagate_error (simple, error))
 *     return NULL;
 *
 *   cake = CAKE (g_simple_async_result_get_op_res_gpointer (simple));
 *   return g_object_ref (cake);
 * }
 * ]|
 */
205

206 207
G_GNUC_BEGIN_IGNORE_DEPRECATIONS

208 209 210 211 212 213 214 215 216
static void g_simple_async_result_async_result_iface_init (GAsyncResultIface       *iface);

struct _GSimpleAsyncResult
{
  GObject parent_instance;

  GObject *source_object;
  GAsyncReadyCallback callback;
  gpointer user_data;
217
  GMainContext *context;
218 219 220
  GError *error;
  gboolean failed;
  gboolean handle_cancellation;
221
  GCancellable *check_cancellable;
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

  gpointer source_tag;

  union {
    gpointer v_pointer;
    gboolean v_boolean;
    gssize   v_ssize;
  } op_res;

  GDestroyNotify destroy_op_res;
};

struct _GSimpleAsyncResultClass
{
  GObjectClass parent_class;
};


G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT,
						g_simple_async_result_async_result_iface_init))

244 245 246 247 248 249 250 251 252
static void
clear_op_res (GSimpleAsyncResult *simple)
{
  if (simple->destroy_op_res)
    simple->destroy_op_res (simple->op_res.v_pointer);
  simple->destroy_op_res = NULL;
  simple->op_res.v_ssize = 0;
}

253 254 255 256 257 258 259 260 261 262
static void
g_simple_async_result_finalize (GObject *object)
{
  GSimpleAsyncResult *simple;

  simple = G_SIMPLE_ASYNC_RESULT (object);

  if (simple->source_object)
    g_object_unref (simple->source_object);

263 264 265
  if (simple->check_cancellable)
    g_object_unref (simple->check_cancellable);

266
  g_main_context_unref (simple->context);
267

268
  clear_op_res (simple);
269 270 271

  if (simple->error)
    g_error_free (simple->error);
272 273

  G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object);
274 275 276 277 278 279
}

static void
g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
280
 
281 282 283 284 285 286 287
  gobject_class->finalize = g_simple_async_result_finalize;
}

static void
g_simple_async_result_init (GSimpleAsyncResult *simple)
{
  simple->handle_cancellation = TRUE;
288

289
  simple->context = g_main_context_ref_thread_default ();
290 291 292 293
}

/**
 * g_simple_async_result_new:
294
 * @source_object: (nullable): a #GObject, or %NULL.
295 296
 * @callback: (scope async): a #GAsyncReadyCallback.
 * @user_data: (closure): user data passed to @callback.
297
 * @source_tag: the asynchronous function.
298
 *
299
 * Creates a #GSimpleAsyncResult.
300
 *
301 302 303 304 305 306 307 308 309
 * The common convention is to create the #GSimpleAsyncResult in the
 * function that starts the asynchronous operation and use that same
 * function as the @source_tag.
 *
 * If your operation supports cancellation with #GCancellable (which it
 * probably should) then you should provide the user's cancellable to
 * g_simple_async_result_set_check_cancellable() immediately after
 * this function returns.
 *
310
 * Returns: a #GSimpleAsyncResult.
311 312
 *
 * Deprecated: 2.46: Use g_task_new() instead.
313 314
 **/
GSimpleAsyncResult *
315 316 317 318
g_simple_async_result_new (GObject             *source_object,
                           GAsyncReadyCallback  callback,
                           gpointer             user_data,
                           gpointer             source_tag)
319 320 321
{
  GSimpleAsyncResult *simple;

322
  g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
323 324 325

  simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
  simple->callback = callback;
326 327 328 329
  if (source_object)
    simple->source_object = g_object_ref (source_object);
  else
    simple->source_object = NULL;
330 331
  simple->user_data = user_data;
  simple->source_tag = source_tag;
332
 
333 334 335 336 337
  return simple;
}

/**
 * g_simple_async_result_new_from_error:
338
 * @source_object: (nullable): a #GObject, or %NULL.
339 340
 * @callback: (scope async): a #GAsyncReadyCallback.
 * @user_data: (closure): user data passed to @callback.
341
 * @error: a #GError
342
 *
343
 * Creates a #GSimpleAsyncResult from an error condition.
344
 *
345
 * Returns: a #GSimpleAsyncResult.
346 347
 *
 * Deprecated: 2.46: Use g_task_new() and g_task_return_error() instead.
348 349
 **/
GSimpleAsyncResult *
350 351 352
g_simple_async_result_new_from_error (GObject             *source_object,
                                      GAsyncReadyCallback  callback,
                                      gpointer             user_data,
353
                                      const GError        *error)
354 355 356
{
  GSimpleAsyncResult *simple;

357
  g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
358 359 360 361 362 363 364 365 366

  simple = g_simple_async_result_new (source_object,
				      callback,
				      user_data, NULL);
  g_simple_async_result_set_from_error (simple, error);

  return simple;
}

367
/**
368
 * g_simple_async_result_new_take_error: (skip)
369
 * @source_object: (nullable): a #GObject, or %NULL
370 371
 * @callback: (scope async): a #GAsyncReadyCallback
 * @user_data: (closure): user data passed to @callback
372 373 374 375 376 377 378
 * @error: a #GError
 *
 * Creates a #GSimpleAsyncResult from an error condition, and takes over the
 * caller's ownership of @error, so the caller does not need to free it anymore.
 *
 * Returns: a #GSimpleAsyncResult
 *
379
 * Since: 2.28
380 381
 *
 * Deprecated: 2.46: Use g_task_new() and g_task_return_error() instead.
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
 **/
GSimpleAsyncResult *
g_simple_async_result_new_take_error (GObject             *source_object,
                                      GAsyncReadyCallback  callback,
                                      gpointer             user_data,
                                      GError              *error)
{
  GSimpleAsyncResult *simple;

  g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);

  simple = g_simple_async_result_new (source_object,
				      callback,
				      user_data, NULL);
  g_simple_async_result_take_error (simple, error);

  return simple;
}

401 402
/**
 * g_simple_async_result_new_error:
403
 * @source_object: (nullable): a #GObject, or %NULL.
404 405
 * @callback: (scope async): a #GAsyncReadyCallback.
 * @user_data: (closure): user data passed to @callback.
406 407 408
 * @domain: a #GQuark.
 * @code: an error code.
 * @format: a string with format characters.
409
 * @...: a list of values to insert into @format.
410
 *
411
 * Creates a new #GSimpleAsyncResult with a set error.
412
 *
413
 * Returns: a #GSimpleAsyncResult.
414 415
 *
 * Deprecated: 2.46: Use g_task_new() and g_task_return_new_error() instead.
416 417
 **/
GSimpleAsyncResult *
418 419 420 421 422 423 424
g_simple_async_result_new_error (GObject             *source_object,
                                 GAsyncReadyCallback  callback,
                                 gpointer             user_data,
                                 GQuark               domain,
                                 gint                 code,
                                 const char          *format,
                                 ...)
425 426 427
{
  GSimpleAsyncResult *simple;
  va_list args;
428
 
429
  g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
430 431 432 433 434 435 436 437 438 439
  g_return_val_if_fail (domain != 0, NULL);
  g_return_val_if_fail (format != NULL, NULL);

  simple = g_simple_async_result_new (source_object,
				      callback,
				      user_data, NULL);

  va_start (args, format);
  g_simple_async_result_set_error_va (simple, domain, code, format, args);
  va_end (args);
440
 
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
  return simple;
}


static gpointer
g_simple_async_result_get_user_data (GAsyncResult *res)
{
  return G_SIMPLE_ASYNC_RESULT (res)->user_data;
}

static GObject *
g_simple_async_result_get_source_object (GAsyncResult *res)
{
  if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
    return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
  return NULL;
}

459 460 461 462 463 464 465
static gboolean
g_simple_async_result_is_tagged (GAsyncResult *res,
				 gpointer      source_tag)
{
  return G_SIMPLE_ASYNC_RESULT (res)->source_tag == source_tag;
}

466 467 468 469 470
static void
g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
{
  iface->get_user_data = g_simple_async_result_get_user_data;
  iface->get_source_object = g_simple_async_result_get_source_object;
471
  iface->is_tagged = g_simple_async_result_is_tagged;
472 473 474 475
}

/**
 * g_simple_async_result_set_handle_cancellation:
476 477
 * @simple: a #GSimpleAsyncResult.
 * @handle_cancellation: a #gboolean.
478
 *
479
 * Sets whether to handle cancellation within the asynchronous operation.
480
 *
481 482 483
 * This function has nothing to do with
 * g_simple_async_result_set_check_cancellable().  It only refers to the
 * #GCancellable passed to g_simple_async_result_run_in_thread().
484 485
 *
 * Deprecated: 2.46
486 487 488
 **/
void
g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
489
                                               gboolean            handle_cancellation)
490 491 492 493 494 495
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  simple->handle_cancellation = handle_cancellation;
}

/**
496
 * g_simple_async_result_get_source_tag: (skip)
497
 * @simple: a #GSimpleAsyncResult.
498
 *
499
 * Gets the source tag for the #GSimpleAsyncResult.
500
 *
501
 * Returns: a #gpointer to the source object for the #GSimpleAsyncResult.
502 503
 *
 * Deprecated: 2.46. Use #GTask and g_task_get_source_tag() instead.
504 505 506 507 508 509 510 511 512
 **/
gpointer
g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
{
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
  return simple->source_tag;
}

/**
513 514
 * g_simple_async_result_propagate_error:
 * @simple: a #GSimpleAsyncResult.
515
 * @dest: (out): a location to propagate the error to.
516
 *
517
 * Propagates an error from within the simple asynchronous result to
518
 * a given destination.
519
 *
520 521 522 523
 * If the #GCancellable given to a prior call to
 * g_simple_async_result_set_check_cancellable() is cancelled then this
 * function will return %TRUE with @dest set appropriately.
 *
Matthias Clasen's avatar
Matthias Clasen committed
524
 * Returns: %TRUE if the error was propagated to @dest. %FALSE otherwise.
525 526
 *
 * Deprecated: 2.46: Use #GTask instead.
527 528
 **/
gboolean
529 530
g_simple_async_result_propagate_error (GSimpleAsyncResult  *simple,
                                       GError             **dest)
531 532 533
{
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);

534 535 536
  if (g_cancellable_set_error_if_cancelled (simple->check_cancellable, dest))
    return TRUE;

537 538 539 540 541 542
  if (simple->failed)
    {
      g_propagate_error (dest, simple->error);
      simple->error = NULL;
      return TRUE;
    }
543

544 545 546 547
  return FALSE;
}

/**
548
 * g_simple_async_result_set_op_res_gpointer: (skip)
549 550 551
 * @simple: a #GSimpleAsyncResult.
 * @op_res: a pointer result from an asynchronous function.
 * @destroy_op_res: a #GDestroyNotify function.
552
 *
553
 * Sets the operation result within the asynchronous result to a pointer.
554 555
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_pointer() instead.
556 557
 **/
void
558 559 560
g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
                                           gpointer            op_res,
                                           GDestroyNotify      destroy_op_res)
561 562 563
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));

564
  clear_op_res (simple);
565 566 567 568 569
  simple->op_res.v_pointer = op_res;
  simple->destroy_op_res = destroy_op_res;
}

/**
570
 * g_simple_async_result_get_op_res_gpointer: (skip)
571
 * @simple: a #GSimpleAsyncResult.
572
 *
573
 * Gets a pointer result as returned by the asynchronous function.
574
 *
575
 * Returns: a pointer from the result.
576 577
 *
 * Deprecated: 2.46: Use #GTask and g_task_propagate_pointer() instead.
578 579
 **/
gpointer
580
g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
581 582 583 584 585 586 587
{
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
  return simple->op_res.v_pointer;
}

/**
 * g_simple_async_result_set_op_res_gssize:
588 589
 * @simple: a #GSimpleAsyncResult.
 * @op_res: a #gssize.
590 591 592
 *
 * Sets the operation result within the asynchronous result to
 * the given @op_res.
593 594
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_int() instead.
595 596
 **/
void
597 598
g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
                                         gssize              op_res)
599 600
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
601
  clear_op_res (simple);
602 603 604 605 606
  simple->op_res.v_ssize = op_res;
}

/**
 * g_simple_async_result_get_op_res_gssize:
607
 * @simple: a #GSimpleAsyncResult.
608
 *
609
 * Gets a gssize from the asynchronous result.
610
 *
611
 * Returns: a gssize returned from the asynchronous function.
612 613
 *
 * Deprecated: 2.46: Use #GTask and g_task_propagate_int() instead.
614 615
 **/
gssize
616
g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
617 618 619 620 621 622 623
{
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
  return simple->op_res.v_ssize;
}

/**
 * g_simple_async_result_set_op_res_gboolean:
624 625
 * @simple: a #GSimpleAsyncResult.
 * @op_res: a #gboolean.
626
 *
627
 * Sets the operation result to a boolean within the asynchronous result.
628 629
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_boolean() instead.
630 631
 **/
void
632 633
g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
                                           gboolean            op_res)
634 635
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
636
  clear_op_res (simple);
637 638 639 640 641
  simple->op_res.v_boolean = !!op_res;
}

/**
 * g_simple_async_result_get_op_res_gboolean:
642
 * @simple: a #GSimpleAsyncResult.
643
 *
644
 * Gets the operation result boolean from within the asynchronous result.
645 646 647
 *
 * Returns: %TRUE if the operation's result was %TRUE, %FALSE
 *     if the operation's result was %FALSE.
648 649
 *
 * Deprecated: 2.46: Use #GTask and g_task_propagate_boolean() instead.
650 651
 **/
gboolean
652
g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
653 654 655 656 657 658 659
{
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
  return simple->op_res.v_boolean;
}

/**
 * g_simple_async_result_set_from_error:
660
 * @simple: a #GSimpleAsyncResult.
661
 * @error: #GError.
662 663
 *
 * Sets the result from a #GError.
664 665
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_error() instead.
666 667 668
 **/
void
g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
669
                                      const GError       *error)
670 671 672 673
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (error != NULL);

674 675
  if (simple->error)
    g_error_free (simple->error);
676 677 678 679
  simple->error = g_error_copy (error);
  simple->failed = TRUE;
}

680
/**
681
 * g_simple_async_result_take_error: (skip)
682 683 684 685 686 687
 * @simple: a #GSimpleAsyncResult
 * @error: a #GError
 *
 * Sets the result from @error, and takes over the caller's ownership
 * of @error, so the caller does not need to free it any more.
 *
688
 * Since: 2.28
689 690
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_error() instead.
691 692 693 694 695 696 697 698 699 700 701 702 703 704
 **/
void
g_simple_async_result_take_error (GSimpleAsyncResult *simple,
                                  GError             *error)
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (error != NULL);

  if (simple->error)
    g_error_free (simple->error);
  simple->error = error;
  simple->failed = TRUE;
}

705
/**
706
 * g_simple_async_result_set_error_va: (skip)
707 708 709 710
 * @simple: a #GSimpleAsyncResult.
 * @domain: a #GQuark (usually #G_IO_ERROR).
 * @code: an error code.
 * @format: a formatted error reporting string.
711 712 713
 * @args: va_list of arguments.
 *
 * Sets an error within the asynchronous result without a #GError.
714
 * Unless writing a binding, see g_simple_async_result_set_error().
715 716
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_error() instead.
717 718 719
 **/
void
g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
720 721 722 723
                                    GQuark              domain,
                                    gint                code,
                                    const char         *format,
                                    va_list             args)
724 725 726 727 728
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (domain != 0);
  g_return_if_fail (format != NULL);

729 730
  if (simple->error)
    g_error_free (simple->error);
731
  simple->error = g_error_new_valist (domain, code, format, args);
732 733 734 735
  simple->failed = TRUE;
}

/**
736
 * g_simple_async_result_set_error: (skip)
737 738 739 740
 * @simple: a #GSimpleAsyncResult.
 * @domain: a #GQuark (usually #G_IO_ERROR).
 * @code: an error code.
 * @format: a formatted error reporting string.
741
 * @...: a list of variables to fill in @format.
742
 *
743
 * Sets an error within the asynchronous result without a #GError.
744 745
 *
 * Deprecated: 2.46: Use #GTask and g_task_return_new_error() instead.
746 747 748
 **/
void
g_simple_async_result_set_error (GSimpleAsyncResult *simple,
749 750 751 752
                                 GQuark              domain,
                                 gint                code,
                                 const char         *format,
                                 ...)
753 754 755 756 757 758 759 760 761 762 763 764 765 766
{
  va_list args;

  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (domain != 0);
  g_return_if_fail (format != NULL);

  va_start (args, format);
  g_simple_async_result_set_error_va (simple, domain, code, format, args);
  va_end (args);
}

/**
 * g_simple_async_result_complete:
767
 * @simple: a #GSimpleAsyncResult.
768
 *
769 770 771 772
 * Completes an asynchronous I/O job immediately. Must be called in
 * the thread where the asynchronous result was to be delivered, as it
 * invokes the callback directly. If you are in a different thread use
 * g_simple_async_result_complete_in_idle().
773 774 775
 *
 * Calling this function takes a reference to @simple for as long as
 * is needed to complete the call.
776 777
 *
 * Deprecated: 2.46: Use #GTask instead.
778 779 780 781
 **/
void
g_simple_async_result_complete (GSimpleAsyncResult *simple)
{
782 783 784 785 786
#ifndef G_DISABLE_CHECKS
  GSource *current_source;
  GMainContext *current_context;
#endif

787 788
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));

789 790
#ifndef G_DISABLE_CHECKS
  current_source = g_main_current_source ();
791
  if (current_source && !g_source_is_destroyed (current_source))
792 793 794 795 796 797 798
    {
      current_context = g_source_get_context (current_source);
      if (simple->context != current_context)
	g_warning ("g_simple_async_result_complete() called from wrong context!");
    }
#endif

799
  if (simple->callback)
800 801 802 803 804 805 806
    {
      g_main_context_push_thread_default (simple->context);
      simple->callback (simple->source_object,
			G_ASYNC_RESULT (simple),
			simple->user_data);
      g_main_context_pop_thread_default (simple->context);
    }
807 808 809 810 811 812 813 814 815 816 817 818 819 820
}

static gboolean
complete_in_idle_cb (gpointer data)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);

  g_simple_async_result_complete (simple);

  return FALSE;
}

/**
 * g_simple_async_result_complete_in_idle:
821
 * @simple: a #GSimpleAsyncResult.
822
 *
823 824 825
 * Completes an asynchronous function in an idle handler in the
 * [thread-default main context][g-main-context-push-thread-default]
 * of the thread that @simple was initially created in
826
 * (and re-pushes that context around the invocation of the callback).
827 828 829
 *
 * Calling this function takes a reference to @simple for as long as
 * is needed to complete the call.
830 831
 *
 * Deprecated: 2.46: Use #GTask instead.
832
 */
833 834 835 836
void
g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
{
  GSource *source;
837

838
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
839

840
  g_object_ref (simple);
841
 
842 843 844
  source = g_idle_source_new ();
  g_source_set_priority (source, G_PRIORITY_DEFAULT);
  g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
845
  g_source_set_name (source, "[gio] complete_in_idle_cb");
846

847
  g_source_attach (source, simple->context);
848 849 850 851 852
  g_source_unref (source);
}

typedef struct {
  GSimpleAsyncResult *simple;
853
  GCancellable *cancellable;
854 855 856
  GSimpleAsyncThreadFunc func;
} RunInThreadData;

857 858 859 860 861 862 863 864

static gboolean
complete_in_idle_cb_for_thread (gpointer _data)
{
  RunInThreadData *data = _data;
  GSimpleAsyncResult *simple;

  simple = data->simple;
865
 
866 867 868 869 870 871
  if (simple->handle_cancellation &&
      g_cancellable_is_cancelled (data->cancellable))
    g_simple_async_result_set_error (simple,
                                     G_IO_ERROR,
                                     G_IO_ERROR_CANCELLED,
                                     "%s", _("Operation was cancelled"));
872
 
873 874 875 876 877 878
  g_simple_async_result_complete (simple);

  if (data->cancellable)
    g_object_unref (data->cancellable);
  g_object_unref (data->simple);
  g_free (data);
879
 
880 881 882
  return FALSE;
}

883 884 885 886
static gboolean
run_in_thread (GIOSchedulerJob *job,
               GCancellable    *c,
               gpointer         _data)
887 888 889
{
  RunInThreadData *data = _data;
  GSimpleAsyncResult *simple = data->simple;
890
  GSource *source;
891
 
892 893
  if (simple->handle_cancellation &&
      g_cancellable_is_cancelled (c))
894 895 896
    g_simple_async_result_set_error (simple,
                                     G_IO_ERROR,
                                     G_IO_ERROR_CANCELLED,
897
                                     "%s", _("Operation was cancelled"));
898
  else
899 900 901
    data->func (simple,
                simple->source_object,
                c);
902

903 904 905
  source = g_idle_source_new ();
  g_source_set_priority (source, G_PRIORITY_DEFAULT);
  g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
906
  g_source_set_name (source, "[gio] complete_in_idle_cb_for_thread");
907

908
  g_source_attach (source, simple->context);
909
  g_source_unref (source);
910 911

  return FALSE;
912 913 914
}

/**
915
 * g_simple_async_result_run_in_thread: (skip)
916 917
 * @simple: a #GSimpleAsyncResult.
 * @func: a #GSimpleAsyncThreadFunc.
918
 * @io_priority: the io priority of the request.
919
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
920
 *
921 922 923
 * Runs the asynchronous job in a separate thread and then calls
 * g_simple_async_result_complete_in_idle() on @simple to return
 * the result to the appropriate main loop.
924 925 926
 *
 * Calling this function takes a reference to @simple for as long as
 * is needed to run the job and report its completion.
927 928
 *
 * Deprecated: 2.46: Use #GTask and g_task_run_in_thread() instead.
929
 */
930
void
931 932
g_simple_async_result_run_in_thread (GSimpleAsyncResult     *simple,
                                     GSimpleAsyncThreadFunc  func,
933
                                     int                     io_priority,
934
                                     GCancellable           *cancellable)
935 936
{
  RunInThreadData *data;
937

938 939 940 941 942 943
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (func != NULL);

  data = g_new (RunInThreadData, 1);
  data->func = func;
  data->simple = g_object_ref (simple);
944 945 946
  data->cancellable = cancellable;
  if (cancellable)
    g_object_ref (cancellable);
947
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
948
  g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
949
  G_GNUC_END_IGNORE_DEPRECATIONS;
950 951
}

952 953 954
/**
 * g_simple_async_result_is_valid:
 * @result: the #GAsyncResult passed to the _finish function.
955 956
 * @source: (nullable): the #GObject passed to the _finish function.
 * @source_tag: (nullable): the asynchronous function.
957 958 959
 *
 * Ensures that the data passed to the _finish function of an async
 * operation is consistent.  Three checks are performed.
960
 *
961 962 963
 * First, @result is checked to ensure that it is really a
 * #GSimpleAsyncResult.  Second, @source is checked to ensure that it
 * matches the source object of @result.  Third, @source_tag is
964 965 966 967 968 969
 * checked to ensure that it is equal to the @source_tag argument given
 * to g_simple_async_result_new() (which, by convention, is a pointer
 * to the _async function corresponding to the _finish function from
 * which this function is called).  (Alternatively, if either
 * @source_tag or @result's source tag is %NULL, then the source tag
 * check is skipped.)
970 971
 *
 * Returns: #TRUE if all checks passed or #FALSE if any failed.
Matthias Clasen's avatar
Matthias Clasen committed
972 973
 *
 * Since: 2.20
974 975
 *
 * Deprecated: 2.46: Use #GTask and g_task_is_valid() instead.
976
 **/
977 978 979 980 981 982 983
gboolean
g_simple_async_result_is_valid (GAsyncResult *result,
                                GObject      *source,
                                gpointer      source_tag)
{
  GSimpleAsyncResult *simple;
  GObject *cmp_source;
984
  gpointer result_source_tag;
985 986 987 988 989 990 991 992

  if (!G_IS_SIMPLE_ASYNC_RESULT (result))
    return FALSE;
  simple = (GSimpleAsyncResult *)result;

  cmp_source = g_async_result_get_source_object (result);
  if (cmp_source != source)
    {
993 994
      if (cmp_source != NULL)
        g_object_unref (cmp_source);
995 996
      return FALSE;
    }
997 998
  if (cmp_source != NULL)
    g_object_unref (cmp_source);
999

1000 1001 1002
  result_source_tag = g_simple_async_result_get_source_tag (simple);
  return source_tag == NULL || result_source_tag == NULL ||
         source_tag == result_source_tag;
1003 1004
}

1005
/**
1006
 * g_simple_async_report_error_in_idle: (skip)
1007
 * @object: (nullable): a #GObject, or %NULL.
1008
 * @callback: a #GAsyncReadyCallback.
1009 1010 1011 1012
 * @user_data: user data passed to @callback.
 * @domain: a #GQuark containing the error domain (usually #G_IO_ERROR).
 * @code: a specific error code.
 * @format: a formatted error reporting string.
1013
 * @...: a list of variables to fill in @format.
1014 1015
 *
 * Reports an error in an asynchronous function in an idle function by
1016 1017
 * directly setting the contents of the #GAsyncResult with the given error
 * information.
1018 1019
 *
 * Deprecated: 2.46: Use g_task_report_error().
1020 1021
 **/
void
1022 1023 1024 1025 1026 1027 1028
g_simple_async_report_error_in_idle (GObject             *object,
                                     GAsyncReadyCallback  callback,
                                     gpointer             user_data,
                                     GQuark               domain,
                                     gint                 code,
                                     const char          *format,
                                     ...)
1029 1030 1031
{
  GSimpleAsyncResult *simple;
  va_list args;
1032
 
1033
  g_return_if_fail (!object || G_IS_OBJECT (object));
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
  g_return_if_fail (domain != 0);
  g_return_if_fail (format != NULL);

  simple = g_simple_async_result_new (object,
				      callback,
				      user_data, NULL);

  va_start (args, format);
  g_simple_async_result_set_error_va (simple, domain, code, format, args);
  va_end (args);
  g_simple_async_result_complete_in_idle (simple);
  g_object_unref (simple);
}
1047

1048
/**
1049
 * g_simple_async_report_gerror_in_idle:
1050
 * @object: (nullable): a #GObject, or %NULL
1051 1052
 * @callback: (scope async): a #GAsyncReadyCallback.
 * @user_data: (closure): user data passed to @callback.
1053
 * @error: the #GError to report
1054 1055 1056
 *
 * Reports an error in an idle function. Similar to
 * g_simple_async_report_error_in_idle(), but takes a #GError rather
1057
 * than building a new one.
1058 1059
 *
 * Deprecated: 2.46: Use g_task_report_error().
1060 1061 1062 1063 1064
 **/
void
g_simple_async_report_gerror_in_idle (GObject *object,
				      GAsyncReadyCallback callback,
				      gpointer user_data,
1065
				      const GError *error)
1066 1067
{
  GSimpleAsyncResult *simple;
1068
 
1069
  g_return_if_fail (!object || G_IS_OBJECT (object));
1070 1071 1072 1073 1074 1075 1076 1077 1078
  g_return_if_fail (error != NULL);

  simple = g_simple_async_result_new_from_error (object,
						 callback,
						 user_data,
						 error);
  g_simple_async_result_complete_in_idle (simple);
  g_object_unref (simple);
}
1079 1080

/**
1081
 * g_simple_async_report_take_gerror_in_idle: (skip)
1082
 * @object: (nullable): a #GObject, or %NULL
1083 1084 1085 1086 1087 1088 1089 1090 1091
 * @callback: a #GAsyncReadyCallback.
 * @user_data: user data passed to @callback.
 * @error: the #GError to report
 *
 * Reports an error in an idle function. Similar to
 * g_simple_async_report_gerror_in_idle(), but takes over the caller's
 * ownership of @error, so the caller does not have to free it any more.
 *
 * Since: 2.28
1092 1093
 *
 * Deprecated: 2.46: Use g_task_report_error().
1094 1095 1096 1097 1098 1099 1100 1101 1102
 **/
void
g_simple_async_report_take_gerror_in_idle (GObject *object,
                                           GAsyncReadyCallback callback,
                                           gpointer user_data,
                                           GError *error)
{
  GSimpleAsyncResult *simple;

1103
  g_return_if_fail (!object || G_IS_OBJECT (object));
1104 1105 1106 1107 1108 1109 1110 1111 1112
  g_return_if_fail (error != NULL);

  simple = g_simple_async_result_new_take_error (object,
                                                 callback,
                                                 user_data,
                                                 error);
  g_simple_async_result_complete_in_idle (simple);
  g_object_unref (simple);
}
1113 1114 1115 1116

/**
 * g_simple_async_result_set_check_cancellable:
 * @simple: a #GSimpleAsyncResult
1117
 * @check_cancellable: (nullable): a #GCancellable to check, or %NULL to unset
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
 *
 * Sets a #GCancellable to check before dispatching results.
 *
 * This function has one very specific purpose: the provided cancellable
 * is checked at the time of g_simple_async_result_propagate_error() If
 * it is cancelled, these functions will return an "Operation was
 * cancelled" error (%G_IO_ERROR_CANCELLED).
 *
 * Implementors of cancellable asynchronous functions should use this in
 * order to provide a guarantee to their callers that cancelling an
 * async operation will reliably result in an error being returned for
 * that operation (even if a positive result for the operation has
 * already been sent as an idle to the main context to be dispatched).
 *
 * The checking described above is done regardless of any call to the
 * unrelated g_simple_async_result_set_handle_cancellation() function.
 *
 * Since: 2.32
1136 1137
 *
 * Deprecated: 2.46: Use #GTask instead.
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
 **/
void
g_simple_async_result_set_check_cancellable (GSimpleAsyncResult *simple,
                                             GCancellable *check_cancellable)
{
  g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
  g_return_if_fail (check_cancellable == NULL || G_IS_CANCELLABLE (check_cancellable));

  g_clear_object (&simple->check_cancellable);
  if (check_cancellable)
    simple->check_cancellable = g_object_ref (check_cancellable);
}
1150 1151

G_GNUC_END_IGNORE_DEPRECATIONS