Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright (C) 2006-2007 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Alexander Larsson <alexl@redhat.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <string.h>
26 : :
27 : : #include "gsimpleasyncresult.h"
28 : : #include "gasyncresult.h"
29 : : #include "gcancellable.h"
30 : : #include "gioscheduler.h"
31 : : #include <gio/gioerror.h>
32 : : #include "glibintl.h"
33 : :
34 : :
35 : : /**
36 : : * GSimpleAsyncResult:
37 : : *
38 : : * As of GLib 2.46, `GSimpleAsyncResult` is deprecated in favor of
39 : : * [class@Gio.Task], which provides a simpler API.
40 : : *
41 : : * `GSimpleAsyncResult` implements [iface@Gio.AsyncResult].
42 : : *
43 : : * `GSimpleAsyncResult` handles [type@Gio.AsyncReadyCallback]s, error
44 : : * reporting, operation cancellation and the final state of an operation,
45 : : * completely transparent to the application. Results can be returned
46 : : * as a pointer e.g. for functions that return data that is collected
47 : : * asynchronously, a boolean value for checking the success or failure
48 : : * of an operation, or a `gssize` for operations which return the number
49 : : * of bytes modified by the operation; all of the simple return cases
50 : : * are covered.
51 : : *
52 : : * Most of the time, an application will not need to know of the details
53 : : * of this API; it is handled transparently, and any necessary operations
54 : : * are handled by [iface@Gio.AsyncResult]’s interface. However, if implementing
55 : : * a new GIO module, for writing language bindings, or for complex
56 : : * applications that need better control of how asynchronous operations
57 : : * are completed, it is important to understand this functionality.
58 : : *
59 : : * `GSimpleAsyncResult`s are tagged with the calling function to ensure
60 : : * that asynchronous functions and their finishing functions are used
61 : : * together correctly.
62 : : *
63 : : * To create a new `GSimpleAsyncResult`, call [ctor@Gio.SimpleAsyncResult.new].
64 : : * If the result needs to be created for a `GError`, use
65 : : * [ctor@Gio.SimpleAsyncResult.new_from_error] or
66 : : * [ctor@Gio.SimpleAsyncResult.new_take_error]. If a `GError` is not available
67 : : * (e.g. the asynchronous operation doesn’t take a `GError` argument),
68 : : * but the result still needs to be created for an error condition, use
69 : : * [ctor@Gio.SimpleAsyncResult.new_error] (or
70 : : * [method@Gio.SimpleAsyncResult.set_error_va] if your application or binding
71 : : * requires passing a variable argument list directly), and the error can then
72 : : * be propagated through the use of
73 : : * [method@Gio.SimpleAsyncResult.propagate_error].
74 : : *
75 : : * An asynchronous operation can be made to ignore a cancellation event by
76 : : * calling [method@Gio.SimpleAsyncResult.set_handle_cancellation] with a
77 : : * `GSimpleAsyncResult` for the operation and `FALSE`. This is useful for
78 : : * operations that are dangerous to cancel, such as close (which would
79 : : * cause a leak if cancelled before being run).
80 : : *
81 : : * `GSimpleAsyncResult` can integrate into GLib’s event loop,
82 : : * [type@GLib.MainLoop], or it can use [type@GLib.Thread]s.
83 : : * [method@Gio.SimpleAsyncResult.complete] will finish an I/O task directly
84 : : * from the point where it is called.
85 : : * [method@Gio.SimpleAsyncResult.complete_in_idle] will finish it from an idle
86 : : * handler in the thread-default main context (see
87 : : * [method@GLib.MainContext.push_thread_default]) where the `GSimpleAsyncResult`
88 : : * was created. [method@Gio.SimpleAsyncResult.run_in_thread] will run the job in
89 : : * a separate thread and then use
90 : : * [method@Gio.SimpleAsyncResult.complete_in_idle] to deliver the result.
91 : : *
92 : : * To set the results of an asynchronous function,
93 : : * [method@Gio.SimpleAsyncResult.set_op_res_gpointer],
94 : : * [method@Gio.SimpleAsyncResult.set_op_res_gboolean], and
95 : : * [method@Gio.SimpleAsyncResult.set_op_res_gssize]
96 : : * are provided, setting the operation's result to a `gpointer`, `gboolean`, or
97 : : * `gssize`, respectively.
98 : : *
99 : : * Likewise, to get the result of an asynchronous function,
100 : : * [method@Gio.SimpleAsyncResult.get_op_res_gpointer],
101 : : * [method@Gio.SimpleAsyncResult.get_op_res_gboolean], and
102 : : * [method@Gio.SimpleAsyncResult.get_op_res_gssize] are
103 : : * provided, getting the operation’s result as a `gpointer`, `gboolean`, and
104 : : * `gssize`, respectively.
105 : : *
106 : : * For the details of the requirements implementations must respect, see
107 : : * [iface@Gio.AsyncResult]. A typical implementation of an asynchronous
108 : : * operation using `GSimpleAsyncResult` looks something like this:
109 : : *
110 : : * ```c
111 : : * static void
112 : : * baked_cb (Cake *cake,
113 : : * gpointer user_data)
114 : : * {
115 : : * // In this example, this callback is not given a reference to the cake,
116 : : * // so the GSimpleAsyncResult has to take a reference to it.
117 : : * GSimpleAsyncResult *result = user_data;
118 : : *
119 : : * if (cake == NULL)
120 : : * g_simple_async_result_set_error (result,
121 : : * BAKER_ERRORS,
122 : : * BAKER_ERROR_NO_FLOUR,
123 : : * "Go to the supermarket");
124 : : * else
125 : : * g_simple_async_result_set_op_res_gpointer (result,
126 : : * g_object_ref (cake),
127 : : * g_object_unref);
128 : : *
129 : : *
130 : : * // In this example, we assume that baked_cb is called as a callback from
131 : : * // the mainloop, so it's safe to complete the operation synchronously here.
132 : : * // If, however, _baker_prepare_cake () might call its callback without
133 : : * // first returning to the mainloop — inadvisable, but some APIs do so —
134 : : * // we would need to use g_simple_async_result_complete_in_idle().
135 : : * g_simple_async_result_complete (result);
136 : : * g_object_unref (result);
137 : : * }
138 : : *
139 : : * void
140 : : * baker_bake_cake_async (Baker *self,
141 : : * guint radius,
142 : : * GAsyncReadyCallback callback,
143 : : * gpointer user_data)
144 : : * {
145 : : * GSimpleAsyncResult *simple;
146 : : * Cake *cake;
147 : : *
148 : : * if (radius < 3)
149 : : * {
150 : : * g_simple_async_report_error_in_idle (G_OBJECT (self),
151 : : * callback,
152 : : * user_data,
153 : : * BAKER_ERRORS,
154 : : * BAKER_ERROR_TOO_SMALL,
155 : : * "%ucm radius cakes are silly",
156 : : * radius);
157 : : * return;
158 : : * }
159 : : *
160 : : * simple = g_simple_async_result_new (G_OBJECT (self),
161 : : * callback,
162 : : * user_data,
163 : : * baker_bake_cake_async);
164 : : * cake = _baker_get_cached_cake (self, radius);
165 : : *
166 : : * if (cake != NULL)
167 : : * {
168 : : * g_simple_async_result_set_op_res_gpointer (simple,
169 : : * g_object_ref (cake),
170 : : * g_object_unref);
171 : : * g_simple_async_result_complete_in_idle (simple);
172 : : * g_object_unref (simple);
173 : : * // Drop the reference returned by _baker_get_cached_cake();
174 : : * // the GSimpleAsyncResult has taken its own reference.
175 : : * g_object_unref (cake);
176 : : * return;
177 : : * }
178 : : *
179 : : * _baker_prepare_cake (self, radius, baked_cb, simple);
180 : : * }
181 : : *
182 : : * Cake *
183 : : * baker_bake_cake_finish (Baker *self,
184 : : * GAsyncResult *result,
185 : : * GError **error)
186 : : * {
187 : : * GSimpleAsyncResult *simple;
188 : : * Cake *cake;
189 : : *
190 : : * g_return_val_if_fail (g_simple_async_result_is_valid (result,
191 : : * G_OBJECT (self),
192 : : * baker_bake_cake_async),
193 : : * NULL);
194 : : *
195 : : * simple = (GSimpleAsyncResult *) result;
196 : : *
197 : : * if (g_simple_async_result_propagate_error (simple, error))
198 : : * return NULL;
199 : : *
200 : : * cake = CAKE (g_simple_async_result_get_op_res_gpointer (simple));
201 : : * return g_object_ref (cake);
202 : : * }
203 : : * ```
204 : : */
205 : :
206 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
207 : :
208 : : static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
209 : :
210 : : struct _GSimpleAsyncResult
211 : : {
212 : : GObject parent_instance;
213 : :
214 : : GObject *source_object;
215 : : GAsyncReadyCallback callback;
216 : : gpointer user_data;
217 : : GMainContext *context;
218 : : GError *error;
219 : : gboolean failed;
220 : : gboolean handle_cancellation;
221 : : GCancellable *check_cancellable;
222 : :
223 : : gpointer source_tag;
224 : :
225 : : union {
226 : : gpointer v_pointer;
227 : : gboolean v_boolean;
228 : : gssize v_ssize;
229 : : } op_res;
230 : :
231 : : GDestroyNotify destroy_op_res;
232 : : };
233 : :
234 : : struct _GSimpleAsyncResultClass
235 : : {
236 : : GObjectClass parent_class;
237 : : };
238 : :
239 : :
240 : 34591 : G_DEFINE_TYPE_WITH_CODE (GSimpleAsyncResult, g_simple_async_result, G_TYPE_OBJECT,
241 : : G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT,
242 : : g_simple_async_result_async_result_iface_init))
243 : :
244 : : static void
245 : 8 : clear_op_res (GSimpleAsyncResult *simple)
246 : : {
247 : 8 : if (simple->destroy_op_res)
248 : 0 : simple->destroy_op_res (simple->op_res.v_pointer);
249 : 8 : simple->destroy_op_res = NULL;
250 : 8 : simple->op_res.v_ssize = 0;
251 : 8 : }
252 : :
253 : : static void
254 : 8 : g_simple_async_result_finalize (GObject *object)
255 : : {
256 : : GSimpleAsyncResult *simple;
257 : :
258 : 8 : simple = G_SIMPLE_ASYNC_RESULT (object);
259 : :
260 : 8 : if (simple->source_object)
261 : 4 : g_object_unref (simple->source_object);
262 : :
263 : 8 : if (simple->check_cancellable)
264 : 0 : g_object_unref (simple->check_cancellable);
265 : :
266 : 8 : g_main_context_unref (simple->context);
267 : :
268 : 8 : clear_op_res (simple);
269 : :
270 : 8 : if (simple->error)
271 : 0 : g_error_free (simple->error);
272 : :
273 : 8 : G_OBJECT_CLASS (g_simple_async_result_parent_class)->finalize (object);
274 : 8 : }
275 : :
276 : : static void
277 : 4 : g_simple_async_result_class_init (GSimpleAsyncResultClass *klass)
278 : : {
279 : 4 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
280 : :
281 : 4 : gobject_class->finalize = g_simple_async_result_finalize;
282 : 4 : }
283 : :
284 : : static void
285 : 8 : g_simple_async_result_init (GSimpleAsyncResult *simple)
286 : : {
287 : 8 : simple->handle_cancellation = TRUE;
288 : :
289 : 8 : simple->context = g_main_context_ref_thread_default ();
290 : 8 : }
291 : :
292 : : /**
293 : : * g_simple_async_result_new:
294 : : * @source_object: (nullable): a #GObject, or %NULL.
295 : : * @callback: (scope async): a #GAsyncReadyCallback.
296 : : * @user_data: user data passed to @callback.
297 : : * @source_tag: the asynchronous function.
298 : : *
299 : : * Creates a #GSimpleAsyncResult.
300 : : *
301 : : * The common convention is to create the #GSimpleAsyncResult in the
302 : : * function that starts the asynchronous operation and use that same
303 : : * function as the @source_tag.
304 : : *
305 : : * If your operation supports cancellation with #GCancellable (which it
306 : : * probably should) then you should provide the user's cancellable to
307 : : * g_simple_async_result_set_check_cancellable() immediately after
308 : : * this function returns.
309 : : *
310 : : * Returns: a #GSimpleAsyncResult.
311 : : *
312 : : * Deprecated: 2.46: Use g_task_new() instead.
313 : : **/
314 : : GSimpleAsyncResult *
315 : 7 : g_simple_async_result_new (GObject *source_object,
316 : : GAsyncReadyCallback callback,
317 : : gpointer user_data,
318 : : gpointer source_tag)
319 : : {
320 : : GSimpleAsyncResult *simple;
321 : :
322 : 7 : g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
323 : :
324 : 7 : simple = g_object_new (G_TYPE_SIMPLE_ASYNC_RESULT, NULL);
325 : 7 : simple->callback = callback;
326 : 7 : if (source_object)
327 : 4 : simple->source_object = g_object_ref (source_object);
328 : : else
329 : 3 : simple->source_object = NULL;
330 : 7 : simple->user_data = user_data;
331 : 7 : simple->source_tag = source_tag;
332 : :
333 : 7 : return simple;
334 : : }
335 : :
336 : : /**
337 : : * g_simple_async_result_new_from_error:
338 : : * @source_object: (nullable): a #GObject, or %NULL.
339 : : * @callback: (scope async): a #GAsyncReadyCallback.
340 : : * @user_data: 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 : 0 : g_simple_async_result_new_from_error (GObject *source_object,
351 : : GAsyncReadyCallback callback,
352 : : gpointer user_data,
353 : : const GError *error)
354 : : {
355 : : GSimpleAsyncResult *simple;
356 : :
357 : 0 : g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
358 : :
359 : 0 : simple = g_simple_async_result_new (source_object,
360 : : callback,
361 : : user_data, NULL);
362 : 0 : g_simple_async_result_set_from_error (simple, error);
363 : :
364 : 0 : return simple;
365 : : }
366 : :
367 : : /**
368 : : * g_simple_async_result_new_take_error: (skip)
369 : : * @source_object: (nullable): a #GObject, or %NULL
370 : : * @callback: (scope async): a #GAsyncReadyCallback.
371 : : * @user_data: user data passed to @callback.
372 : : * @error: a #GError
373 : : *
374 : : * Creates a #GSimpleAsyncResult from an error condition, and takes over the
375 : : * caller's ownership of @error, so the caller does not need to free it anymore.
376 : : *
377 : : * Returns: a #GSimpleAsyncResult
378 : : *
379 : : * Since: 2.28
380 : : *
381 : : * Deprecated: 2.46: Use g_task_new() and g_task_return_error() instead.
382 : : **/
383 : : GSimpleAsyncResult *
384 : 0 : g_simple_async_result_new_take_error (GObject *source_object,
385 : : GAsyncReadyCallback callback,
386 : : gpointer user_data,
387 : : GError *error)
388 : : {
389 : : GSimpleAsyncResult *simple;
390 : :
391 : 0 : g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
392 : :
393 : 0 : simple = g_simple_async_result_new (source_object,
394 : : callback,
395 : : user_data, NULL);
396 : 0 : g_simple_async_result_take_error (simple, error);
397 : :
398 : 0 : return simple;
399 : : }
400 : :
401 : : /**
402 : : * g_simple_async_result_new_error:
403 : : * @source_object: (nullable): a #GObject, or %NULL.
404 : : * @callback: (scope async): a #GAsyncReadyCallback.
405 : : * @user_data: user data passed to @callback.
406 : : * @domain: a #GQuark.
407 : : * @code: an error code.
408 : : * @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 : 0 : g_simple_async_result_new_error (GObject *source_object,
419 : : GAsyncReadyCallback callback,
420 : : gpointer user_data,
421 : : GQuark domain,
422 : : gint code,
423 : : const char *format,
424 : : ...)
425 : : {
426 : : GSimpleAsyncResult *simple;
427 : : va_list args;
428 : :
429 : 0 : g_return_val_if_fail (!source_object || G_IS_OBJECT (source_object), NULL);
430 : 0 : g_return_val_if_fail (domain != 0, NULL);
431 : 0 : g_return_val_if_fail (format != NULL, NULL);
432 : :
433 : 0 : simple = g_simple_async_result_new (source_object,
434 : : callback,
435 : : user_data, NULL);
436 : :
437 : 0 : va_start (args, format);
438 : 0 : g_simple_async_result_set_error_va (simple, domain, code, format, args);
439 : 0 : va_end (args);
440 : :
441 : 0 : return simple;
442 : : }
443 : :
444 : :
445 : : static gpointer
446 : 2 : g_simple_async_result_get_user_data (GAsyncResult *res)
447 : : {
448 : 2 : return G_SIMPLE_ASYNC_RESULT (res)->user_data;
449 : : }
450 : :
451 : : static GObject *
452 : 35 : g_simple_async_result_get_source_object (GAsyncResult *res)
453 : : {
454 : 35 : if (G_SIMPLE_ASYNC_RESULT (res)->source_object)
455 : 22 : return g_object_ref (G_SIMPLE_ASYNC_RESULT (res)->source_object);
456 : 13 : return NULL;
457 : : }
458 : :
459 : : static gboolean
460 : 1 : g_simple_async_result_is_tagged (GAsyncResult *res,
461 : : gpointer source_tag)
462 : : {
463 : 1 : return G_SIMPLE_ASYNC_RESULT (res)->source_tag == source_tag;
464 : : }
465 : :
466 : : static void
467 : 4 : g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface)
468 : : {
469 : 4 : iface->get_user_data = g_simple_async_result_get_user_data;
470 : 4 : iface->get_source_object = g_simple_async_result_get_source_object;
471 : 4 : iface->is_tagged = g_simple_async_result_is_tagged;
472 : 4 : }
473 : :
474 : : /**
475 : : * g_simple_async_result_set_handle_cancellation:
476 : : * @simple: a #GSimpleAsyncResult.
477 : : * @handle_cancellation: a #gboolean.
478 : : *
479 : : * Sets whether to handle cancellation within the asynchronous operation.
480 : : *
481 : : * This function has nothing to do with
482 : : * g_simple_async_result_set_check_cancellable(). It only refers to the
483 : : * #GCancellable passed to g_simple_async_result_run_in_thread().
484 : : *
485 : : * Deprecated: 2.46
486 : : **/
487 : : void
488 : 0 : g_simple_async_result_set_handle_cancellation (GSimpleAsyncResult *simple,
489 : : gboolean handle_cancellation)
490 : : {
491 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
492 : 0 : simple->handle_cancellation = handle_cancellation;
493 : : }
494 : :
495 : : /**
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 : : gpointer
506 : 14 : g_simple_async_result_get_source_tag (GSimpleAsyncResult *simple)
507 : : {
508 : 14 : g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
509 : 14 : return simple->source_tag;
510 : : }
511 : :
512 : : /**
513 : : * g_simple_async_result_propagate_error:
514 : : * @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 : : * If the #GCancellable given to a prior call to
521 : : * g_simple_async_result_set_check_cancellable() is cancelled then this
522 : : * function will return %TRUE with @dest set appropriately.
523 : : *
524 : : * Returns: %TRUE if the error was propagated to @dest. %FALSE otherwise.
525 : : *
526 : : * Deprecated: 2.46: Use #GTask instead.
527 : : **/
528 : : gboolean
529 : 1 : g_simple_async_result_propagate_error (GSimpleAsyncResult *simple,
530 : : GError **dest)
531 : : {
532 : 1 : g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
533 : :
534 : 1 : if (g_cancellable_set_error_if_cancelled (simple->check_cancellable, dest))
535 : 0 : return TRUE;
536 : :
537 : 1 : if (simple->failed)
538 : : {
539 : 1 : g_propagate_error (dest, simple->error);
540 : 1 : simple->error = NULL;
541 : 1 : return TRUE;
542 : : }
543 : :
544 : 0 : return FALSE;
545 : : }
546 : :
547 : : /**
548 : : * g_simple_async_result_set_op_res_gpointer: (skip)
549 : : * @simple: a #GSimpleAsyncResult.
550 : : * @op_res: a pointer result from an asynchronous function.
551 : : * @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 : 0 : g_simple_async_result_set_op_res_gpointer (GSimpleAsyncResult *simple,
559 : : gpointer op_res,
560 : : GDestroyNotify destroy_op_res)
561 : : {
562 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
563 : :
564 : 0 : clear_op_res (simple);
565 : 0 : simple->op_res.v_pointer = op_res;
566 : 0 : simple->destroy_op_res = destroy_op_res;
567 : : }
568 : :
569 : : /**
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 : 0 : g_simple_async_result_get_op_res_gpointer (GSimpleAsyncResult *simple)
581 : : {
582 : 0 : g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
583 : 0 : return simple->op_res.v_pointer;
584 : : }
585 : :
586 : : /**
587 : : * g_simple_async_result_set_op_res_gssize:
588 : : * @simple: a #GSimpleAsyncResult.
589 : : * @op_res: a #gssize.
590 : : *
591 : : * Sets the operation result within the asynchronous result to
592 : : * the given @op_res.
593 : : *
594 : : * Deprecated: 2.46: Use #GTask and g_task_return_int() instead.
595 : : **/
596 : : void
597 : 0 : g_simple_async_result_set_op_res_gssize (GSimpleAsyncResult *simple,
598 : : gssize op_res)
599 : : {
600 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
601 : 0 : clear_op_res (simple);
602 : 0 : simple->op_res.v_ssize = op_res;
603 : : }
604 : :
605 : : /**
606 : : * 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 : 0 : g_simple_async_result_get_op_res_gssize (GSimpleAsyncResult *simple)
617 : : {
618 : 0 : g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), 0);
619 : 0 : return simple->op_res.v_ssize;
620 : : }
621 : :
622 : : /**
623 : : * g_simple_async_result_set_op_res_gboolean:
624 : : * @simple: a #GSimpleAsyncResult.
625 : : * @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 : 0 : g_simple_async_result_set_op_res_gboolean (GSimpleAsyncResult *simple,
633 : : gboolean op_res)
634 : : {
635 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
636 : 0 : clear_op_res (simple);
637 : 0 : simple->op_res.v_boolean = !!op_res;
638 : : }
639 : :
640 : : /**
641 : : * 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 : : * Returns: %TRUE if the operation's result was %TRUE, %FALSE
647 : : * if the operation's result was %FALSE.
648 : : *
649 : : * Deprecated: 2.46: Use #GTask and g_task_propagate_boolean() instead.
650 : : **/
651 : : gboolean
652 : 0 : g_simple_async_result_get_op_res_gboolean (GSimpleAsyncResult *simple)
653 : : {
654 : 0 : g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), FALSE);
655 : 0 : return simple->op_res.v_boolean;
656 : : }
657 : :
658 : : /**
659 : : * 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 : : void
668 : 0 : g_simple_async_result_set_from_error (GSimpleAsyncResult *simple,
669 : : const GError *error)
670 : : {
671 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
672 : 0 : g_return_if_fail (error != NULL);
673 : :
674 : 0 : if (simple->error)
675 : 0 : g_error_free (simple->error);
676 : 0 : simple->error = g_error_copy (error);
677 : 0 : simple->failed = TRUE;
678 : : }
679 : :
680 : : /**
681 : : * g_simple_async_result_take_error: (skip)
682 : : * @simple: a #GSimpleAsyncResult
683 : : * @error: a #GError
684 : : *
685 : : * Sets the result from @error, and takes over the caller's ownership
686 : : * of @error, so the caller does not need to free it any more.
687 : : *
688 : : * Since: 2.28
689 : : *
690 : : * Deprecated: 2.46: Use #GTask and g_task_return_error() instead.
691 : : **/
692 : : void
693 : 0 : g_simple_async_result_take_error (GSimpleAsyncResult *simple,
694 : : GError *error)
695 : : {
696 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
697 : 0 : g_return_if_fail (error != NULL);
698 : :
699 : 0 : if (simple->error)
700 : 0 : g_error_free (simple->error);
701 : 0 : simple->error = error;
702 : 0 : simple->failed = TRUE;
703 : : }
704 : :
705 : : /**
706 : : * g_simple_async_result_set_error_va: (skip)
707 : : * @simple: a #GSimpleAsyncResult.
708 : : * @domain: a #GQuark (usually %G_IO_ERROR).
709 : : * @code: an error code.
710 : : * @format: a formatted error reporting string.
711 : : * @args: va_list of arguments.
712 : : *
713 : : * 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 : : void
719 : 1 : g_simple_async_result_set_error_va (GSimpleAsyncResult *simple,
720 : : GQuark domain,
721 : : gint code,
722 : : const char *format,
723 : : va_list args)
724 : : {
725 : 1 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
726 : 1 : g_return_if_fail (domain != 0);
727 : 1 : g_return_if_fail (format != NULL);
728 : :
729 : 1 : if (simple->error)
730 : 0 : g_error_free (simple->error);
731 : 1 : simple->error = g_error_new_valist (domain, code, format, args);
732 : 1 : simple->failed = TRUE;
733 : : }
734 : :
735 : : /**
736 : : * g_simple_async_result_set_error: (skip)
737 : : * @simple: a #GSimpleAsyncResult.
738 : : * @domain: a #GQuark (usually %G_IO_ERROR).
739 : : * @code: an error code.
740 : : * @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 : : void
748 : 1 : g_simple_async_result_set_error (GSimpleAsyncResult *simple,
749 : : GQuark domain,
750 : : gint code,
751 : : const char *format,
752 : : ...)
753 : : {
754 : : va_list args;
755 : :
756 : 1 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
757 : 1 : g_return_if_fail (domain != 0);
758 : 1 : g_return_if_fail (format != NULL);
759 : :
760 : 1 : va_start (args, format);
761 : 1 : g_simple_async_result_set_error_va (simple, domain, code, format, args);
762 : 1 : va_end (args);
763 : : }
764 : :
765 : : /**
766 : : * g_simple_async_result_complete:
767 : : * @simple: a #GSimpleAsyncResult.
768 : : *
769 : : * Completes an asynchronous I/O job immediately. Must be called in
770 : : * the thread where the asynchronous result was to be delivered, as it
771 : : * invokes the callback directly. If you are in a different thread use
772 : : * g_simple_async_result_complete_in_idle().
773 : : *
774 : : * Calling this function takes a reference to @simple for as long as
775 : : * is needed to complete the call.
776 : : *
777 : : * Deprecated: 2.46: Use #GTask instead.
778 : : **/
779 : : void
780 : 3 : g_simple_async_result_complete (GSimpleAsyncResult *simple)
781 : : {
782 : : #ifndef G_DISABLE_CHECKS
783 : : GSource *current_source;
784 : : GMainContext *current_context;
785 : : #endif
786 : :
787 : 3 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
788 : :
789 : : #ifndef G_DISABLE_CHECKS
790 : 3 : current_source = g_main_current_source ();
791 : 3 : if (current_source && !g_source_is_destroyed (current_source))
792 : : {
793 : 3 : current_context = g_source_get_context (current_source);
794 : 3 : if (simple->context != current_context)
795 : 0 : g_warning ("g_simple_async_result_complete() called from wrong context!");
796 : : }
797 : : #endif
798 : :
799 : 3 : if (simple->callback)
800 : : {
801 : 3 : g_main_context_push_thread_default (simple->context);
802 : 3 : simple->callback (simple->source_object,
803 : 3 : G_ASYNC_RESULT (simple),
804 : : simple->user_data);
805 : 3 : g_main_context_pop_thread_default (simple->context);
806 : : }
807 : : }
808 : :
809 : : static gboolean
810 : 1 : complete_in_idle_cb (gpointer data)
811 : : {
812 : 1 : GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (data);
813 : :
814 : 1 : g_simple_async_result_complete (simple);
815 : :
816 : 1 : return FALSE;
817 : : }
818 : :
819 : : /**
820 : : * g_simple_async_result_complete_in_idle:
821 : : * @simple: a #GSimpleAsyncResult.
822 : : *
823 : : * Completes an asynchronous function in an idle handler in the
824 : : * [thread-default main context][g-main-context-push-thread-default]
825 : : * of the thread that @simple was initially created in
826 : : * (and re-pushes that context around the invocation of the callback).
827 : : *
828 : : * Calling this function takes a reference to @simple for as long as
829 : : * is needed to complete the call.
830 : : *
831 : : * Deprecated: 2.46: Use #GTask instead.
832 : : */
833 : : void
834 : 1 : g_simple_async_result_complete_in_idle (GSimpleAsyncResult *simple)
835 : : {
836 : : GSource *source;
837 : :
838 : 1 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
839 : :
840 : 1 : g_object_ref (simple);
841 : :
842 : 1 : source = g_idle_source_new ();
843 : 1 : g_source_set_priority (source, G_PRIORITY_DEFAULT);
844 : 1 : g_source_set_callback (source, complete_in_idle_cb, simple, g_object_unref);
845 : 1 : g_source_set_static_name (source, "[gio] complete_in_idle_cb");
846 : :
847 : 1 : g_source_attach (source, simple->context);
848 : 1 : g_source_unref (source);
849 : : }
850 : :
851 : : typedef struct {
852 : : GSimpleAsyncResult *simple;
853 : : GCancellable *cancellable;
854 : : GSimpleAsyncThreadFunc func;
855 : : } RunInThreadData;
856 : :
857 : :
858 : : static gboolean
859 : 0 : complete_in_idle_cb_for_thread (gpointer _data)
860 : : {
861 : 0 : RunInThreadData *data = _data;
862 : : GSimpleAsyncResult *simple;
863 : :
864 : 0 : simple = data->simple;
865 : :
866 : 0 : if (simple->handle_cancellation &&
867 : 0 : g_cancellable_is_cancelled (data->cancellable))
868 : 0 : g_simple_async_result_set_error (simple,
869 : : G_IO_ERROR,
870 : : G_IO_ERROR_CANCELLED,
871 : : "%s", _("Operation was cancelled"));
872 : :
873 : 0 : g_simple_async_result_complete (simple);
874 : :
875 : 0 : if (data->cancellable)
876 : 0 : g_object_unref (data->cancellable);
877 : 0 : g_object_unref (data->simple);
878 : 0 : g_free (data);
879 : :
880 : 0 : return FALSE;
881 : : }
882 : :
883 : : static gboolean
884 : 0 : run_in_thread (GIOSchedulerJob *job,
885 : : GCancellable *c,
886 : : gpointer _data)
887 : : {
888 : 0 : RunInThreadData *data = _data;
889 : 0 : GSimpleAsyncResult *simple = data->simple;
890 : : GSource *source;
891 : :
892 : 0 : if (simple->handle_cancellation &&
893 : 0 : g_cancellable_is_cancelled (c))
894 : 0 : g_simple_async_result_set_error (simple,
895 : : G_IO_ERROR,
896 : : G_IO_ERROR_CANCELLED,
897 : : "%s", _("Operation was cancelled"));
898 : : else
899 : 0 : data->func (simple,
900 : : simple->source_object,
901 : : c);
902 : :
903 : 0 : source = g_idle_source_new ();
904 : 0 : g_source_set_priority (source, G_PRIORITY_DEFAULT);
905 : 0 : g_source_set_callback (source, complete_in_idle_cb_for_thread, data, NULL);
906 : 0 : g_source_set_static_name (source, "[gio] complete_in_idle_cb_for_thread");
907 : :
908 : 0 : g_source_attach (source, simple->context);
909 : 0 : g_source_unref (source);
910 : :
911 : 0 : return FALSE;
912 : : }
913 : :
914 : : /**
915 : : * g_simple_async_result_run_in_thread: (skip)
916 : : * @simple: a #GSimpleAsyncResult.
917 : : * @func: a #GSimpleAsyncThreadFunc.
918 : : * @io_priority: the io priority of the request.
919 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
920 : : *
921 : : * Runs the asynchronous job in a separate thread and then calls
922 : : * g_simple_async_result_complete_in_idle() on @simple to return
923 : : * the result to the appropriate main loop.
924 : : *
925 : : * Calling this function takes a reference to @simple for as long as
926 : : * 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 : 0 : g_simple_async_result_run_in_thread (GSimpleAsyncResult *simple,
932 : : GSimpleAsyncThreadFunc func,
933 : : int io_priority,
934 : : GCancellable *cancellable)
935 : : {
936 : : RunInThreadData *data;
937 : :
938 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
939 : 0 : g_return_if_fail (func != NULL);
940 : :
941 : 0 : data = g_new (RunInThreadData, 1);
942 : 0 : data->func = func;
943 : 0 : data->simple = g_object_ref (simple);
944 : 0 : data->cancellable = cancellable;
945 : 0 : if (cancellable)
946 : 0 : g_object_ref (cancellable);
947 : : G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
948 : 0 : g_io_scheduler_push_job (run_in_thread, data, NULL, io_priority, cancellable);
949 : : G_GNUC_END_IGNORE_DEPRECATIONS;
950 : : }
951 : :
952 : : /**
953 : : * g_simple_async_result_is_valid:
954 : : * @result: the #GAsyncResult passed to the _finish function.
955 : : * @source: (nullable): the #GObject passed to the _finish function.
956 : : * @source_tag: (nullable): the asynchronous function.
957 : : *
958 : : * Ensures that the data passed to the _finish function of an async
959 : : * operation is consistent. Three checks are performed.
960 : : *
961 : : * First, @result is checked to ensure that it is really a
962 : : * #GSimpleAsyncResult. Second, @source is checked to ensure that it
963 : : * matches the source object of @result. Third, @source_tag is
964 : : * checked to ensure that it is equal to the @source_tag argument given
965 : : * to g_simple_async_result_new() (which, by convention, is a pointer
966 : : * to the _async function corresponding to the _finish function from
967 : : * which this function is called). (Alternatively, if either
968 : : * @source_tag or @result's source tag is %NULL, then the source tag
969 : : * check is skipped.)
970 : : *
971 : : * Returns: #TRUE if all checks passed or #FALSE if any failed.
972 : : *
973 : : * Since: 2.20
974 : : *
975 : : * Deprecated: 2.46: Use #GTask and g_task_is_valid() instead.
976 : : **/
977 : : gboolean
978 : 37 : g_simple_async_result_is_valid (GAsyncResult *result,
979 : : GObject *source,
980 : : gpointer source_tag)
981 : : {
982 : : GSimpleAsyncResult *simple;
983 : : GObject *cmp_source;
984 : : gpointer result_source_tag;
985 : :
986 : 37 : if (!G_IS_SIMPLE_ASYNC_RESULT (result))
987 : 2 : return FALSE;
988 : 35 : simple = (GSimpleAsyncResult *)result;
989 : :
990 : 35 : cmp_source = g_async_result_get_source_object (result);
991 : 35 : if (cmp_source != source)
992 : : {
993 : 21 : if (cmp_source != NULL)
994 : 15 : g_object_unref (cmp_source);
995 : 21 : return FALSE;
996 : : }
997 : 14 : if (cmp_source != NULL)
998 : 7 : g_object_unref (cmp_source);
999 : :
1000 : 14 : result_source_tag = g_simple_async_result_get_source_tag (simple);
1001 : 14 : return source_tag == NULL || result_source_tag == NULL ||
1002 : : 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 : : * @user_data: user data passed to @callback.
1010 : : * @domain: a #GQuark containing the error domain (usually %G_IO_ERROR).
1011 : : * @code: a specific error code.
1012 : : * @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 : : * directly setting the contents of the #GAsyncResult with the given error
1017 : : * information.
1018 : : *
1019 : : * Deprecated: 2.46: Use g_task_report_error().
1020 : : **/
1021 : : void
1022 : 0 : g_simple_async_report_error_in_idle (GObject *object,
1023 : : GAsyncReadyCallback callback,
1024 : : gpointer user_data,
1025 : : GQuark domain,
1026 : : gint code,
1027 : : const char *format,
1028 : : ...)
1029 : : {
1030 : : GSimpleAsyncResult *simple;
1031 : : va_list args;
1032 : :
1033 : 0 : g_return_if_fail (!object || G_IS_OBJECT (object));
1034 : 0 : g_return_if_fail (domain != 0);
1035 : 0 : g_return_if_fail (format != NULL);
1036 : :
1037 : 0 : simple = g_simple_async_result_new (object,
1038 : : callback,
1039 : : user_data, NULL);
1040 : :
1041 : 0 : va_start (args, format);
1042 : 0 : g_simple_async_result_set_error_va (simple, domain, code, format, args);
1043 : 0 : va_end (args);
1044 : 0 : g_simple_async_result_complete_in_idle (simple);
1045 : 0 : g_object_unref (simple);
1046 : : }
1047 : :
1048 : : /**
1049 : : * g_simple_async_report_gerror_in_idle:
1050 : : * @object: (nullable): a #GObject, or %NULL
1051 : : * @callback: (scope async): a #GAsyncReadyCallback.
1052 : : * @user_data: user data passed to @callback.
1053 : : * @error: the #GError to report
1054 : : *
1055 : : * Reports an error in an idle function. Similar to
1056 : : * 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 : : void
1062 : 0 : g_simple_async_report_gerror_in_idle (GObject *object,
1063 : : GAsyncReadyCallback callback,
1064 : : gpointer user_data,
1065 : : const GError *error)
1066 : : {
1067 : : GSimpleAsyncResult *simple;
1068 : :
1069 : 0 : g_return_if_fail (!object || G_IS_OBJECT (object));
1070 : 0 : g_return_if_fail (error != NULL);
1071 : :
1072 : 0 : simple = g_simple_async_result_new_from_error (object,
1073 : : callback,
1074 : : user_data,
1075 : : error);
1076 : 0 : g_simple_async_result_complete_in_idle (simple);
1077 : 0 : g_object_unref (simple);
1078 : : }
1079 : :
1080 : : /**
1081 : : * g_simple_async_report_take_gerror_in_idle: (skip)
1082 : : * @object: (nullable): a #GObject, or %NULL
1083 : : * @callback: a #GAsyncReadyCallback.
1084 : : * @user_data: user data passed to @callback.
1085 : : * @error: the #GError to report
1086 : : *
1087 : : * Reports an error in an idle function. Similar to
1088 : : * g_simple_async_report_gerror_in_idle(), but takes over the caller's
1089 : : * ownership of @error, so the caller does not have to free it any more.
1090 : : *
1091 : : * Since: 2.28
1092 : : *
1093 : : * Deprecated: 2.46: Use g_task_report_error().
1094 : : **/
1095 : : void
1096 : 0 : g_simple_async_report_take_gerror_in_idle (GObject *object,
1097 : : GAsyncReadyCallback callback,
1098 : : gpointer user_data,
1099 : : GError *error)
1100 : : {
1101 : : GSimpleAsyncResult *simple;
1102 : :
1103 : 0 : g_return_if_fail (!object || G_IS_OBJECT (object));
1104 : 0 : g_return_if_fail (error != NULL);
1105 : :
1106 : 0 : simple = g_simple_async_result_new_take_error (object,
1107 : : callback,
1108 : : user_data,
1109 : : error);
1110 : 0 : g_simple_async_result_complete_in_idle (simple);
1111 : 0 : g_object_unref (simple);
1112 : : }
1113 : :
1114 : : /**
1115 : : * g_simple_async_result_set_check_cancellable:
1116 : : * @simple: a #GSimpleAsyncResult
1117 : : * @check_cancellable: (nullable): a #GCancellable to check, or %NULL to unset
1118 : : *
1119 : : * Sets a #GCancellable to check before dispatching results.
1120 : : *
1121 : : * This function has one very specific purpose: the provided cancellable
1122 : : * is checked at the time of g_simple_async_result_propagate_error() If
1123 : : * it is cancelled, these functions will return an "Operation was
1124 : : * cancelled" error (%G_IO_ERROR_CANCELLED).
1125 : : *
1126 : : * Implementors of cancellable asynchronous functions should use this in
1127 : : * order to provide a guarantee to their callers that cancelling an
1128 : : * async operation will reliably result in an error being returned for
1129 : : * that operation (even if a positive result for the operation has
1130 : : * already been sent as an idle to the main context to be dispatched).
1131 : : *
1132 : : * The checking described above is done regardless of any call to the
1133 : : * unrelated g_simple_async_result_set_handle_cancellation() function.
1134 : : *
1135 : : * Since: 2.32
1136 : : *
1137 : : * Deprecated: 2.46: Use #GTask instead.
1138 : : **/
1139 : : void
1140 : 0 : g_simple_async_result_set_check_cancellable (GSimpleAsyncResult *simple,
1141 : : GCancellable *check_cancellable)
1142 : : {
1143 : 0 : g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple));
1144 : 0 : g_return_if_fail (check_cancellable == NULL || G_IS_CANCELLABLE (check_cancellable));
1145 : :
1146 : 0 : g_clear_object (&simple->check_cancellable);
1147 : 0 : if (check_cancellable)
1148 : 0 : simple->check_cancellable = g_object_ref (check_cancellable);
1149 : : }
1150 : :
1151 : : G_GNUC_END_IGNORE_DEPRECATIONS
|