| // Copyright 2020 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| use { | |
| fidl::{endpoints::RequestStream, handle::AsyncChannel}, | |
| fidl_fuchsia_process_lifecycle::{LifecycleRequest, LifecycleRequestStream}, | |
| fuchsia_async::{self as fasync}, | |
| fuchsia_runtime::{self as fruntime, HandleInfo, HandleType}, | |
| fuchsia_syslog::{self as fxlog, fx_log_err, fx_log_info}, | |
| fuchsia_zircon::{self as zx}, | |
| futures_util::stream::TryStreamExt, | |
| std::process, | |
| }; | |
| /// Example which takes the Lifecycle handle passed by the Runner. The program | |
| /// waits for a request on the channel to stop, then closes the channel and | |
| /// exits normally (vs abnormally). | |
| #[fasync::run_singlethreaded] | |
| async fn main() { | |
| fxlog::init().expect("logger failed to start"); | |
| match fruntime::take_startup_handle(HandleInfo::new(HandleType::Lifecycle, 0)) { | |
| Some(lifecycle_handle) => { | |
| fx_log_info!("Lifecycle channel received."); | |
| // We could start waiting for a message on this channel which | |
| // would tell us to stop. Instead we close it, indicating to our | |
| // Runner that we are done. | |
| let x: zx::Channel = lifecycle_handle.into(); | |
| let async_x = AsyncChannel::from( | |
| fasync::Channel::from_channel(x).expect("Async channel conversion failed."), | |
| ); | |
| let mut req_stream = LifecycleRequestStream::from_channel(async_x); | |
| fx_log_info!("Awaiting request to close"); | |
| while let Some(request) = | |
| req_stream.try_next().await.expect("Failure receiving lifecycle FIDL message") | |
| { | |
| match request { | |
| LifecycleRequest::Stop { control_handle: c } => { | |
| fx_log_info!("Receive request to stop, bye bye!"); | |
| c.shutdown(); | |
| process::exit(0); | |
| } | |
| } | |
| } | |
| // We only arrive here if the lifecycle channel closed without | |
| // first sending the shutdown event, which is unexpected. | |
| process::abort(); | |
| } | |
| None => { | |
| // We did not receive a lifecycle channel, exit abnormally. | |
| fx_log_err!("No lifecycle channel received, exiting."); | |
| process::abort(); | |
| } | |
| } | |
| } |