mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 15:55:29 +03: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
|
#pragma once
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <common.h>
|
||||||
|
#include <common/file_descriptor.h>
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace memory {
|
namespace memory {
|
||||||
@ -226,7 +227,7 @@ namespace skyline {
|
|||||||
memory::Region stack{};
|
memory::Region stack{};
|
||||||
memory::Region tlsIo{}; //!< TLS/IO
|
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
|
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