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:
parent
70fce5c4c7
commit
2f3b901f7f
36 changed files with 184 additions and 199 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue