gio/cancellable: Fix comments for g_cancellable_connect()

We had wrong comments, in particular:

  @callback is called exactly once each time @cancellable is cancelled,
  either directly at the time of the connect if @cancellable is already
  cancelled, or when @cancellable is cancelled in some thread.
  In case the cancellable is reset via [method@Gio.Cancellable.reset]
  then the callback can be called again if the @cancellable is cancelled

This is not true if `@cancellable` is already cancelled because then the
callback will be thrown away, and will not be called for subsequent
cancellations.

  Since GLib 2.40, the lock protecting @cancellable is not held when
  @callback is invoked.  This lifts a restriction in place for
  earlier GLib versions which now makes it easier to write cleanup
  code that unconditionally invokes e.g. g_cancellable_cancel().

As per commit 3a07b2abd4 this section needs some amending since
it's not true anymore, as the GCancellable's mutex is held when `@callback` is
invoked. However this happens in a way that it's still safe to call most
of the GCancellable API.

Closes: #3642
This commit is contained in:
Marco Trevisan (Treviño)
2025-04-02 19:36:34 +02:00
parent 49680afd5c
commit c6ace7aaf7

View File

@@ -264,6 +264,11 @@ g_cancellable_get_current (void)
* is to drop the reference to a cancellable after cancelling it,
* and let it die with the outstanding async operations. You should
* create a fresh cancellable for further async operations.
*
* In the event that a [signal@Gio.Cancellable::cancelled] signal handler is currently
* running, this call will block until the handler has finished.
* Calling this function from a signal handler will therefore result in a
* deadlock.
**/
void
g_cancellable_reset (GCancellable *cancellable)
@@ -392,6 +397,11 @@ g_cancellable_get_fd (GCancellable *cancellable)
* readable status. Reading to unset the readable status is done
* with g_cancellable_reset().
*
* Note that in the event that a [signal@Gio.Cancellable::cancelled] signal handler is
* currently running, this call will block until the handler has finished.
* Calling this function from a signal handler will therefore result in a
* deadlock.
*
* Returns: %TRUE if @pollfd was successfully initialized, %FALSE on
* failure to prepare the cancellable.
*
@@ -440,7 +450,12 @@ g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
* block scarce file descriptors until it is finalized if this function
* is not called. This can cause the application to run out of file
* descriptors when many #GCancellables are used at the same time.
*
*
* Note that in the event that a [signal@Gio.Cancellable::cancelled] signal handler is
* currently running, this call will block until the handler has finished.
* Calling this function from a signal handler will therefore result in a
* deadlock.
*
* Since: 2.22
**/
void
@@ -484,6 +499,9 @@ g_cancellable_release_fd (GCancellable *cancellable)
* 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.
*
* It is safe (although useless, since it will be a no-op) to call
* this function from a [signal@Gio.Cancellable::cancelled] signal handler.
**/
void
g_cancellable_cancel (GCancellable *cancellable)
@@ -538,7 +556,10 @@ g_cancellable_cancel (GCancellable *cancellable)
* either directly at the time of the connect if @cancellable is already
* cancelled, or when @cancellable is cancelled in some thread.
* In case the cancellable is reset via [method@Gio.Cancellable.reset]
* then the callback can be called again if the @cancellable is cancelled.
* then the callback can be called again if the @cancellable is cancelled and
* if it had not been previously cancelled at the time
* [method@Gio.Cancellable.connect] was called (e.g. if the connection actually
* took place, returning a non-zero value).
*
* @data_destroy_func will be called when the handler is
* disconnected, or immediately if the cancellable is already
@@ -547,9 +568,21 @@ g_cancellable_cancel (GCancellable *cancellable)
* See #GCancellable::cancelled for details on how to use this.
*
* Since GLib 2.40, the lock protecting @cancellable is not held when
* @callback is invoked. This lifts a restriction in place for
* @callback is invoked. This lifts a restriction in place for
* earlier GLib versions which now makes it easier to write cleanup
* code that unconditionally invokes e.g. g_cancellable_cancel().
* code that unconditionally invokes e.g. [method@Gio.Cancellable.cancel].
* Note that since 2.82 GLib still holds a lock during the callback but its
* designed in a way that most of the [class@Gio.Cancellable] methods can be
* called, including [method@Gio.Cancellable.cancel] or
* [method@GObject.Object.unref].
*
* There are still some methods that will deadlock (by design) when
* called from the [signal@Gio.Cancellable::cancelled] callbacks:
* - [method@Gio.Cancellable.connect]
* - [method@Gio.Cancellable.disconnect]
* - [method@Gio.Cancellable.reset]
* - [method@Gio.Cancellable.make_pollfd]
* - [method@Gio.Cancellable.release_fd]
*
* Returns: The id of the signal handler or 0 if @cancellable has already
* been cancelled.