blob: 9532f901d3282b7bbf07e3d6c8d9fa40c0591306 [file] [log] [blame]
// Copyright 2016 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 "magma_system_device.h"
#include "magma_system_connection.h"
#include "magma_util/macros.h"
#include "platform_object.h"
uint32_t MagmaSystemDevice::GetDeviceId()
{
uint64_t result;
magma::Status status = Query(MAGMA_QUERY_DEVICE_ID, &result);
if (!status.ok())
return 0;
DASSERT(result >> 32 == 0);
return static_cast<uint32_t>(result);
}
std::shared_ptr<magma::PlatformConnection>
MagmaSystemDevice::Open(std::shared_ptr<MagmaSystemDevice> device, msd_client_id_t client_id)
{
msd_connection_t* msd_connection = msd_device_open(device->msd_dev(), client_id);
if (!msd_connection)
return DRETP(nullptr, "msd_device_open failed");
return magma::PlatformConnection::Create(std::make_unique<MagmaSystemConnection>(
std::move(device), MsdConnectionUniquePtr(msd_connection)));
}
void MagmaSystemDevice::StartConnectionThread(
std::shared_ptr<magma::PlatformConnection> platform_connection)
{
std::unique_lock<std::mutex> lock(connection_list_mutex_);
auto shutdown_event = platform_connection->ShutdownEvent();
std::thread thread(magma::PlatformConnection::RunLoop, std::move(platform_connection));
connection_map_->insert(std::pair<std::thread::id, Connection>(
thread.get_id(), Connection{std::move(thread), std::move(shutdown_event)}));
}
void MagmaSystemDevice::ConnectionClosed(std::thread::id thread_id)
{
std::unique_lock<std::mutex> lock(connection_list_mutex_);
if (!connection_map_)
return;
auto iter = connection_map_->find(thread_id);
// May not be in the map if no connection thread was started.
if (iter != connection_map_->end()) {
iter->second.thread.detach();
connection_map_->erase(iter);
}
}
void MagmaSystemDevice::Shutdown()
{
std::unique_lock<std::mutex> lock(connection_list_mutex_);
auto map = std::move(connection_map_);
lock.unlock();
for (auto& element : *map) {
element.second.shutdown_event->Signal();
}
auto start = std::chrono::high_resolution_clock::now();
for (auto& element : *map) {
element.second.thread.join();
}
std::chrono::duration<double, std::milli> elapsed =
std::chrono::high_resolution_clock::now() - start;
DLOG("shutdown took %u ms", (uint32_t)elapsed.count());
(void)elapsed;
}