blob: dcba44a21560439e27435dcf55d3cf749c1eb8a7 [file] [log] [blame]
// Copyright 2018 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.
#![feature(async_await, await_macro)]
#![recursion_limit = "512"]
#[macro_use]
mod log_error;
mod active_session_queue;
mod fidl_clones;
mod mpmc;
mod publisher;
mod registry;
mod session_list;
mod session_proxy;
mod subscriber;
#[cfg(test)]
mod test;
use self::{
active_session_queue::ActiveSessionQueue, publisher::Publisher, registry::Registry,
session_list::SessionList,
};
use failure::Error;
use fuchsia_async as fasync;
use fuchsia_component::server::ServiceFs;
use fuchsia_zircon as zx;
use futures::{lock::Mutex, Future, StreamExt, TryFutureExt};
use std::sync::Arc;
use zx::AsHandleRef;
type Result<T> = std::result::Result<T, Error>;
const CHANNEL_BUFFER_SIZE: usize = 100;
/// This number should be forgiving. If we lower it we may want to build some
/// in-process staging area for changes so we can send them to clients that ACK
/// late. At 20 though, clients that don't ACK can't reasonably expect to be
/// accomodated.
const MAX_EVENTS_SENT_WITHOUT_ACK: usize = 20;
fn session_id_rights() -> zx::Rights {
zx::Rights::DUPLICATE | zx::Rights::TRANSFER | zx::Rights::INSPECT
}
fn clone_session_id_handle(session_id_handle: &zx::Event) -> Result<zx::Event> {
Ok(session_id_handle.as_handle_ref().duplicate(session_id_rights())?.into())
}
fn spawn_log_error(fut: impl Future<Output = Result<()>> + Send + 'static) {
fasync::spawn(fut.unwrap_or_else(|e| eprintln!("{}", e)))
}
#[fasync::run_singlethreaded]
async fn main() {
let session_list = Arc::new(Mutex::new(SessionList::default()));
let active_session_queue = Arc::new(Mutex::new(ActiveSessionQueue::default()));
let (active_session_sink, active_session_stream) = mpmc::channel(CHANNEL_BUFFER_SIZE);
let (collection_event_sink, collection_event_stream) = mpmc::channel(CHANNEL_BUFFER_SIZE);
let publisher = Publisher::new(
session_list.clone(),
active_session_queue.clone(),
active_session_sink,
collection_event_sink,
);
let registry = Registry::new(
session_list.clone(),
active_session_queue.clone(),
active_session_stream,
collection_event_stream,
);
let mut server = ServiceFs::new();
server
.dir("public")
.add_fidl_service(|request_stream| spawn_log_error(publisher.clone().serve(request_stream)))
.add_fidl_service(|request_stream| spawn_log_error(registry.clone().serve(request_stream)));
server.take_and_serve_directory_handle().expect("To serve Media Session services");
await!(server.collect::<()>());
}