blob: 6c4ace884606297f65bab9eac04b7e1ed3b31940 [file] [log] [blame]
// 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();
}
}
}