Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright (C) 2006-2007 Red Hat, Inc.
4 : : * Copyright (C) 2022-2024 Canonical, Ltd.
5 : : *
6 : : * SPDX-License-Identifier: LGPL-2.1-or-later
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General
19 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 : : *
21 : : * Author: Alexander Larsson <alexl@redhat.com>
22 : : * Author: Marco Trevisan <marco.trevisan@canonical.com>
23 : : */
24 : :
25 : : #include "config.h"
26 : : #include "glib.h"
27 : : #include <gioerror.h>
28 : : #include "glib-private.h"
29 : : #include "gcancellable.h"
30 : : #include "glibintl.h"
31 : :
32 : :
33 : : /**
34 : : * GCancellable:
35 : : *
36 : : * `GCancellable` allows operations to be cancelled.
37 : : *
38 : : * `GCancellable` is a thread-safe operation cancellation stack used
39 : : * throughout GIO to allow for cancellation of synchronous and
40 : : * asynchronous operations.
41 : : */
42 : :
43 : : enum {
44 : : CANCELLED,
45 : : LAST_SIGNAL
46 : : };
47 : :
48 : : struct _GCancellablePrivate
49 : : {
50 : : /* Atomic so that we don't require holding global mutexes for independent ops. */
51 : : gboolean cancelled;
52 : : int cancelled_running;
53 : :
54 : : /* Access to fields below is protected by cancellable's mutex. */
55 : : GMutex mutex;
56 : : guint fd_refcount;
57 : : GWakeup *wakeup;
58 : : };
59 : :
60 : : static guint signals[LAST_SIGNAL] = { 0 };
61 : :
62 : 459539 : G_DEFINE_TYPE_WITH_PRIVATE (GCancellable, g_cancellable, G_TYPE_OBJECT)
63 : :
64 : : static GPrivate current_cancellable;
65 : : static GCond cancellable_cond;
66 : :
67 : : static void
68 : 103214 : g_cancellable_finalize (GObject *object)
69 : : {
70 : 103214 : GCancellable *cancellable = G_CANCELLABLE (object);
71 : :
72 : : /* We're at finalization phase, so only one thread can be here.
73 : : * Thus there's no need to lock. In case something is locking us, then we've
74 : : * a bug, and g_mutex_clear() will make this clear aborting.
75 : : */
76 : 103214 : if (cancellable->priv->wakeup)
77 : 0 : GLIB_PRIVATE_CALL (g_wakeup_free) (cancellable->priv->wakeup);
78 : :
79 : 103214 : g_mutex_clear (&cancellable->priv->mutex);
80 : :
81 : 103214 : G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object);
82 : 103214 : }
83 : :
84 : : static void
85 : 118 : g_cancellable_class_init (GCancellableClass *klass)
86 : : {
87 : 118 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
88 : :
89 : 118 : gobject_class->finalize = g_cancellable_finalize;
90 : :
91 : : /**
92 : : * GCancellable::cancelled:
93 : : * @cancellable: a #GCancellable.
94 : : *
95 : : * Emitted when the operation has been cancelled.
96 : : *
97 : : * Can be used by implementations of cancellable operations. If the
98 : : * operation is cancelled from another thread, the signal will be
99 : : * emitted in the thread that cancelled the operation, not the
100 : : * thread that is running the operation.
101 : : *
102 : : * Note that disconnecting from this signal (or any signal) in a
103 : : * multi-threaded program is prone to race conditions. For instance
104 : : * it is possible that a signal handler may be invoked even after
105 : : * a call to g_signal_handler_disconnect() for that handler has
106 : : * already returned.
107 : : *
108 : : * There is also a problem when cancellation happens right before
109 : : * connecting to the signal. If this happens the signal will
110 : : * unexpectedly not be emitted, and checking before connecting to
111 : : * the signal leaves a race condition where this is still happening.
112 : : *
113 : : * In order to make it safe and easy to connect handlers there
114 : : * are two helper functions: g_cancellable_connect() and
115 : : * g_cancellable_disconnect() which protect against problems
116 : : * like this.
117 : : *
118 : : * An example of how to us this:
119 : : * |[<!-- language="C" -->
120 : : * // Make sure we don't do unnecessary work if already cancelled
121 : : * if (g_cancellable_set_error_if_cancelled (cancellable, error))
122 : : * return;
123 : : *
124 : : * // Set up all the data needed to be able to handle cancellation
125 : : * // of the operation
126 : : * my_data = my_data_new (...);
127 : : *
128 : : * id = 0;
129 : : * if (cancellable)
130 : : * id = g_cancellable_connect (cancellable,
131 : : * G_CALLBACK (cancelled_handler)
132 : : * data, NULL);
133 : : *
134 : : * // cancellable operation here...
135 : : *
136 : : * g_cancellable_disconnect (cancellable, id);
137 : : *
138 : : * // cancelled_handler is never called after this, it is now safe
139 : : * // to free the data
140 : : * my_data_free (my_data);
141 : : * ]|
142 : : *
143 : : * Note that the cancelled signal is emitted in the thread that
144 : : * the user cancelled from, which may be the main thread. So, the
145 : : * cancellable signal should not do something that can block.
146 : : */
147 : 118 : signals[CANCELLED] =
148 : 118 : g_signal_new (I_("cancelled"),
149 : : G_TYPE_FROM_CLASS (gobject_class),
150 : : G_SIGNAL_RUN_LAST,
151 : : G_STRUCT_OFFSET (GCancellableClass, cancelled),
152 : : NULL, NULL,
153 : : NULL,
154 : : G_TYPE_NONE, 0);
155 : :
156 : 118 : }
157 : :
158 : : static void
159 : 103537 : g_cancellable_init (GCancellable *cancellable)
160 : : {
161 : 103537 : cancellable->priv = g_cancellable_get_instance_private (cancellable);
162 : :
163 : 103537 : g_mutex_init (&cancellable->priv->mutex);
164 : 103537 : }
165 : :
166 : : /**
167 : : * g_cancellable_new:
168 : : *
169 : : * Creates a new #GCancellable object.
170 : : *
171 : : * Applications that want to start one or more operations
172 : : * that should be cancellable should create a #GCancellable
173 : : * and pass it to the operations.
174 : : *
175 : : * One #GCancellable can be used in multiple consecutive
176 : : * operations or in multiple concurrent operations.
177 : : *
178 : : * Returns: a #GCancellable.
179 : : **/
180 : : GCancellable *
181 : 103536 : g_cancellable_new (void)
182 : : {
183 : 103536 : return g_object_new (G_TYPE_CANCELLABLE, NULL);
184 : : }
185 : :
186 : : /**
187 : : * g_cancellable_push_current:
188 : : * @cancellable: a #GCancellable object
189 : : *
190 : : * Pushes @cancellable onto the cancellable stack. The current
191 : : * cancellable can then be received using g_cancellable_get_current().
192 : : *
193 : : * This is useful when implementing cancellable operations in
194 : : * code that does not allow you to pass down the cancellable object.
195 : : *
196 : : * This is typically called automatically by e.g. #GFile operations,
197 : : * so you rarely have to call this yourself.
198 : : **/
199 : : void
200 : 14810 : g_cancellable_push_current (GCancellable *cancellable)
201 : : {
202 : : GSList *l;
203 : :
204 : 14810 : g_return_if_fail (cancellable != NULL);
205 : :
206 : 14810 : l = g_private_get (¤t_cancellable);
207 : 14810 : l = g_slist_prepend (l, cancellable);
208 : 14810 : g_private_set (¤t_cancellable, l);
209 : : }
210 : :
211 : : /**
212 : : * g_cancellable_pop_current:
213 : : * @cancellable: a #GCancellable object
214 : : *
215 : : * Pops @cancellable off the cancellable stack (verifying that @cancellable
216 : : * is on the top of the stack).
217 : : **/
218 : : void
219 : 14810 : g_cancellable_pop_current (GCancellable *cancellable)
220 : : {
221 : : GSList *l;
222 : :
223 : 14810 : l = g_private_get (¤t_cancellable);
224 : :
225 : 14810 : g_return_if_fail (l != NULL);
226 : 14810 : g_return_if_fail (l->data == cancellable);
227 : :
228 : 14810 : l = g_slist_delete_link (l, l);
229 : 14810 : g_private_set (¤t_cancellable, l);
230 : : }
231 : :
232 : : /**
233 : : * g_cancellable_get_current:
234 : : *
235 : : * Gets the top cancellable from the stack.
236 : : *
237 : : * Returns: (nullable) (transfer none): a #GCancellable from the top
238 : : * of the stack, or %NULL if the stack is empty.
239 : : **/
240 : : GCancellable *
241 : 0 : g_cancellable_get_current (void)
242 : : {
243 : : GSList *l;
244 : :
245 : 0 : l = g_private_get (¤t_cancellable);
246 : 0 : if (l == NULL)
247 : 0 : return NULL;
248 : :
249 : 0 : return G_CANCELLABLE (l->data);
250 : : }
251 : :
252 : : /**
253 : : * g_cancellable_reset:
254 : : * @cancellable: a #GCancellable object.
255 : : *
256 : : * Resets @cancellable to its uncancelled state.
257 : : *
258 : : * If cancellable is currently in use by any cancellable operation
259 : : * then the behavior of this function is undefined.
260 : : *
261 : : * Note that it is generally not a good idea to reuse an existing
262 : : * cancellable for more operations after it has been cancelled once,
263 : : * as this function might tempt you to do. The recommended practice
264 : : * is to drop the reference to a cancellable after cancelling it,
265 : : * and let it die with the outstanding async operations. You should
266 : : * create a fresh cancellable for further async operations.
267 : : *
268 : : * In the event that a [signal@Gio.Cancellable::cancelled] signal handler is currently
269 : : * running, this call will block until the handler has finished.
270 : : * Calling this function from a signal handler will therefore result in a
271 : : * deadlock.
272 : : **/
273 : : void
274 : 20273 : g_cancellable_reset (GCancellable *cancellable)
275 : : {
276 : : GCancellablePrivate *priv;
277 : :
278 : 20273 : g_return_if_fail (G_IS_CANCELLABLE (cancellable));
279 : :
280 : 20273 : priv = cancellable->priv;
281 : :
282 : 20273 : g_mutex_lock (&priv->mutex);
283 : :
284 : 20272 : if (g_atomic_int_compare_and_exchange (&priv->cancelled, TRUE, FALSE))
285 : : {
286 : 48 : if (priv->wakeup)
287 : 0 : GLIB_PRIVATE_CALL (g_wakeup_acknowledge) (priv->wakeup);
288 : : }
289 : :
290 : 20272 : g_mutex_unlock (&priv->mutex);
291 : : }
292 : :
293 : : /**
294 : : * g_cancellable_is_cancelled:
295 : : * @cancellable: (nullable): a #GCancellable or %NULL
296 : : *
297 : : * Checks if a cancellable job has been cancelled.
298 : : *
299 : : * Returns: %TRUE if @cancellable is cancelled,
300 : : * FALSE if called with %NULL or if item is not cancelled.
301 : : **/
302 : : gboolean
303 : 680844 : g_cancellable_is_cancelled (GCancellable *cancellable)
304 : : {
305 : 680844 : return cancellable != NULL && g_atomic_int_get (&cancellable->priv->cancelled);
306 : : }
307 : :
308 : : /**
309 : : * g_cancellable_set_error_if_cancelled:
310 : : * @cancellable: (nullable): a #GCancellable or %NULL
311 : : * @error: #GError to append error state to
312 : : *
313 : : * If the @cancellable is cancelled, sets the error to notify
314 : : * that the operation was cancelled.
315 : : *
316 : : * Returns: %TRUE if @cancellable was cancelled, %FALSE if it was not
317 : : */
318 : : gboolean
319 : 448993 : g_cancellable_set_error_if_cancelled (GCancellable *cancellable,
320 : : GError **error)
321 : : {
322 : 448993 : if (g_cancellable_is_cancelled (cancellable))
323 : : {
324 : 4284 : g_set_error_literal (error,
325 : : G_IO_ERROR,
326 : : G_IO_ERROR_CANCELLED,
327 : : _("Operation was cancelled"));
328 : 4284 : return TRUE;
329 : : }
330 : :
331 : 444709 : return FALSE;
332 : : }
333 : :
334 : : /**
335 : : * g_cancellable_get_fd:
336 : : * @cancellable: a #GCancellable.
337 : : *
338 : : * Gets the file descriptor for a cancellable job. This can be used to
339 : : * implement cancellable operations on Unix systems. The returned fd will
340 : : * turn readable when @cancellable is cancelled.
341 : : *
342 : : * You are not supposed to read from the fd yourself, just check for
343 : : * readable status. Reading to unset the readable status is done
344 : : * with g_cancellable_reset().
345 : : *
346 : : * After a successful return from this function, you should use
347 : : * g_cancellable_release_fd() to free up resources allocated for
348 : : * the returned file descriptor.
349 : : *
350 : : * See also g_cancellable_make_pollfd().
351 : : *
352 : : * Returns: A valid file descriptor. `-1` if the file descriptor
353 : : * is not supported, or on errors.
354 : : **/
355 : : int
356 : 1 : g_cancellable_get_fd (GCancellable *cancellable)
357 : : {
358 : : GPollFD pollfd;
359 : : #ifndef G_OS_WIN32
360 : : gboolean retval G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */;
361 : : #endif
362 : :
363 : 1 : if (cancellable == NULL)
364 : 0 : return -1;
365 : :
366 : : #ifdef G_OS_WIN32
367 : : pollfd.fd = -1;
368 : : #else
369 : 1 : retval = g_cancellable_make_pollfd (cancellable, &pollfd);
370 : 1 : g_assert (retval);
371 : : #endif
372 : :
373 : 1 : return pollfd.fd;
374 : : }
375 : :
376 : : /**
377 : : * g_cancellable_make_pollfd:
378 : : * @cancellable: (nullable): a #GCancellable or %NULL
379 : : * @pollfd: a pointer to a #GPollFD
380 : : *
381 : : * Creates a #GPollFD corresponding to @cancellable; this can be passed
382 : : * to g_poll() and used to poll for cancellation. This is useful both
383 : : * for unix systems without a native poll and for portability to
384 : : * windows.
385 : : *
386 : : * When this function returns %TRUE, you should use
387 : : * g_cancellable_release_fd() to free up resources allocated for the
388 : : * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd().
389 : : *
390 : : * If this function returns %FALSE, either no @cancellable was given or
391 : : * resource limits prevent this function from allocating the necessary
392 : : * structures for polling. (On Linux, you will likely have reached
393 : : * the maximum number of file descriptors.) The suggested way to handle
394 : : * these cases is to ignore the @cancellable.
395 : : *
396 : : * You are not supposed to read from the fd yourself, just check for
397 : : * readable status. Reading to unset the readable status is done
398 : : * with g_cancellable_reset().
399 : : *
400 : : * Note that in the event that a [signal@Gio.Cancellable::cancelled] signal handler is
401 : : * currently running, this call will block until the handler has finished.
402 : : * Calling this function from a signal handler will therefore result in a
403 : : * deadlock.
404 : : *
405 : : * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on
406 : : * failure to prepare the cancellable.
407 : : *
408 : : * Since: 2.22
409 : : **/
410 : : gboolean
411 : 55204 : g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
412 : : {
413 : : GCancellablePrivate *priv;
414 : :
415 : 55204 : g_return_val_if_fail (pollfd != NULL, FALSE);
416 : 55204 : if (cancellable == NULL)
417 : 40427 : return FALSE;
418 : 14777 : g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE);
419 : :
420 : 14777 : priv = cancellable->priv;
421 : :
422 : 14777 : g_mutex_lock (&priv->mutex);
423 : :
424 : 14777 : if ((priv->fd_refcount++) == 0)
425 : : {
426 : 14746 : priv->wakeup = GLIB_PRIVATE_CALL (g_wakeup_new) ();
427 : :
428 : 14746 : if (g_atomic_int_get (&priv->cancelled))
429 : 40 : GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
430 : : }
431 : :
432 : 14777 : g_assert (priv->wakeup);
433 : 14777 : GLIB_PRIVATE_CALL (g_wakeup_get_pollfd) (priv->wakeup, pollfd);
434 : :
435 : 14777 : g_mutex_unlock (&priv->mutex);
436 : :
437 : 14777 : return TRUE;
438 : : }
439 : :
440 : : /**
441 : : * g_cancellable_release_fd:
442 : : * @cancellable: a #GCancellable
443 : : *
444 : : * Releases a resources previously allocated by g_cancellable_get_fd()
445 : : * or g_cancellable_make_pollfd().
446 : : *
447 : : * For compatibility reasons with older releases, calling this function
448 : : * is not strictly required, the resources will be automatically freed
449 : : * when the @cancellable is finalized. However, the @cancellable will
450 : : * block scarce file descriptors until it is finalized if this function
451 : : * is not called. This can cause the application to run out of file
452 : : * descriptors when many #GCancellables are used at the same time.
453 : : *
454 : : * Note that in the event that a [signal@Gio.Cancellable::cancelled] signal handler is
455 : : * currently running, this call will block until the handler has finished.
456 : : * Calling this function from a signal handler will therefore result in a
457 : : * deadlock.
458 : : *
459 : : * Since: 2.22
460 : : **/
461 : : void
462 : 14777 : g_cancellable_release_fd (GCancellable *cancellable)
463 : : {
464 : 14777 : if (cancellable == NULL)
465 : 0 : return;
466 : :
467 : 14777 : g_return_if_fail (G_IS_CANCELLABLE (cancellable));
468 : :
469 : 14777 : g_mutex_lock (&cancellable->priv->mutex);
470 : :
471 : 14777 : g_assert (cancellable->priv->fd_refcount > 0);
472 : :
473 : 14777 : if ((cancellable->priv->fd_refcount--) == 1)
474 : : {
475 : 14746 : GLIB_PRIVATE_CALL (g_wakeup_free) (cancellable->priv->wakeup);
476 : 14746 : cancellable->priv->wakeup = NULL;
477 : : }
478 : :
479 : 14777 : g_mutex_unlock (&cancellable->priv->mutex);
480 : : }
481 : :
482 : : /**
483 : : * g_cancellable_cancel:
484 : : * @cancellable: (nullable): a #GCancellable object.
485 : : *
486 : : * Will set @cancellable to cancelled, and will emit the
487 : : * #GCancellable::cancelled signal. (However, see the warning about
488 : : * race conditions in the documentation for that signal if you are
489 : : * planning to connect to it.)
490 : : *
491 : : * This function is thread-safe. In other words, you can safely call
492 : : * it from a thread other than the one running the operation that was
493 : : * passed the @cancellable.
494 : : *
495 : : * If @cancellable is %NULL, this function returns immediately for convenience.
496 : : *
497 : : * The convention within GIO is that cancelling an asynchronous
498 : : * operation causes it to complete asynchronously. That is, if you
499 : : * cancel the operation from the same thread in which it is running,
500 : : * then the operation's #GAsyncReadyCallback will not be invoked until
501 : : * the application returns to the main loop.
502 : : *
503 : : * It is safe (although useless, since it will be a no-op) to call
504 : : * this function from a [signal@Gio.Cancellable::cancelled] signal handler.
505 : : **/
506 : : void
507 : 133352 : g_cancellable_cancel (GCancellable *cancellable)
508 : : {
509 : : GCancellablePrivate *priv;
510 : :
511 : 133352 : if (cancellable == NULL || g_atomic_int_get (&cancellable->priv->cancelled))
512 : 30145 : return;
513 : :
514 : 103207 : priv = cancellable->priv;
515 : :
516 : : /* We add a reference before locking, to avoid that potential toggle
517 : : * notifications on the object might happen while we're locked.
518 : : */
519 : 103207 : g_object_ref (cancellable);
520 : 103207 : g_mutex_lock (&priv->mutex);
521 : :
522 : 103207 : if (!g_atomic_int_compare_and_exchange (&priv->cancelled, FALSE, TRUE))
523 : : {
524 : 0 : g_mutex_unlock (&priv->mutex);
525 : 0 : g_object_unref (cancellable);
526 : 0 : return;
527 : : }
528 : :
529 : 103207 : g_atomic_int_inc (&priv->cancelled_running);
530 : :
531 : 103207 : if (priv->wakeup)
532 : 9 : GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
533 : :
534 : : /* Adding another reference, in case the callback is unreffing the
535 : : * cancellable and there are toggle references, so that the second to last
536 : : * reference (that would lead a toggle notification) won't be released
537 : : * while we're locked.
538 : : */
539 : 103207 : g_object_ref (cancellable);
540 : :
541 : 103207 : g_signal_emit (cancellable, signals[CANCELLED], 0);
542 : :
543 : 103205 : if (g_atomic_int_dec_and_test (&priv->cancelled_running))
544 : 103205 : g_cond_broadcast (&cancellable_cond);
545 : :
546 : 103205 : g_mutex_unlock (&priv->mutex);
547 : :
548 : 103205 : g_object_unref (cancellable);
549 : 103205 : g_object_unref (cancellable);
550 : : }
551 : :
552 : : /**
553 : : * g_cancellable_connect:
554 : : * @cancellable: A #GCancellable.
555 : : * @callback: The #GCallback to connect.
556 : : * @data: Data to pass to @callback.
557 : : * @data_destroy_func: (nullable): Free function for @data or %NULL.
558 : : *
559 : : * Convenience function to connect to the #GCancellable::cancelled
560 : : * signal. Also handles the race condition that may happen
561 : : * if the cancellable is cancelled right before connecting.
562 : : *
563 : : * @callback is called exactly once each time @cancellable is cancelled,
564 : : * either directly at the time of the connect if @cancellable is already
565 : : * cancelled, or when @cancellable is cancelled in some thread.
566 : : * In case the cancellable is reset via [method@Gio.Cancellable.reset]
567 : : * then the callback can be called again if the @cancellable is cancelled and
568 : : * if it had not been previously cancelled at the time
569 : : * [method@Gio.Cancellable.connect] was called (e.g. if the connection actually
570 : : * took place, returning a non-zero value).
571 : : *
572 : : * @data_destroy_func will be called when the handler is
573 : : * disconnected, or immediately if the cancellable is already
574 : : * cancelled.
575 : : *
576 : : * See #GCancellable::cancelled for details on how to use this.
577 : : *
578 : : * Since GLib 2.40, the lock protecting @cancellable is not held when
579 : : * @callback is invoked. This lifts a restriction in place for
580 : : * earlier GLib versions which now makes it easier to write cleanup
581 : : * code that unconditionally invokes e.g. [method@Gio.Cancellable.cancel].
582 : : * Note that since 2.82 GLib still holds a lock during the callback but it’s
583 : : * designed in a way that most of the [class@Gio.Cancellable] methods can be
584 : : * called, including [method@Gio.Cancellable.cancel] or
585 : : * [method@GObject.Object.unref].
586 : : *
587 : : * There are still some methods that will deadlock (by design) when
588 : : * called from the [signal@Gio.Cancellable::cancelled] callbacks:
589 : : * - [method@Gio.Cancellable.connect]
590 : : * - [method@Gio.Cancellable.disconnect]
591 : : * - [method@Gio.Cancellable.reset]
592 : : * - [method@Gio.Cancellable.make_pollfd]
593 : : * - [method@Gio.Cancellable.release_fd]
594 : : *
595 : : * Returns: The id of the signal handler or 0 if @cancellable has already
596 : : * been cancelled.
597 : : *
598 : : * Since: 2.22
599 : : */
600 : : gulong
601 : 10036 : g_cancellable_connect (GCancellable *cancellable,
602 : : GCallback callback,
603 : : gpointer data,
604 : : GDestroyNotify data_destroy_func)
605 : : {
606 : 10036 : GCancellable *extra_ref = NULL;
607 : : gulong id;
608 : :
609 : 10036 : g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), 0);
610 : :
611 : : /* If the cancellable is already cancelled we may end up calling the callback
612 : : * immediately, and the callback may unref the Cancellable, so we need to add
613 : : * an extra reference here. We can't do it only in the case the cancellable
614 : : * is already cancelled because it can be potentially be reset, so we can't
615 : : * rely on the atomic value only, but we need to be locked to be really sure.
616 : : * At the same time we don't want to wake up the ToggleNotify if toggle
617 : : * references are enabled while we're locked.
618 : : */
619 : 10036 : g_object_ref (cancellable);
620 : :
621 : 10036 : g_mutex_lock (&cancellable->priv->mutex);
622 : :
623 : 10036 : if (g_atomic_int_get (&cancellable->priv->cancelled))
624 : : {
625 : : void (*_callback) (GCancellable *cancellable,
626 : : gpointer user_data);
627 : :
628 : : /* Adding another reference, in case the callback is unreffing the
629 : : * cancellable and there are toggle references, so that the second to last
630 : : * reference (that would lead a toggle notification) won't be released
631 : : * while we're locked.
632 : : */
633 : 10006 : extra_ref = g_object_ref (cancellable);
634 : :
635 : 10006 : _callback = (void *)callback;
636 : 10006 : id = 0;
637 : :
638 : 10006 : _callback (cancellable, data);
639 : : }
640 : : else
641 : : {
642 : : GClosure *closure;
643 : :
644 : 30 : closure = g_cclosure_new (callback, g_steal_pointer (&data),
645 : 30 : (GClosureNotify) g_steal_pointer (&data_destroy_func));
646 : :
647 : 30 : id = g_signal_connect_closure_by_id (cancellable, signals[CANCELLED],
648 : : 0, closure, FALSE);
649 : : }
650 : :
651 : 10036 : g_mutex_unlock (&cancellable->priv->mutex);
652 : :
653 : 10036 : if (data_destroy_func)
654 : 3 : data_destroy_func (data);
655 : :
656 : 10036 : g_object_unref (cancellable);
657 : 10036 : g_clear_object (&extra_ref);
658 : :
659 : 10036 : return id;
660 : : }
661 : :
662 : : /**
663 : : * g_cancellable_disconnect:
664 : : * @cancellable: (nullable): A #GCancellable or %NULL.
665 : : * @handler_id: Handler id of the handler to be disconnected, or `0`.
666 : : *
667 : : * Disconnects a handler from a cancellable instance similar to
668 : : * g_signal_handler_disconnect(). Additionally, in the event that a
669 : : * signal handler is currently running, this call will block until the
670 : : * handler has finished. Calling this function from a
671 : : * #GCancellable::cancelled signal handler will therefore result in a
672 : : * deadlock.
673 : : *
674 : : * This avoids a race condition where a thread cancels at the
675 : : * same time as the cancellable operation is finished and the
676 : : * signal handler is removed. See #GCancellable::cancelled for
677 : : * details on how to use this.
678 : : *
679 : : * If @cancellable is %NULL or @handler_id is `0` this function does
680 : : * nothing.
681 : : *
682 : : * Since: 2.22
683 : : */
684 : : void
685 : 10064 : g_cancellable_disconnect (GCancellable *cancellable,
686 : : gulong handler_id)
687 : : {
688 : : GCancellablePrivate *priv;
689 : :
690 : 10064 : if (handler_id == 0 || cancellable == NULL)
691 : 10043 : return;
692 : :
693 : 21 : priv = cancellable->priv;
694 : :
695 : 21 : g_mutex_lock (&priv->mutex);
696 : :
697 : 20 : while (g_atomic_int_get (&priv->cancelled_running) != 0)
698 : 0 : g_cond_wait (&cancellable_cond, &priv->mutex);
699 : :
700 : 20 : g_mutex_unlock (&priv->mutex);
701 : :
702 : 20 : g_signal_handler_disconnect (cancellable, handler_id);
703 : : }
704 : :
705 : : typedef struct {
706 : : GSource source;
707 : :
708 : : /* Atomic: */
709 : : GSource **self_ptr;
710 : : /* Atomic: */
711 : : GCancellable *cancellable;
712 : : gulong cancelled_handler;
713 : : /* Atomic: */
714 : : gboolean cancelled_callback_called;
715 : : } GCancellableSource;
716 : :
717 : : /*
718 : : * The reference count of the GSource might be 0 at this point but it is not
719 : : * finalized yet and its dispose function did not run yet, or otherwise we
720 : : * would have disconnected the signal handler already and due to the signal
721 : : * emission lock it would be impossible to call the signal handler at that
722 : : * point. That is: at this point we either have a fully valid GSource, or
723 : : * it's not disposed or finalized yet and we can still resurrect it as needed.
724 : : *
725 : : * As such we first ensure that we have a strong reference to the GSource in
726 : : * here before calling any other GSource API.
727 : : */
728 : : static void
729 : 102756 : cancellable_source_cancelled (GCancellable *cancellable,
730 : : gpointer user_data)
731 : : {
732 : 102756 : GSource *source = g_atomic_pointer_exchange ((GSource **) user_data, NULL);
733 : : GCancellableSource *cancellable_source;
734 : : gboolean callback_was_not_called G_GNUC_UNUSED;
735 : :
736 : : /* The source is being disposed, so don't bother marking it as ready */
737 : 102756 : if (source == NULL)
738 : 1 : return;
739 : :
740 : 102755 : cancellable_source = (GCancellableSource *) source;
741 : :
742 : 102755 : g_source_ref (source);
743 : 102755 : g_source_set_ready_time (source, 0);
744 : :
745 : 102755 : callback_was_not_called = g_atomic_int_compare_and_exchange (
746 : : &cancellable_source->cancelled_callback_called, FALSE, TRUE);
747 : 102755 : g_assert (callback_was_not_called);
748 : :
749 : 102755 : g_source_unref (source);
750 : : }
751 : :
752 : : static gboolean
753 : 60656 : cancellable_source_prepare (GSource *source,
754 : : gint *timeout)
755 : : {
756 : 60656 : GCancellableSource *cancellable_source = (GCancellableSource *) source;
757 : : GCancellable *cancellable;
758 : :
759 : 60656 : if (timeout)
760 : 60656 : *timeout = -1;
761 : :
762 : 60656 : cancellable = g_atomic_pointer_get (&cancellable_source->cancellable);
763 : 60656 : if (cancellable && !g_atomic_int_get (&cancellable->priv->cancelled_running))
764 : : {
765 : 60562 : g_atomic_int_set (&cancellable_source->cancelled_callback_called, FALSE);
766 : 60562 : g_atomic_pointer_set (cancellable_source->self_ptr, source);
767 : : }
768 : :
769 : 60656 : return FALSE;
770 : : }
771 : :
772 : : static gboolean
773 : 2794 : cancellable_source_dispatch (GSource *source,
774 : : GSourceFunc callback,
775 : : gpointer user_data)
776 : : {
777 : 2794 : GCancellableSourceFunc func = (GCancellableSourceFunc)callback;
778 : 2794 : GCancellableSource *cancellable_source = (GCancellableSource *)source;
779 : :
780 : 2794 : g_source_set_ready_time (source, -1);
781 : 2794 : return (*func) (cancellable_source->cancellable, user_data);
782 : : }
783 : :
784 : : static void
785 : 117375 : cancellable_source_dispose (GSource *source)
786 : : {
787 : 117375 : GCancellableSource *cancellable_source = (GCancellableSource *)source;
788 : : GCancellable *cancellable;
789 : :
790 : 117375 : cancellable = g_atomic_pointer_exchange (&cancellable_source->cancellable, NULL);
791 : :
792 : 117375 : if (cancellable)
793 : : {
794 : 117375 : GSource *self_ptr =
795 : 117375 : g_atomic_pointer_exchange (cancellable_source->self_ptr, NULL);
796 : :
797 : 117375 : if (self_ptr == NULL)
798 : : {
799 : : /* There can be a race here: if thread A has called
800 : : * g_cancellable_cancel() and has got as far as committing to call
801 : : * cancellable_source_cancelled(), then thread B drops the final
802 : : * ref on the GCancellableSource before g_source_ref() is called in
803 : : * cancellable_source_cancelled(), then cancellable_source_dispose()
804 : : * will run through and the GCancellableSource will be finalised
805 : : * before cancellable_source_cancelled() gets to g_source_ref(). It
806 : : * will then be left in a state where it’s committed to using a
807 : : * dangling GCancellableSource pointer.
808 : : *
809 : : * Eliminate that race by waiting to ensure that our cancelled
810 : : * callback has been called, so that there's no risk that we're
811 : : * unreffing something that is still going to be used.
812 : : */
813 : :
814 : 102464 : while (!g_atomic_int_get (&cancellable_source->cancelled_callback_called))
815 : : ;
816 : : }
817 : :
818 : 117375 : g_clear_signal_handler (&cancellable_source->cancelled_handler, cancellable);
819 : 117375 : g_object_unref (cancellable);
820 : : }
821 : 117375 : }
822 : :
823 : : static gboolean
824 : 2763 : cancellable_source_closure_callback (GCancellable *cancellable,
825 : : gpointer data)
826 : : {
827 : 2763 : GClosure *closure = data;
828 : :
829 : 2763 : GValue params = G_VALUE_INIT;
830 : 2763 : GValue result_value = G_VALUE_INIT;
831 : : gboolean result;
832 : :
833 : 2763 : g_value_init (&result_value, G_TYPE_BOOLEAN);
834 : :
835 : 2763 : g_value_init (¶ms, G_TYPE_CANCELLABLE);
836 : 2763 : g_value_set_object (¶ms, cancellable);
837 : :
838 : 2763 : g_closure_invoke (closure, &result_value, 1, ¶ms, NULL);
839 : :
840 : 2763 : result = g_value_get_boolean (&result_value);
841 : 2763 : g_value_unset (&result_value);
842 : 2763 : g_value_unset (¶ms);
843 : :
844 : 2763 : return result;
845 : : }
846 : :
847 : : static GSourceFuncs cancellable_source_funcs =
848 : : {
849 : : cancellable_source_prepare,
850 : : NULL,
851 : : cancellable_source_dispatch,
852 : : NULL,
853 : : (GSourceFunc)cancellable_source_closure_callback,
854 : : NULL,
855 : : };
856 : :
857 : : /**
858 : : * g_cancellable_source_new:
859 : : * @cancellable: (nullable): a #GCancellable, or %NULL
860 : : *
861 : : * Creates a source that triggers if @cancellable is cancelled and
862 : : * calls its callback of type #GCancellableSourceFunc. This is
863 : : * primarily useful for attaching to another (non-cancellable) source
864 : : * with g_source_add_child_source() to add cancellability to it.
865 : : *
866 : : * For convenience, you can call this with a %NULL #GCancellable,
867 : : * in which case the source will never trigger.
868 : : *
869 : : * The new #GSource will hold a reference to the #GCancellable.
870 : : *
871 : : * Returns: (transfer full): the new #GSource.
872 : : *
873 : : * Since: 2.28
874 : : */
875 : : GSource *
876 : 117472 : g_cancellable_source_new (GCancellable *cancellable)
877 : : {
878 : : GSource *source;
879 : : GCancellableSource *cancellable_source;
880 : :
881 : 117472 : source = g_source_new (&cancellable_source_funcs, sizeof (GCancellableSource));
882 : 117472 : g_source_set_static_name (source, "GCancellable");
883 : 117472 : g_source_set_dispose_function (source, cancellable_source_dispose);
884 : 117472 : cancellable_source = (GCancellableSource *)source;
885 : :
886 : 117472 : if (cancellable)
887 : : {
888 : 117472 : cancellable_source->cancellable = g_object_ref (cancellable);
889 : 117472 : cancellable_source->self_ptr = g_new (GSource *, 1);
890 : 117472 : g_atomic_pointer_set (cancellable_source->self_ptr, source);
891 : :
892 : : /* We intentionally don't use g_cancellable_connect() here,
893 : : * because we don't want the "at most once" behavior.
894 : : */
895 : 117472 : cancellable_source->cancelled_handler =
896 : 117472 : g_signal_connect_data (cancellable, "cancelled",
897 : : G_CALLBACK (cancellable_source_cancelled),
898 : 117472 : cancellable_source->self_ptr,
899 : : (GClosureNotify) g_free, G_CONNECT_DEFAULT);
900 : 117472 : if (g_cancellable_is_cancelled (cancellable))
901 : 58 : g_source_set_ready_time (source, 0);
902 : : }
903 : :
904 : 117472 : return source;
905 : : }
|