OSDN Git Service

Catch sigint to shut down BT testing process
authorZach Johnson <zachoverflow@google.com>
Tue, 3 Nov 2020 18:47:39 +0000 (10:47 -0800)
committerZach Johnson <zachoverflow@google.com>
Fri, 6 Nov 2020 21:10:21 +0000 (13:10 -0800)
Temporary nix-based hack until we have tokio signal support.

Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --host
Change-Id: I6cfb1d2792a07ec42b3e17ac63e09b0eca583258

gd/rust/facade/Android.bp
gd/rust/facade/src/lib.rs
gd/rust/facade/src/main.rs

index ae9c58a..5a523fc 100644 (file)
@@ -24,6 +24,7 @@ rust_binary {
       "libfutures",
       "libgrpcio",
       "libtokio",
+      "libnix",
     ],
     host_supported: true,
 }
index 5bfa173..9959b1d 100644 (file)
@@ -8,8 +8,8 @@ pub mod empty {
     pub use protobuf::well_known_types::Empty;
 }
 
-pub use bt_facade_rootservice_proto::rootservice;
 pub use bt_facade_common_proto::common;
+pub use bt_facade_rootservice_proto::rootservice;
 
 use tokio::runtime::Runtime;
 
index d2dd910..7653975 100644 (file)
@@ -4,26 +4,31 @@
 extern crate clap;
 use clap::{App, Arg};
 
+#[macro_use]
+extern crate lazy_static;
+
 use grpcio::*;
 
-use futures::channel::oneshot;
+use futures::channel::mpsc;
 use futures::executor::block_on;
+use futures::stream::StreamExt;
 
 use bluetooth_with_facades::RootFacadeService;
 
-use std::io::{self, Read};
 use std::sync::Arc;
-use std::thread;
+use std::sync::Mutex;
 
 use tokio::runtime::Runtime;
 
+use nix::sys::signal;
+
 fn main() {
+    let sigint = install_sigint();
     let rt = Arc::new(Runtime::new().unwrap());
-    let runtime = Arc::clone(&rt);
-    runtime.block_on(async_main(rt));
+    rt.block_on(async_main(Arc::clone(&rt), sigint));
 }
 
-async fn async_main(rt: Arc<Runtime>) {
+async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) {
     let matches = App::new("bluetooth_with_facades")
         .about("The bluetooth stack, with testing facades enabled and exposed via gRPC.")
         .arg(
@@ -62,13 +67,36 @@ async fn async_main(rt: Arc<Runtime>) {
         .build()
         .unwrap();
 
-    let (tx, rx) = oneshot::channel();
-
-    thread::spawn(move || {
-        println!("Press ENTER to exit...");
-        let _ = io::stdin().read(&mut [0]).unwrap();
-        tx.send(())
-    });
-    block_on(rx).unwrap();
+    sigint.next().await;
     block_on(server.shutdown()).unwrap();
 }
+
+// TODO: remove as this is a temporary nix-based hack to catch SIGINT
+fn install_sigint() -> mpsc::UnboundedReceiver<()> {
+    let (tx, rx) = mpsc::unbounded();
+    *SIGINT_TX.lock().unwrap() = Some(tx);
+
+    let sig_action = signal::SigAction::new(
+        signal::SigHandler::Handler(handle_sigint),
+        signal::SaFlags::empty(),
+        signal::SigSet::empty(),
+    );
+    unsafe {
+        signal::sigaction(signal::SIGINT, &sig_action).unwrap();
+    }
+
+    rx
+}
+
+lazy_static! {
+    static ref SIGINT_TX: Mutex<Option<mpsc::UnboundedSender<()>>> = Mutex::new(None);
+}
+
+extern "C" fn handle_sigint(_: i32) {
+    let mut sigint_tx = SIGINT_TX.lock().unwrap();
+    if let Some(tx) = &*sigint_tx {
+        println!("Stopping gRPC root server due to SIGINT");
+        tx.unbounded_send(()).unwrap();
+    }
+    *sigint_tx = None;
+}