/* The convention within GIO is that cancelling an asynchronous operation causes it to complete asynchronously. That is, if you cancel the operation from the same thread in which it is running, then the operation's #GAsyncReadyCallback will not be invoked until the application returns to the main loop.  */
void g_cancellable_cancel(GCancellable *cancellable)
/* The convention within GIO is that cancelling an asynchronous operation causes it to complete asynchronously. That is, if you cancel the operation from the same thread in which it is running, then the operation's #GAsyncReadyCallback will not be invoked until the application returns to the main loop.  */
void g_cancellable_cancel(GCancellable *cancellable)
{
  GCancellablePrivate *priv;
  if (cancellable == NULL ||
      cancellable->priv->cancelled)
    return;
  priv = cancellable->priv;
  g_mutex_lock (&cancellable_mutex);
  if (priv->cancelled)
    {
      g_mutex_unlock (&cancellable_mutex);
      return;
    }
  priv->cancelled = TRUE;
  priv->cancelled_running = TRUE;
  if (priv->wakeup)
    GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup);
  g_mutex_unlock (&cancellable_mutex);
  g_object_ref (cancellable);
  g_signal_emit (cancellable, signals[CANCELLED], 0);
  g_mutex_lock (&cancellable_mutex);
  priv->cancelled_running = FALSE;
  if (priv->cancelled_running_waiting)
    g_cond_broadcast (&cancellable_cond);
  priv->cancelled_running_waiting = FALSE;
  g_mutex_unlock (&cancellable_mutex);
  g_object_unref (cancellable);
}