1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 04:44:59 +00:00

AK: Make MappedFile heap-allocated and ref-counted

Let's adapt this class a bit better to how it's actually being used.

Instead of having valid/invalid states and storing an error in case
it's invalid, a MappedFile is now always valid, and the factory
function that creates it will return an OSError if mapping fails.
This commit is contained in:
Andreas Kling 2021-01-10 15:55:54 +01:00
parent 70fce5c4c7
commit 2f3b901f7f
36 changed files with 184 additions and 199 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,6 +25,7 @@
*/
#include <AK/MappedFile.h>
#include <AK/ScopeGuard.h>
#include <AK/String.h>
#include <fcntl.h>
#include <stdio.h>
@ -32,68 +33,43 @@
#include <sys/stat.h>
#include <unistd.h>
//#define DEBUG_MAPPED_FILE
namespace AK {
MappedFile::MappedFile(const StringView& file_name)
Result<NonnullRefPtr<MappedFile>, OSError> MappedFile::map(const StringView& path)
{
int fd = open_with_path_length(file_name.characters_without_null_termination(), file_name.length(), O_RDONLY | O_CLOEXEC, 0);
int fd = open_with_path_length(path.characters_without_null_termination(), path.length(), O_RDONLY | O_CLOEXEC, 0);
if (fd < 0)
return OSError(errno);
if (fd == -1) {
m_errno = errno;
perror("open");
return;
}
ScopeGuard fd_close_guard = [fd] {
close(fd);
};
struct stat st;
fstat(fd, &st);
m_size = st.st_size;
m_map = mmap(nullptr, m_size, PROT_READ, MAP_SHARED, fd, 0);
if (m_map == MAP_FAILED) {
m_errno = errno;
perror("mmap");
if (fstat(fd, &st) < 0) {
auto saved_errno = errno;
return OSError(saved_errno);
}
#ifdef DEBUG_MAPPED_FILE
dbgln("MappedFile(\"{}\") := ( fd={}, m_size={}, m_map={} )", file_name, fd, m_size, m_map);
#endif
auto size = st.st_size;
auto* ptr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
if (ptr == MAP_FAILED)
return OSError(errno);
return adopt(*new MappedFile(ptr, size));
}
MappedFile::MappedFile(void* ptr, size_t size)
: m_data(ptr)
, m_size(size)
{
}
MappedFile::~MappedFile()
{
unmap();
}
void MappedFile::unmap()
{
if (!is_valid())
return;
int rc = munmap(m_map, m_size);
auto rc = munmap(m_data, m_size);
ASSERT(rc == 0);
m_size = 0;
m_map = (void*)-1;
}
MappedFile::MappedFile(MappedFile&& other)
: m_size(other.m_size)
, m_map(other.m_map)
{
other.m_size = 0;
other.m_map = (void*)-1;
}
MappedFile& MappedFile::operator=(MappedFile&& other)
{
if (this == &other)
return *this;
unmap();
swap(m_size, other.m_size);
swap(m_map, other.m_map);
return *this;
}
}