blob: a8d236ec5ed7e50524124d6f357afefc0e4802aa [file] [log] [blame] [edit]
// 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/cpp/task.h>
#include <lib/sync/completion.h>
#include <memory>
#include <utility>
#include <fs/synchronous_vfs.h>
namespace fs {
SynchronousVfs::SynchronousVfs() : is_shutting_down_(false) {}
SynchronousVfs::SynchronousVfs(async_dispatcher_t* dispatcher)
: Vfs(dispatcher), is_shutting_down_(false) {}
SynchronousVfs::~SynchronousVfs() {
Shutdown(nullptr);
ZX_DEBUG_ASSERT(connections_.is_empty());
}
// Synchronously drop all connections.
void SynchronousVfs::Shutdown(ShutdownCallback handler) {
is_shutting_down_ = true;
UninstallAll(zx::time::infinite());
while (!connections_.is_empty()) {
connections_.front().SyncTeardown();
}
ZX_ASSERT_MSG(connections_.is_empty(), "Failed to complete VFS shutdown");
if (handler) {
handler(ZX_OK);
}
}
void SynchronousVfs::CloseAllConnectionsForVnode(const Vnode& node,
CloseAllConnectionsForVnodeCallback callback) {
for (auto connection = connections_.begin(); connection != connections_.end();) {
auto c = connection;
connection++;
if (c->vnode().get() == &node) {
c->SyncTeardown();
}
}
if (callback) {
callback();
}
}
zx_status_t SynchronousVfs::RegisterConnection(std::unique_ptr<internal::Connection> connection,
zx::channel channel) {
ZX_DEBUG_ASSERT(!is_shutting_down_);
connections_.push_back(std::move(connection));
zx_status_t status = connections_.back().StartDispatching(std::move(channel));
if (status != ZX_OK) {
connections_.pop_back();
return status;
}
return ZX_OK;
}
void SynchronousVfs::UnregisterConnection(internal::Connection* connection) {
// We drop the result of |erase| on the floor, effectively destroying the
// connection.
connections_.erase(*connection);
}
bool SynchronousVfs::IsTerminating() const { return is_shutting_down_; }
} // namespace fs