Skip to content

Commit 7eda01a

Browse files
Add MainContext checks to manual async functions
1 parent 44cfc4a commit 7eda01a

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

gdk4/src/clipboard.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{Clipboard, Texture};
44
use glib::object::IsA;
55
use glib::translate::*;
6-
use glib::{GString, ToValue};
6+
use glib::GString;
77
use std::future;
88
use std::pin::Pin;
99
use std::ptr;
@@ -17,6 +17,16 @@ impl Clipboard {
1717
cancellable: Option<&impl IsA<gio::Cancellable>>,
1818
callback: Q,
1919
) {
20+
let main_context = glib::MainContext::ref_thread_default();
21+
let is_main_context_owner = main_context.is_owner();
22+
let has_acquired_main_context = (!is_main_context_owner)
23+
.then(|| main_context.acquire().ok())
24+
.flatten();
25+
assert!(
26+
is_main_context_owner || has_acquired_main_context.is_some(),
27+
"Async operations only allowed if the thread is owning the MainContext"
28+
);
29+
2030
let user_data: Box<Q> = Box::new(callback);
2131
unsafe extern "C" fn read_async_trampoline<
2232
Q: FnOnce(Result<(gio::InputStream, GString), glib::Error>) + 'static,

gdk4/src/drop.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ impl Drop {
1717
cancellable: Option<&impl IsA<gio::Cancellable>>,
1818
callback: Q,
1919
) {
20+
let main_context = glib::MainContext::ref_thread_default();
21+
let is_main_context_owner = main_context.is_owner();
22+
let has_acquired_main_context = (!is_main_context_owner)
23+
.then(|| main_context.acquire().ok())
24+
.flatten();
25+
assert!(
26+
is_main_context_owner || has_acquired_main_context.is_some(),
27+
"Async operations only allowed if the thread is owning the MainContext"
28+
);
29+
2030
let user_data: Box<Q> = Box::new(callback);
2131
unsafe extern "C" fn read_async_trampoline<
2232
Q: FnOnce(Result<(gio::InputStream, GString), glib::Error>) + 'static,

gdk4/src/functions.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ pub fn content_deserialize_async<R: FnOnce(Result<glib::Value, glib::Error>) + S
4141
callback: R,
4242
) {
4343
assert_initialized_main_thread!();
44+
let main_context = glib::MainContext::ref_thread_default();
45+
let is_main_context_owner = main_context.is_owner();
46+
let has_acquired_main_context = (!is_main_context_owner)
47+
.then(|| main_context.acquire().ok())
48+
.flatten();
49+
assert!(
50+
is_main_context_owner || has_acquired_main_context.is_some(),
51+
"Async operations only allowed if the thread is owning the MainContext"
52+
);
53+
4454
let user_data: Box<R> = Box::new(callback);
4555
unsafe extern "C" fn content_deserialize_async_trampoline<
4656
R: FnOnce(Result<glib::Value, glib::Error>) + Send + 'static,
@@ -227,6 +237,15 @@ pub fn content_serialize_async<R: FnOnce(Result<(), glib::Error>) + Send + 'stat
227237
callback: R,
228238
) {
229239
assert_initialized_main_thread!();
240+
let main_context = glib::MainContext::ref_thread_default();
241+
let is_main_context_owner = main_context.is_owner();
242+
let has_acquired_main_context = (!is_main_context_owner)
243+
.then(|| main_context.acquire().ok())
244+
.flatten();
245+
assert!(
246+
is_main_context_owner || has_acquired_main_context.is_some(),
247+
"Async operations only allowed if the thread is owning the MainContext"
248+
);
230249
let user_data: Box<R> = Box::new(callback);
231250
unsafe extern "C" fn content_serialize_async_trampoline<
232251
R: FnOnce(Result<(), glib::Error>) + Send + 'static,

gdk4/src/subclass/content_provider.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub trait ContentProviderImplExt: ObjectSubclass {
6161

6262
fn parent_write_mime_type_async<
6363
Q: IsA<gio::Cancellable>,
64-
R: FnOnce(Result<(), glib::Error>) + Send + 'static,
64+
R: FnOnce(Result<(), glib::Error>) + 'static,
6565
>(
6666
&self,
6767
provider: &Self::Type,
@@ -163,7 +163,7 @@ impl<T: ContentProviderImpl> ContentProviderImplExt for T {
163163

164164
fn parent_write_mime_type_async<
165165
Q: IsA<gio::Cancellable>,
166-
R: FnOnce(Result<(), glib::Error>) + Send + 'static,
166+
R: FnOnce(Result<(), glib::Error>) + 'static,
167167
>(
168168
&self,
169169
provider: &Self::Type,
@@ -174,6 +174,16 @@ impl<T: ContentProviderImpl> ContentProviderImplExt for T {
174174
callback: R,
175175
) {
176176
unsafe {
177+
let main_context = glib::MainContext::ref_thread_default();
178+
let is_main_context_owner = main_context.is_owner();
179+
let has_acquired_main_context = (!is_main_context_owner)
180+
.then(|| main_context.acquire().ok())
181+
.flatten();
182+
assert!(
183+
is_main_context_owner || has_acquired_main_context.is_some(),
184+
"Async operations only allowed if the thread is owning the MainContext"
185+
);
186+
177187
let data = T::type_data();
178188
let parent_class = data.as_ref().parent_class() as *mut ffi::GdkContentProviderClass;
179189
let f = (*parent_class)
@@ -186,7 +196,7 @@ impl<T: ContentProviderImpl> ContentProviderImplExt for T {
186196
let user_data: Box<(R, _)> = Box::new((callback, finish));
187197

188198
unsafe extern "C" fn parent_write_mime_type_async_trampoline<
189-
R: FnOnce(Result<(), glib::Error>) + Send + 'static,
199+
R: FnOnce(Result<(), glib::Error>) + 'static,
190200
>(
191201
source_object_ptr: *mut glib::gobject_ffi::GObject,
192202
res: *mut gio::ffi::GAsyncResult,

0 commit comments

Comments
 (0)