@@ -18,6 +18,7 @@ use translate::{from_glib, from_glib_full, FromGlib, ToGlib, ToGlibPtr};
18
18
use libc;
19
19
20
20
use Source ;
21
+ use MainContext ;
21
22
22
23
/// The id of a source that is returned by `idle_add` and `timeout_add`.
23
24
#[ derive( Debug , Eq , PartialEq ) ]
@@ -108,8 +109,8 @@ unsafe extern "C" fn destroy_closure(ptr: gpointer) {
108
109
Box :: < RefCell < Box < FnMut ( ) -> Continue + ' static > > > :: from_raw ( ptr as * mut _ ) ;
109
110
}
110
111
111
- fn into_raw < F : FnMut ( ) -> Continue + Send + ' static > ( func : F ) -> gpointer {
112
- let func: Box < RefCell < Box < FnMut ( ) -> Continue + Send + ' static > > > =
112
+ fn into_raw < F : FnMut ( ) -> Continue + ' static > ( func : F ) -> gpointer {
113
+ let func: Box < RefCell < Box < FnMut ( ) -> Continue + ' static > > > =
113
114
Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
114
115
Box :: into_raw ( func) as gpointer
115
116
}
@@ -125,8 +126,8 @@ unsafe extern "C" fn destroy_closure_child_watch(ptr: gpointer) {
125
126
}
126
127
127
128
#[ cfg_attr( feature = "cargo-clippy" , allow( type_complexity) ) ]
128
- fn into_raw_child_watch < F : FnMut ( Pid , i32 ) + Send + ' static > ( func : F ) -> gpointer {
129
- let func: Box < RefCell < Box < FnMut ( Pid , i32 ) + Send + ' static > > > =
129
+ fn into_raw_child_watch < F : FnMut ( Pid , i32 ) + ' static > ( func : F ) -> gpointer {
130
+ let func: Box < RefCell < Box < FnMut ( Pid , i32 ) + ' static > > > =
130
131
Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
131
132
Box :: into_raw ( func) as gpointer
132
133
}
@@ -144,8 +145,8 @@ unsafe extern "C" fn destroy_closure_unix_fd(ptr: gpointer) {
144
145
}
145
146
146
147
#[ cfg( any( unix, feature = "dox" ) ) ]
147
- fn into_raw_unix_fd < F : FnMut ( RawFd , IOCondition ) -> Continue + Send + ' static > ( func : F ) -> gpointer {
148
- let func: Box < RefCell < Box < FnMut ( RawFd , IOCondition ) -> Continue + Send + ' static > > > =
148
+ fn into_raw_unix_fd < F : FnMut ( RawFd , IOCondition ) -> Continue + ' static > ( func : F ) -> gpointer {
149
+ let func: Box < RefCell < Box < FnMut ( RawFd , IOCondition ) -> Continue + ' static > > > =
149
150
Box :: new ( RefCell :: new ( Box :: new ( func) ) ) ;
150
151
Box :: into_raw ( func) as gpointer
151
152
}
@@ -164,6 +165,27 @@ where F: FnMut() -> Continue + Send + 'static {
164
165
}
165
166
}
166
167
168
+ /// Adds a closure to be called by the default main loop when it's idle.
169
+ ///
170
+ /// `func` will be called repeatedly until it returns `Continue(false)`.
171
+ ///
172
+ /// The default main loop almost always is the main loop of the main thread.
173
+ /// Thus the closure is called on the main thread.
174
+ ///
175
+ /// Different to `idle_add()`, this does not require `func` to be
176
+ /// `Send` but can only be called from the thread that owns the main context.
177
+ ///
178
+ /// This function panics if called from a different thread than the one that
179
+ /// owns the main context.
180
+ pub fn idle_add_local < F > ( func : F ) -> SourceId
181
+ where F : FnMut ( ) -> Continue + ' static {
182
+ unsafe {
183
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
184
+ from_glib ( glib_ffi:: g_idle_add_full ( glib_ffi:: G_PRIORITY_DEFAULT_IDLE , Some ( trampoline) ,
185
+ into_raw ( func) , Some ( destroy_closure) ) )
186
+ }
187
+ }
188
+
167
189
/// Adds a closure to be called by the default main loop at regular intervals
168
190
/// with millisecond granularity.
169
191
///
@@ -182,6 +204,31 @@ where F: FnMut() -> Continue + Send + 'static {
182
204
}
183
205
}
184
206
207
+ /// Adds a closure to be called by the default main loop at regular intervals
208
+ /// with millisecond granularity.
209
+ ///
210
+ /// `func` will be called repeatedly every `interval` milliseconds until it
211
+ /// returns `Continue(false)`. Precise timing is not guaranteed, the timeout may
212
+ /// be delayed by other events. Prefer `timeout_add_seconds` when millisecond
213
+ /// precision is not necessary.
214
+ ///
215
+ /// The default main loop almost always is the main loop of the main thread.
216
+ /// Thus the closure is called on the main thread.
217
+ ///
218
+ /// Different to `timeout_add()`, this does not require `func` to be
219
+ /// `Send` but can only be called from the thread that owns the main context.
220
+ ///
221
+ /// This function panics if called from a different thread than the one that
222
+ /// owns the main context.
223
+ pub fn timeout_add_local < F > ( interval : u32 , func : F ) -> SourceId
224
+ where F : FnMut ( ) -> Continue + ' static {
225
+ unsafe {
226
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
227
+ from_glib ( glib_ffi:: g_timeout_add_full ( glib_ffi:: G_PRIORITY_DEFAULT , interval,
228
+ Some ( trampoline) , into_raw ( func) , Some ( destroy_closure) ) )
229
+ }
230
+ }
231
+
185
232
/// Adds a closure to be called by the default main loop at regular intervals
186
233
/// with second granularity.
187
234
///
@@ -199,6 +246,30 @@ where F: FnMut() -> Continue + Send + 'static {
199
246
}
200
247
}
201
248
249
+ /// Adds a closure to be called by the default main loop at regular intervals
250
+ /// with second granularity.
251
+ ///
252
+ /// `func` will be called repeatedly every `interval` seconds until it
253
+ /// returns `Continue(false)`. Precise timing is not guaranteed, the timeout may
254
+ /// be delayed by other events.
255
+ ///
256
+ /// The default main loop almost always is the main loop of the main thread.
257
+ /// Thus the closure is called on the main thread.
258
+ ///
259
+ /// Different to `timeout_add_seconds()`, this does not require `func` to be
260
+ /// `Send` but can only be called from the thread that owns the main context.
261
+ ///
262
+ /// This function panics if called from a different thread than the one that
263
+ /// owns the main context.
264
+ pub fn timeout_add_seconds_local < F > ( interval : u32 , func : F ) -> SourceId
265
+ where F : FnMut ( ) -> Continue + ' static {
266
+ unsafe {
267
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
268
+ from_glib ( glib_ffi:: g_timeout_add_seconds_full ( glib_ffi:: G_PRIORITY_DEFAULT , interval,
269
+ Some ( trampoline) , into_raw ( func) , Some ( destroy_closure) ) )
270
+ }
271
+ }
272
+
202
273
/// Adds a closure to be called by the main loop the returned `Source` is attached to when a child
203
274
/// process exits.
204
275
///
@@ -212,6 +283,26 @@ where F: FnMut(Pid, i32) + Send + 'static {
212
283
}
213
284
}
214
285
286
+ /// Adds a closure to be called by the main loop the returned `Source` is attached to when a child
287
+ /// process exits.
288
+ ///
289
+ /// `func` will be called when `pid` exits
290
+ ///
291
+ /// Different to `child_watch_add()`, this does not require `func` to be
292
+ /// `Send` but can only be called from the thread that owns the main context.
293
+ ///
294
+ /// This function panics if called from a different thread than the one that
295
+ /// owns the main context.
296
+ pub fn child_watch_add_local < ' a , N : Into < Option < & ' a str > > , F > ( pid : Pid , func : F ) -> SourceId
297
+ where F : FnMut ( Pid , i32 ) + ' static {
298
+ unsafe {
299
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
300
+ let trampoline = trampoline_child_watch as * mut libc:: c_void ;
301
+ from_glib ( glib_ffi:: g_child_watch_add_full ( glib_ffi:: G_PRIORITY_DEFAULT , pid. 0 ,
302
+ Some ( transmute ( trampoline) ) , into_raw_child_watch ( func) , Some ( destroy_closure_child_watch) ) )
303
+ }
304
+ }
305
+
215
306
#[ cfg( any( unix, feature = "dox" ) ) ]
216
307
/// Adds a closure to be called by the default main loop whenever a UNIX signal is raised.
217
308
///
@@ -228,6 +319,29 @@ where F: FnMut() -> Continue + Send + 'static {
228
319
}
229
320
}
230
321
322
+ #[ cfg( any( unix, feature = "dox" ) ) ]
323
+ /// Adds a closure to be called by the default main loop whenever a UNIX signal is raised.
324
+ ///
325
+ /// `func` will be called repeatedly every time `signum` is raised until it
326
+ /// returns `Continue(false)`.
327
+ ///
328
+ /// The default main loop almost always is the main loop of the main thread.
329
+ /// Thus the closure is called on the main thread.
330
+ ///
331
+ /// Different to `unix_signal_add()`, this does not require `func` to be
332
+ /// `Send` but can only be called from the thread that owns the main context.
333
+ ///
334
+ /// This function panics if called from a different thread than the one that
335
+ /// owns the main context.
336
+ pub fn unix_signal_add_local < F > ( signum : i32 , func : F ) -> SourceId
337
+ where F : FnMut ( ) -> Continue + ' static {
338
+ unsafe {
339
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
340
+ from_glib ( glib_ffi:: g_unix_signal_add_full ( glib_ffi:: G_PRIORITY_DEFAULT , signum,
341
+ Some ( trampoline) , into_raw ( func) , Some ( destroy_closure) ) )
342
+ }
343
+ }
344
+
231
345
#[ cfg( any( unix, feature = "dox" ) ) ]
232
346
/// Adds a closure to be called by the main loop the returned `Source` is attached to whenever a
233
347
/// UNIX file descriptor reaches the given IO condition.
@@ -246,6 +360,31 @@ where F: FnMut(RawFd, IOCondition) -> Continue + Send + 'static {
246
360
}
247
361
}
248
362
363
+ #[ cfg( any( unix, feature = "dox" ) ) ]
364
+ /// Adds a closure to be called by the main loop the returned `Source` is attached to whenever a
365
+ /// UNIX file descriptor reaches the given IO condition.
366
+ ///
367
+ /// `func` will be called repeatedly while the file descriptor matches the given IO condition
368
+ /// until it returns `Continue(false)`.
369
+ ///
370
+ /// The default main loop almost always is the main loop of the main thread.
371
+ /// Thus the closure is called on the main thread.
372
+ ///
373
+ /// Different to `unix_fd_add()`, this does not require `func` to be
374
+ /// `Send` but can only be called from the thread that owns the main context.
375
+ ///
376
+ /// This function panics if called from a different thread than the one that
377
+ /// owns the main context.
378
+ pub fn unix_fd_add_local < F > ( fd : RawFd , condition : IOCondition , func : F ) -> SourceId
379
+ where F : FnMut ( RawFd , IOCondition ) -> Continue + ' static {
380
+ unsafe {
381
+ assert ! ( MainContext :: default ( ) . is_owner( ) ) ;
382
+ let trampoline = trampoline_unix_fd as * mut libc:: c_void ;
383
+ from_glib ( glib_ffi:: g_unix_fd_add_full ( glib_ffi:: G_PRIORITY_DEFAULT , fd, condition. to_glib ( ) ,
384
+ Some ( transmute ( trampoline) ) , into_raw_unix_fd ( func) , Some ( destroy_closure_unix_fd) ) )
385
+ }
386
+ }
387
+
249
388
/// Removes the source with the given id `source_id` from the default main context.
250
389
///
251
390
/// It is a programmer error to attempt to remove a non-existent source.
0 commit comments