blob: b885047579f76436fc3d49ea6c92f3a6ec0e1a03 [file] [log] [blame] [edit]
// Copyright 2019 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 "src/graphics/drivers/misc/goldfish/instance.h"
#include <fidl/fuchsia.hardware.goldfish/cpp/wire.h>
#include <lib/async/cpp/task.h>
#include <lib/ddk/debug.h>
#include <lib/zx/bti.h>
#include <zircon/threads.h>
#include <ddktl/fidl.h>
#include "src/graphics/drivers/misc/goldfish/pipe.h"
#include "src/graphics/drivers/misc/goldfish/pipe_device.h"
namespace goldfish {
namespace {
const char kTag[] = "goldfish-pipe";
} // namespace
Instance::Instance(PipeDevice* pipe_device, async_dispatcher_t* dispatcher)
: pipe_device_(pipe_device), dispatcher_(dispatcher) {}
Instance::~Instance() = default;
void Instance::OpenPipe(OpenPipeRequestView request, OpenPipeCompleter::Sync& completer) {
if (!request->pipe_request.is_valid()) {
zxlogf(ERROR, "%s: invalid channel", kTag);
completer.Close(ZX_ERR_INVALID_ARGS);
return;
}
async::PostTask(dispatcher_, [this, pipe_request = std::move(request->pipe_request)]() mutable {
auto pipe = std::make_unique<Pipe>(pipe_device_, dispatcher_, /* OnBind */ nullptr,
/* OnClose */ [this](Pipe* pipe_ptr) {
// We know |pipe_ptr| is still alive because |pipe_ptr|
// is still in |pipes_|.
ZX_DEBUG_ASSERT(pipes_.find(pipe_ptr) != pipes_.end());
pipes_.erase(pipe_ptr);
});
auto pipe_ptr = pipe.get();
pipes_.insert({pipe_ptr, std::move(pipe)});
pipe_ptr->Bind(std::move(pipe_request));
// Init() must be called after Bind() as it can cause an asynchronous
// failure. The pipe will be cleaned up later by the error handler in
// the event of a failure.
pipe_ptr->Init();
});
}
void Instance::DdkRelease() { delete this; }
} // namespace goldfish