blob: 07f7b6a6f364ef6fb173f931f0247ceb8be0b8a2 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IPCZ_SRC_REFERENCE_DRIVERS_MEMORY_H_
#define IPCZ_SRC_REFERENCE_DRIVERS_MEMORY_H_
#include "reference_drivers/file_descriptor.h"
#include "third_party/abseil-cpp/absl/types/span.h"
namespace ipcz::reference_drivers {
// A basic driver memory implementation for ipcz, which uses Linux-specific
// support for an anonymous file living entirely in RAM (see memfd_create()).
class MemfdMemory {
public:
// An mmap'd region of a MemfdMemory's underlying file. Instances of this
// object should be acquired from MemfdMemory::Map().
class Mapping {
public:
Mapping();
Mapping(void* base_address, size_t size);
Mapping(Mapping&&);
Mapping& operator=(Mapping&&);
Mapping(const Mapping&) = delete;
Mapping& operator=(const Mapping&) = delete;
~Mapping();
bool is_valid() const { return base_address_ != nullptr; }
size_t size() const { return size_; }
void* base() const { return base_address_; }
absl::Span<uint8_t> bytes() const {
return {static_cast<uint8_t*>(base()), size_};
}
template <typename T>
T* As() const {
return static_cast<T*>(base());
}
void Reset();
private:
void* base_address_ = nullptr;
size_t size_ = 0;
};
// Constructs an invalid MemfdMemory object which cannot be mapped.
MemfdMemory();
// Constructs a new MemfdMemory object over `descriptor`, a file descriptor
// which should have been previously taken from some other valid MemfdMemory
// object or otherwise acquried via memfd_create(). `size` must correspond to
// the size of the underlying memory file.
MemfdMemory(FileDescriptor fd, size_t size);
// Constructs a new MemfdMemory object over a newly allocated, anonymous
// shared memory file of at least `size` bytes.
explicit MemfdMemory(size_t size);
MemfdMemory(MemfdMemory&&);
MemfdMemory& operator=(MemfdMemory&&);
MemfdMemory(const MemfdMemory&) = delete;
MemfdMemory& operator=(const MemfdMemory&) = delete;
~MemfdMemory();
size_t size() const { return size_; }
bool is_valid() const { return fd_.is_valid(); }
const FileDescriptor& descriptor() const { return fd_; }
// Invalidates this object and returns a FileDescrtiptor which can be used
// later to reconstruct an equivalent MemfdMemory object with the same size().
FileDescriptor TakeDescriptor() { return std::move(fd_); }
// Resets this object, closing its underlying memory file descriptor.
void reset() { fd_.reset(); }
// Returns a new MemfdMemory object with its own handle to the same underlying
// memory file as `this`. Must only be called on a valid MemfdMemory object
// (i.e. is_valid() must be true.)
MemfdMemory Clone();
// Maps the entire file owned by this object and returns a Mapping for it.
// Must only be called on a valid MemfdMemory object (i.e. is_valid() must be
// true.)
Mapping Map();
private:
FileDescriptor fd_;
size_t size_ = 0;
};
} // namespace ipcz::reference_drivers
#endif // IPCZ_SRC_REFERENCE_DRIVERS_MEMORY_H_