@@ -22,8 +22,10 @@ use ark::shell::Shell;
22
22
use ark:: version:: detect_r;
23
23
use bus:: Bus ;
24
24
use crossbeam:: channel:: bounded;
25
+ use crossbeam:: channel:: unbounded;
25
26
use log:: * ;
26
27
use nix:: sys:: signal:: * ;
28
+ use notify:: Watcher ;
27
29
use stdext:: unwrap;
28
30
29
31
fn start_kernel ( connection_file : ConnectionFile , capture_streams : bool ) {
@@ -203,6 +205,8 @@ fn main() {
203
205
204
206
let mut connection_file: Option < String > = None ;
205
207
let mut log_file: Option < String > = None ;
208
+ let mut startup_notifier_file: Option < String > = None ;
209
+ let mut startup_delay: Option < std:: time:: Duration > = None ;
206
210
let mut has_action = false ;
207
211
let mut capture_streams = true ;
208
212
@@ -241,23 +245,86 @@ fn main() {
241
245
break ;
242
246
}
243
247
} ,
248
+ "--startup-notifier-file" => {
249
+ if let Some ( file) = argv. next ( ) {
250
+ startup_notifier_file = Some ( file) ;
251
+ } else {
252
+ eprintln ! (
253
+ "A notification file must be specified with the --startup-notifier-file argument."
254
+ ) ;
255
+ break ;
256
+ }
257
+ } ,
258
+ "--startup-delay" => {
259
+ if let Some ( delay_arg) = argv. next ( ) {
260
+ if let Ok ( delay) = delay_arg. parse :: < u64 > ( ) {
261
+ startup_delay = Some ( std:: time:: Duration :: from_millis ( delay) ) ;
262
+ } else {
263
+ eprintln ! ( "Can't parse delay in milliseconds" ) ;
264
+ break ;
265
+ }
266
+ } else {
267
+ eprintln ! (
268
+ "A delay in milliseconds must be specified with the --startup-delay argument."
269
+ ) ;
270
+ break ;
271
+ }
272
+ } ,
244
273
other => {
245
274
eprintln ! ( "Argument '{}' unknown" , other) ;
246
275
break ;
247
276
} ,
248
277
}
249
278
}
250
279
280
+ // Initialize the logger.
281
+ logger:: initialize ( log_file. as_deref ( ) ) ;
282
+
283
+ if let Some ( file) = startup_notifier_file {
284
+ let path = std:: path:: Path :: new ( & file) ;
285
+ let ( tx, rx) = unbounded ( ) ;
286
+
287
+ if let Err ( err) = ( || -> anyhow:: Result < ( ) > {
288
+ let config = notify:: Config :: default ( )
289
+ . with_poll_interval ( std:: time:: Duration :: from_millis ( 2 ) )
290
+ . with_compare_contents ( false ) ;
291
+
292
+ let mut watcher = notify:: RecommendedWatcher :: new ( tx, config) . unwrap ( ) ;
293
+ watcher. watch ( path, notify:: RecursiveMode :: NonRecursive ) ?;
294
+
295
+ loop {
296
+ let ev = rx. recv ( ) ?;
297
+ match ev. unwrap ( ) . kind {
298
+ notify:: event:: EventKind :: Modify ( _) => {
299
+ break ;
300
+ } ,
301
+ notify:: event:: EventKind :: Remove ( _) => {
302
+ break ;
303
+ } ,
304
+ _ => {
305
+ continue ;
306
+ } ,
307
+ }
308
+ }
309
+
310
+ watcher. unwatch ( path) ?;
311
+ Ok ( ( ) )
312
+ } ) ( ) {
313
+ eprintln ! ( "Problem with the delay file: {:?}" , err) ;
314
+ }
315
+ }
316
+
317
+ if let Some ( delay) = startup_delay {
318
+ std:: thread:: sleep ( delay) ;
319
+ }
320
+
251
321
// If the user didn't specify an action, print the usage instructions and
252
322
// exit
253
323
if !has_action {
254
324
print_usage ( ) ;
255
325
return ;
256
326
}
257
327
258
- // Initialize the logger.
259
- logger:: initialize ( log_file. as_deref ( ) ) ;
260
-
261
328
// Register segfault handler to get a backtrace. Should be after
262
329
// initialising `log!`. Note that R will not override this handler
263
330
// because we set `R_SignalHandlers` to 0 before startup.
0 commit comments