@@ -32,20 +32,54 @@ impl MainContext {
32
32
}
33
33
}
34
34
35
+ /// Invokes `func` on the main context.
35
36
pub fn invoke < F > ( & self , func : F )
36
37
where F : FnOnce ( ) + Send + ' static {
37
38
self . invoke_with_priority ( :: PRIORITY_DEFAULT_IDLE , func) ;
38
39
}
39
40
41
+ /// Invokes `func` on the main context with the given priority.
40
42
pub fn invoke_with_priority < F > ( & self , priority : Priority , func : F )
41
43
where F : FnOnce ( ) + Send + ' static {
42
44
unsafe {
43
- let func = Box :: into_raw ( Box :: new ( Some ( func) ) ) ;
44
- glib_ffi:: g_main_context_invoke_full ( self . to_glib_none ( ) . 0 , priority. to_glib ( ) , Some ( trampoline :: < F > ) ,
45
- func as gpointer , Some ( destroy_closure :: < F > ) )
45
+ self . invoke_unsafe ( priority, func) ;
46
46
}
47
47
}
48
48
49
+ /// Invokes `func` on the main context.
50
+ ///
51
+ /// Different to `invoke()`, this does not require `func` to be
52
+ /// `Send` but can only be called from the thread that owns the main context.
53
+ ///
54
+ /// This function panics if called from a different thread than the one that
55
+ /// owns the main context.
56
+ pub fn invoke_local < F > ( & self , func : F )
57
+ where F : FnOnce ( ) + ' static {
58
+ self . invoke_local_with_priority ( :: PRIORITY_DEFAULT_IDLE , func) ;
59
+ }
60
+
61
+ /// Invokes `func` on the main context with the given priority.
62
+ ///
63
+ /// Different to `invoke_with_priority()`, this does not require `func` to be
64
+ /// `Send` but can only be called from the thread that owns the main context.
65
+ ///
66
+ /// This function panics if called from a different thread than the one that
67
+ /// owns the main context.
68
+ pub fn invoke_local_with_priority < F > ( & self , priority : Priority , func : F )
69
+ where F : FnOnce ( ) + ' static {
70
+ unsafe {
71
+ assert ! ( self . is_owner( ) ) ;
72
+ self . invoke_unsafe ( priority, func) ;
73
+ }
74
+ }
75
+
76
+ unsafe fn invoke_unsafe < F > ( & self , priority : Priority , func : F )
77
+ where F : FnOnce ( ) + ' static {
78
+ let func = Box :: into_raw ( Box :: new ( Some ( func) ) ) ;
79
+ glib_ffi:: g_main_context_invoke_full ( self . to_glib_none ( ) . 0 , priority. to_glib ( ) , Some ( trampoline :: < F > ) ,
80
+ func as gpointer , Some ( destroy_closure :: < F > ) )
81
+ }
82
+
49
83
/// Calls closure with context configured as the thread default one.
50
84
///
51
85
/// Thread default context is changed in panic-safe manner by calling
@@ -63,14 +97,14 @@ impl MainContext {
63
97
}
64
98
65
99
#[ cfg_attr( feature = "cargo-clippy" , allow( transmute_ptr_to_ref) ) ]
66
- unsafe extern "C" fn trampoline < F : FnOnce ( ) + Send + ' static > ( func : gpointer ) -> gboolean {
100
+ unsafe extern "C" fn trampoline < F : FnOnce ( ) + ' static > ( func : gpointer ) -> gboolean {
67
101
let func: & mut Option < F > = transmute ( func) ;
68
102
let func = func. take ( ) . expect ( "MainContext::invoke() closure called multiple times" ) ;
69
103
func ( ) ;
70
104
glib_ffi:: G_SOURCE_REMOVE
71
105
}
72
106
73
- unsafe extern "C" fn destroy_closure < F : FnOnce ( ) + Send + ' static > ( ptr : gpointer ) {
107
+ unsafe extern "C" fn destroy_closure < F : FnOnce ( ) + ' static > ( ptr : gpointer ) {
74
108
Box :: < Option < F > > :: from_raw ( ptr as * mut _ ) ;
75
109
}
76
110
0 commit comments