Skip to content

Commit

Permalink
Move g_cancellable_set_error_if_cancelled() to manual
Browse files Browse the repository at this point in the history
Regression from this change:
7c9b36c#diff-8439ea6875c9b60b7d07a7b39f6dde1d31d38459f7c27173e56b4cecb0eadefaR142

Basically `g_cancellable_set_error_if_cancelled()` doesn't follow the
GError conventions - it's the inverse, it returns `TRUE` if an error
was set, and `FALSE` otherwise.

We need to move this to manual implementation.

I caught this while updating ostree-rs-ext to use gio 0.15,
and our https://github.com/ostreedev/ostree-rs-ext/blob/main/lib/src/tokio_util.rs
unit test started to panic.
  • Loading branch information
cgwalters authored and sdroege committed Nov 12, 2022
1 parent 0fff9d9 commit 42489e6
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 21 deletions.
3 changes: 3 additions & 0 deletions gio/Gir.toml
Expand Up @@ -398,6 +398,9 @@ manual_traits = ["CancellableExtManual"]
name = "cancelled"
# Racy, use 'connect' and 'disconnect' instead
ignore = true
[[object.function]]
name = "set_error_if_cancelled"
manual = true

[[object]]
name = "Gio.CharsetConverter"
Expand Down
20 changes: 0 additions & 20 deletions gio/src/auto/cancellable.rs
Expand Up @@ -5,7 +5,6 @@
use glib::object::IsA;
use glib::translate::*;
use std::fmt;
use std::ptr;

glib::wrapper! {
#[doc(alias = "GCancellable")]
Expand Down Expand Up @@ -62,9 +61,6 @@ pub trait CancellableExt: 'static {

#[doc(alias = "g_cancellable_release_fd")]
fn release_fd(&self);

#[doc(alias = "g_cancellable_set_error_if_cancelled")]
fn set_error_if_cancelled(&self) -> Result<(), glib::Error>;
}

impl<O: IsA<Cancellable>> CancellableExt for O {
Expand Down Expand Up @@ -107,22 +103,6 @@ impl<O: IsA<Cancellable>> CancellableExt for O {
ffi::g_cancellable_release_fd(self.as_ref().to_glib_none().0);
}
}

fn set_error_if_cancelled(&self) -> Result<(), glib::Error> {
unsafe {
let mut error = ptr::null_mut();
let is_ok = ffi::g_cancellable_set_error_if_cancelled(
self.as_ref().to_glib_none().0,
&mut error,
);
assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
}

impl fmt::Display for Cancellable {
Expand Down
29 changes: 29 additions & 0 deletions gio/src/cancellable.rs
Expand Up @@ -75,6 +75,10 @@ pub trait CancellableExtManual {
/// Returns a `Future` that completes when the cancellable becomes cancelled. Completes
/// immediately if the cancellable is already cancelled.
fn future(&self) -> std::pin::Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>;
// rustdoc-stripper-ignore-next
/// Set an error if the cancellable is already cancelled.
#[doc(alias = "g_cancellable_set_error_if_cancelled")]
fn set_error_if_cancelled(&self) -> Result<(), glib::Error>;
}

impl<O: IsA<Cancellable>> CancellableExtManual for O {
Expand Down Expand Up @@ -136,6 +140,24 @@ impl<O: IsA<Cancellable>> CancellableExtManual for O {
}
})
}

fn set_error_if_cancelled(&self) -> Result<(), glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::g_cancellable_set_error_if_cancelled(
self.as_ref().to_glib_none().0,
&mut error,
);
// Here's the special case, this function has an inverted
// return value for the error case.
assert_eq!(is_ok == glib::ffi::GFALSE, error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
}

#[cfg(test)]
Expand All @@ -158,6 +180,13 @@ mod tests {
c.disconnect_cancelled(id.unwrap());
}

#[test]
fn cancellable_error_if_cancelled() {
let c = Cancellable::new();
c.cancel();
assert!(c.set_error_if_cancelled().is_err());
}

#[test]
fn cancellable_future() {
let c = Cancellable::new();
Expand Down
1 change: 0 additions & 1 deletion gio/src/subclass/async_initable.rs
Expand Up @@ -9,7 +9,6 @@ use glib::subclass::prelude::*;

use std::ptr;

use crate::prelude::CancellableExt;
use crate::prelude::CancellableExtManual;
use crate::AsyncInitable;
use crate::AsyncResult;
Expand Down

0 comments on commit 42489e6

Please sign in to comment.