mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-04 23:55:08 +01:00
Implement RAII wrapper over file descriptors
The `FileDescriptor` class is a RAII wrapper over FDs which handles their lifetimes alongside other C++ semantics such as moving and copying. It has been used in `skyline::kernel::MemoryManager` to handle the lifetime of the ashmem FD correctly, it wasn't being destroyed earlier which can result in leaking FDs across runs.
This commit is contained in:
parent
7ce2a903a1
commit
344c5f2a62
69
app/src/main/cpp/skyline/common/file_descriptor.h
Normal file
69
app/src/main/cpp/skyline/common/file_descriptor.h
Normal file
@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include "base.h"
|
||||
|
||||
namespace skyline {
|
||||
/**
|
||||
* @brief A RAII wrapper around Linux file descriptors which automatically closes the file descriptor when it goes out of scope and duplicates them on copies
|
||||
* @note This class should **always** be moved rather than copied where possible to avoid a system call for duplicating file descriptors
|
||||
*/
|
||||
class FileDescriptor {
|
||||
private:
|
||||
int fd;
|
||||
|
||||
public:
|
||||
FileDescriptor() : fd(-1) {}
|
||||
|
||||
FileDescriptor(int fd) : fd(fd) {}
|
||||
|
||||
FileDescriptor &operator=(int newFd) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
fd = newFd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileDescriptor(const FileDescriptor &other) : fd(dup(other.fd)) {
|
||||
if (fd == -1)
|
||||
throw exception("Failed to duplicate file descriptor: {}", strerror(errno));
|
||||
}
|
||||
|
||||
FileDescriptor &operator=(const FileDescriptor &other) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
fd = dup(other.fd);
|
||||
if (fd == -1)
|
||||
throw exception("Failed to duplicate file descriptor: {}", strerror(errno));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FileDescriptor(FileDescriptor &&other) : fd(other.fd) {
|
||||
other.fd = -1;
|
||||
}
|
||||
|
||||
FileDescriptor &operator=(FileDescriptor &&other) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
fd = other.fd;
|
||||
other.fd = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FileDescriptor() {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
operator int() const {
|
||||
return fd;
|
||||
}
|
||||
|
||||
int operator*() const {
|
||||
return fd;
|
||||
}
|
||||
};
|
||||
}
|
@ -3,8 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <common.h>
|
||||
#include <sys/mman.h>
|
||||
#include <common.h>
|
||||
#include <common/file_descriptor.h>
|
||||
|
||||
namespace skyline {
|
||||
namespace memory {
|
||||
@ -226,7 +227,7 @@ namespace skyline {
|
||||
memory::Region stack{};
|
||||
memory::Region tlsIo{}; //!< TLS/IO
|
||||
|
||||
int memoryFd{}; //!< The file descriptor of the memory backing for the entire guest address space
|
||||
FileDescriptor memoryFd{}; //!< The file descriptor of the memory backing for the entire guest address space
|
||||
|
||||
std::shared_mutex mutex; //!< Synchronizes any operations done on the VMM, it's locked in shared mode by readers and exclusive mode by writers
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user