variant: Fix double-free
gio::Settings::set_value takes over ownership of the Variant sometimes, but in other cases it doesn't. To prevent this being a problem, the custom Variant is made of the type that will never have its ownership taken. This is not necessarily consistent with what gtk-rs authors intended. In practice, the ownership is shared by refcounting, and after the Rust reference is dropped, one taken by Settings survives.
This commit is contained in:
@ -91,6 +91,11 @@ mod variants {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let ret = glib_sys::g_variant_builder_end(builder);
|
let ret = glib_sys::g_variant_builder_end(builder);
|
||||||
glib_sys::g_variant_builder_unref(builder);
|
glib_sys::g_variant_builder_unref(builder);
|
||||||
|
// HACK: This is to prevent C taking ownership
|
||||||
|
// of "floating" Variants,
|
||||||
|
// where Rust gets to keep a stale reference
|
||||||
|
// and crash when trying to drop it.
|
||||||
|
glib_sys::g_variant_ref_sink(ret);
|
||||||
glib::Variant::from_glib_full(ret)
|
glib::Variant::from_glib_full(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +146,7 @@ fn set_layout(kind: String, name: String) {
|
|||||||
.chain(inputs).collect();
|
.chain(inputs).collect();
|
||||||
settings.set_value(
|
settings.set_value(
|
||||||
"sources",
|
"sources",
|
||||||
&variants::ArrayPairString(inputs).to_variant()
|
&variants::ArrayPairString(inputs).to_variant(),
|
||||||
);
|
);
|
||||||
settings.apply();
|
settings.apply();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user