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