blob: 55646b78bbceaadf0f5e39b3274e502507e4888f [file] [log] [blame]
// 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 <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/string.h>
#include <fs/remote-dir.h>
#include <fs/tracked-remote-dir.h>
namespace fs {
TrackedRemoteDir::TrackedRemoteDir(zx::channel remote)
: RemoteDir(std::move(remote)), tracker_(this, GetRemote(), ZX_CHANNEL_PEER_CLOSED),
container_(nullptr) {
ZX_DEBUG_ASSERT(!IsTracked());
}
zx_status_t TrackedRemoteDir::AddAsTrackedEntry(async_dispatcher_t* dispatcher,
PseudoDir* container, fbl::String name) {
if (IsTracked()) {
return ZX_ERR_BAD_STATE;
}
ZX_DEBUG_ASSERT(!IsTracked());
ZX_DEBUG_ASSERT(!tracker_.is_pending());
ZX_DEBUG_ASSERT(container_ == nullptr);
ZX_DEBUG_ASSERT(container != nullptr);
zx_status_t status = container->AddEntry(name, fbl::WrapRefPtr(this));
if (status != ZX_OK) {
return status;
}
container_ = container;
name_ = std::move(name);
// When tracker_ completes, |HandleClose()| is invoked.
return tracker_.Begin(dispatcher);
}
void TrackedRemoteDir::HandleClose(async_dispatcher_t* dispatcher, async::WaitBase* wait,
zx_status_t status, const zx_packet_signal_t* signal) {
ZX_DEBUG_ASSERT(IsTracked());
container_->RemoveEntry(name_, this);
// After we have removed ourself from the PseudoDirectory, we may have been deleted.
// Do not deference anything else within |this|.
}
bool TrackedRemoteDir::IsTracked() const {
return container_ != nullptr;
}
} // namespace fs