blob: 689eec7d4ffb9dffbf9cdc106b993a3e76f582db [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.
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/fit/function.h>
#include <memory>
// The driver is split up into separate concerns, with one instance of this
// class unifying the lifetime of those concerns (including the creation and
// destruction order).
// This is per-driver context, not per-device context.
// Anything that's driver-wide can go in here, or in instances rooted here.
class DriverCtx {
// This is a dedicated devhost for the device, so clean exit is only important
// to the extent that we need to be able to re-init the device, and possibly
// to ensure the device is left in lower-power mode. Since a new replacement
// devhost is coming up very shortly, and it can re-init from any device state
// (is the idea), it seems quite a lot better to let the new devhost worry
// about the device vs. a potentially-broken devhost on it's way out. Also,
// the system as a whole must tolerate a crash of a dedicated devhost anyway.
// So (at least for now) this method is free to just exit the devhost after
// attempting to give some debug breadcrumbs.
// TODO(dustingreen): Do format, printf, log, maybe some epitaphs.
void FatalError(const char* format, ...);
// The returned async::Loop* lasts for the whole lifetime of the driver (up to
// driver ops release()). All the things using the loop are per-device, and
// all devices are gone by the time the loop is deleted.
// Only non-blocking work can use this loop, as blocking could cause
// interference among clients. Blocking work should use some other thread.
async::Loop* shared_fidl_loop() { return shared_fidl_loop_.get(); }
// Can be compared to thrd_current() to determine if the caller is running on
// the shared FIDL thread.
thrd_t shared_fidl_thread() { return shared_fidl_thread_; }
// Run to_run on given dispatcher, in order.
void PostSerial(async_dispatcher_t* dispatcher, fit::closure to_run);
// Run to_run_on_shared_fidl_thread on shared_fidl_thread().
void PostToSharedFidl(fit::closure to_run_on_shared_fidl_thread);
std::unique_ptr<async::Loop> shared_fidl_loop_;
thrd_t shared_fidl_thread_;