| 22 | } |
| 23 | |
| 24 | fn child_process() { |
| 25 | let mut result_write = std::io::stderr(); |
| 26 | let mut child_running = true; |
| 27 | while child_running { |
| 28 | tokio::runtime::Builder::new_multi_thread() |
| 29 | .enable_all() |
| 30 | .build() |
| 31 | .unwrap() |
| 32 | .block_on(async { |
| 33 | 'task: loop { |
| 34 | println!("child: creating stdin"); |
| 35 | let mut stdin = wasmtime_wasi::cli::stdin().p2_stream(); |
| 36 | |
| 37 | println!("child: checking that stdin is not ready"); |
| 38 | assert!( |
| 39 | tokio::time::timeout( |
| 40 | std::time::Duration::from_millis(100), |
| 41 | stdin.ready() |
| 42 | ) |
| 43 | .await |
| 44 | .is_err(), |
| 45 | "stdin available too soon" |
| 46 | ); |
| 47 | |
| 48 | writeln!(&mut result_write, "start").unwrap(); |
| 49 | |
| 50 | println!("child: started"); |
| 51 | |
| 52 | let mut buffer = String::new(); |
| 53 | loop { |
| 54 | println!("child: waiting for stdin to be ready"); |
| 55 | stdin.ready().await; |
| 56 | |
| 57 | println!("child: reading input"); |
| 58 | // We can't effectively test for the case where stdin was closed, so panic if it is... |
| 59 | let bytes = stdin.read(1024).unwrap(); |
| 60 | |
| 61 | println!("child got: {bytes:?}"); |
| 62 | |
| 63 | buffer.push_str(std::str::from_utf8(bytes.as_ref()).unwrap()); |
| 64 | if let Some((line, rest)) = buffer.split_once('\n') { |
| 65 | if line == "all done" { |
| 66 | writeln!(&mut result_write, "done").unwrap(); |
| 67 | println!("child: exiting..."); |
| 68 | child_running = false; |
| 69 | break 'task; |
| 70 | } else if line == "restart_runtime" { |
| 71 | writeln!(&mut result_write, "restarting").unwrap(); |
| 72 | println!("child: restarting runtime..."); |
| 73 | break 'task; |
| 74 | } else if line == "restart_task" { |
| 75 | writeln!(&mut result_write, "restarting").unwrap(); |
| 76 | println!("child: restarting task..."); |
| 77 | continue 'task; |
| 78 | } else { |
| 79 | writeln!(&mut result_write, "{line}").unwrap(); |
| 80 | } |
| 81 | |