blob: 12edd7b5d95018aa75e5fe52bdf7796446cbb60d [file] [log] [blame]
// Copyright 2024 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.
#ifndef SRC_GRAPHICS_DISPLAY_LIB_DRIVER_FRAMEWORK_MIGRATION_UTILS_DISPATCHER_LOOP_BACKED_DISPATCHER_H_
#define SRC_GRAPHICS_DISPLAY_LIB_DRIVER_FRAMEWORK_MIGRATION_UTILS_DISPATCHER_LOOP_BACKED_DISPATCHER_H_
#include <lib/async-loop/cpp/loop.h>
#include <lib/ddk/device.h>
#include <lib/zx/result.h>
#include <zircon/errors.h>
#include <string_view>
#include <fbl/alloc_checker.h>
#include "src/graphics/display/lib/driver-framework-migration-utils/dispatcher/dispatcher.h"
namespace display {
// An async_dispatcher_t backed by an async Loop running on a dedicated thread.
//
// The Loop is owned by the `LoopBackedDispatcher` instance and is shut down
// iff the `LoopBackedDispatcher` is destroyed.
//
// The Loop allows dispatch of async tasks and interrupt requests.
class LoopBackedDispatcher final : public Dispatcher {
public:
// Factory function that creates an asynchronous dispatch Loop and starts its
// worker thread of `thread_name` and as `scheduler_role`.
//
// Preferred for production use.
//
// `device` must not be null.
// `thread_name` must not be empty.
// `scheduler_role` is a hint. It's not an error if `LoopBackedDispatcher` fails to
// set the worker thread's scheduler role.
static zx::result<std::unique_ptr<Dispatcher>> Create(zx_device_t* device,
std::string_view thread_name,
std::string_view scheduler_role);
// Factory function that creates an asynchronous dispatch Loop and starts its
// worker thread of `thread_name` without setting the scheduling role.
//
// `thread_name` must not be empty.
static zx::result<std::unique_ptr<Dispatcher>> Create(std::string_view thread_name);
// Prefer the `Create()` factory method.
LoopBackedDispatcher();
~LoopBackedDispatcher() override;
LoopBackedDispatcher(const LoopBackedDispatcher&) = delete;
LoopBackedDispatcher(LoopBackedDispatcher&&) = delete;
LoopBackedDispatcher& operator=(const LoopBackedDispatcher&) = delete;
LoopBackedDispatcher& operator=(LoopBackedDispatcher&&) = delete;
// Dispatcher:
async_dispatcher_t* async_dispatcher() const override { return loop_.dispatcher(); }
private:
// Must be called exactly once for each valid `LoopBackedDispatcher` instance.
//
// `thread_name` must not be empty.
zx::result<> StartThread(std::string_view thread_name);
// `scheduler_role` is a hint. It's not an error if `LoopBackedDispatcher` fails to
// set the worker thread's scheduler role.
zx::result<> SetThreadSchedulerRole(std::string_view scheduler_role, zx_device_t* device);
async::Loop loop_;
thrd_t loop_thread_;
};
} // namespace display
#endif // SRC_GRAPHICS_DISPLAY_LIB_DRIVER_FRAMEWORK_MIGRATION_UTILS_DISPATCHER_LOOP_BACKED_DISPATCHER_H_