blob: 871a4bab87110053ea803c1c0c38a0b00f4aca7e [file] [log] [blame]
// Copyright 2017 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.
#pragma once
#ifndef __Fuchsia__
#error "Fuchsia-only header"
#endif
#include <stdint.h>
#include <async/wait.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>
#include <fs/vfs.h>
#include <fs/vnode.h>
#include <zx/event.h>
namespace fs {
// Connection represents an open connection to a Vnode (the server-side
// component of a file descriptor). The Vnode's methods will be invoked
// in response to RIO protocol messages received over the channel.
//
// This class is thread-safe.
class Connection : public fbl::DoublyLinkedListable<fbl::unique_ptr<Connection>> {
public:
// Create a connection bound to a particular vnode.
//
// The VFS will be notified when remote side closes the connection.
//
// |vfs| is the VFS which is responsible for dispatching operations to the vnode.
// |vnode| is the vnode which will handle I/O requests.
// |channel| is the channel on which the RIO protocol will be served.
// |flags| are the file flags passed to |open()|, such as |O_RDONLY|.
Connection(fs::Vfs* vfs, fbl::RefPtr<fs::Vnode> vnode, zx::channel channel,
uint32_t flags);
// Closes the connection.
//
// The connection must not be destroyed if its wait handler is running
// concurrently on another thread.
//
// In practice, this means the connection must have already been remotely
// closed, or it must be destroyed on the wait handler's dispatch thread
// to prevent a race.
~Connection();
// Begins waiting for messages on the channel.
//
// Must be called at most once in the lifetime of the connection.
zx_status_t Serve();
private:
zx_status_t CallHandler();
static zx_status_t HandleMessageThunk(zxrio_msg_t* msg, void* cookie);
zx_status_t HandleMessage(zxrio_msg_t* msg);
bool is_waiting() const { return wait_.object() != ZX_HANDLE_INVALID; }
fs::Vfs* const vfs_;
fbl::RefPtr<fs::Vnode> const vnode_;
// Channel on which the connection is being served.
zx::channel channel_;
// Asynchronous wait for incoming messages.
// The object field is |ZX_HANDLE_INVALID| when not actively waiting.
async::Wait wait_;
// Open flags such as |O_RDONLY|, |O_ADMIN|, and other bits.
uint32_t flags_;
// Handle to event which allows client to refer to open vnodes in multi-path
// operations (see: link, rename). Defaults to ZX_HANDLE_INVALID.
// Validated on the server-side using cookies.
zx::event token_{};
// Directory cookie for readdir operations.
fs::vdircookie_t dircookie_{};
// Current seek offset.
size_t offset_{};
};
} // namespace fs