mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 13:20:04 +00:00
Merge pull request #4396 from FearlessTobi/open-delays
fs_user: Add a delay for each file open
This commit is contained in:
commit
21bda754b3
@ -11,6 +11,7 @@
|
|||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/file_sys/delay_generator.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
@ -153,6 +154,18 @@ public:
|
|||||||
* @return The number of free bytes in the archive
|
* @return The number of free bytes in the archive
|
||||||
*/
|
*/
|
||||||
virtual u64 GetFreeBytes() const = 0;
|
virtual u64 GetFreeBytes() const = 0;
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() {
|
||||||
|
if (delay_generator != nullptr) {
|
||||||
|
return delay_generator->GetOpenDelayNs();
|
||||||
|
}
|
||||||
|
LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default");
|
||||||
|
delay_generator = std::make_unique<DefaultDelayGenerator>();
|
||||||
|
return delay_generator->GetOpenDelayNs();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchiveFactory : NonCopyable {
|
class ArchiveFactory : NonCopyable {
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
class ExtSaveDataDelayGenerator : public DelayGenerator {
|
class ExtSaveDataDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(std::size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// This is the delay measured for a savedate read,
|
// This is the delay measured for a savedata read,
|
||||||
// not for extsaveData
|
// not for extsaveData
|
||||||
// For now we will take that
|
// For now we will take that
|
||||||
static constexpr u64 slope(183);
|
static constexpr u64 slope(183);
|
||||||
@ -69,6 +69,14 @@ public:
|
|||||||
std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return ipc_delay_nanoseconds;
|
return ipc_delay_nanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on N3DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/929b68489f4abb2c6cf81d56970a20b4
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(3085068);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +88,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
class ExtSaveDataArchive : public SaveDataArchive {
|
class ExtSaveDataArchive : public SaveDataArchive {
|
||||||
public:
|
public:
|
||||||
explicit ExtSaveDataArchive(const std::string& mount_point) : SaveDataArchive(mount_point) {}
|
explicit ExtSaveDataArchive(const std::string& mount_point,
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator_)
|
||||||
|
: SaveDataArchive(mount_point) {
|
||||||
|
delay_generator = std::move(delay_generator_);
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return "ExtSaveDataArchive: " + mount_point;
|
return "ExtSaveDataArchive: " + mount_point;
|
||||||
@ -232,7 +244,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
|
|||||||
return ERR_NOT_FORMATTED;
|
return ERR_NOT_FORMATTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto archive = std::make_unique<ExtSaveDataArchive>(fullpath);
|
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>();
|
||||||
|
auto archive = std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator));
|
||||||
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,14 @@ public:
|
|||||||
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(269082);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path,
|
ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFile(const Path& path,
|
||||||
@ -378,7 +386,8 @@ bool ArchiveFactory_SDMC::Initialize() {
|
|||||||
|
|
||||||
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path,
|
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path,
|
||||||
u64 program_id) {
|
u64 program_id) {
|
||||||
auto archive = std::make_unique<SDMCArchive>(sdmc_directory);
|
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<SDMCDelayGenerator>();
|
||||||
|
auto archive = std::make_unique<SDMCArchive>(sdmc_directory, std::move(delay_generator));
|
||||||
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,11 @@ namespace FileSys {
|
|||||||
/// Archive backend for SDMC archive
|
/// Archive backend for SDMC archive
|
||||||
class SDMCArchive : public ArchiveBackend {
|
class SDMCArchive : public ArchiveBackend {
|
||||||
public:
|
public:
|
||||||
explicit SDMCArchive(const std::string& mount_point_) : mount_point(mount_point_) {}
|
explicit SDMCArchive(const std::string& mount_point_,
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator_)
|
||||||
|
: mount_point(mount_point_) {
|
||||||
|
delay_generator = std::move(delay_generator_);
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return "SDMCArchive: " + mount_point;
|
return "SDMCArchive: " + mount_point;
|
||||||
|
@ -15,6 +15,28 @@
|
|||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
class SDMCWriteOnlyDelayGenerator : public DelayGenerator {
|
||||||
|
public:
|
||||||
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 slope(183);
|
||||||
|
static constexpr u64 offset(524879);
|
||||||
|
static constexpr u64 minimum(631826);
|
||||||
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(269082);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Path& path,
|
ResultVal<std::unique_ptr<FileBackend>> SDMCWriteOnlyArchive::OpenFile(const Path& path,
|
||||||
const Mode& mode) const {
|
const Mode& mode) const {
|
||||||
if (mode.read_flag) {
|
if (mode.read_flag) {
|
||||||
@ -51,7 +73,10 @@ bool ArchiveFactory_SDMCWriteOnly::Initialize() {
|
|||||||
|
|
||||||
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path,
|
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path,
|
||||||
u64 program_id) {
|
u64 program_id) {
|
||||||
auto archive = std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory);
|
std::unique_ptr<DelayGenerator> delay_generator =
|
||||||
|
std::make_unique<SDMCWriteOnlyDelayGenerator>();
|
||||||
|
auto archive =
|
||||||
|
std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory, std::move(delay_generator));
|
||||||
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@ namespace FileSys {
|
|||||||
*/
|
*/
|
||||||
class SDMCWriteOnlyArchive : public SDMCArchive {
|
class SDMCWriteOnlyArchive : public SDMCArchive {
|
||||||
public:
|
public:
|
||||||
explicit SDMCWriteOnlyArchive(const std::string& mount_point) : SDMCArchive(mount_point) {}
|
explicit SDMCWriteOnlyArchive(const std::string& mount_point,
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator_)
|
||||||
|
: SDMCArchive(mount_point, std::move(delay_generator_)) {}
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return "SDMCWriteOnlyArchive: " + mount_point;
|
return "SDMCWriteOnlyArchive: " + mount_point;
|
||||||
|
@ -19,4 +19,11 @@ u64 DefaultDelayGenerator::GetReadDelayNs(std::size_t length) {
|
|||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 DefaultDelayGenerator::GetOpenDelayNs() {
|
||||||
|
// This is the delay measured for a romfs open.
|
||||||
|
// For now we will take that as a default
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(9438006);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
@ -13,6 +13,7 @@ class DelayGenerator {
|
|||||||
public:
|
public:
|
||||||
virtual ~DelayGenerator();
|
virtual ~DelayGenerator();
|
||||||
virtual u64 GetReadDelayNs(std::size_t length) = 0;
|
virtual u64 GetReadDelayNs(std::size_t length) = 0;
|
||||||
|
virtual u64 GetOpenDelayNs() = 0;
|
||||||
|
|
||||||
// TODO (B3N30): Add getter for all other file/directory io operations
|
// TODO (B3N30): Add getter for all other file/directory io operations
|
||||||
};
|
};
|
||||||
@ -20,6 +21,7 @@ public:
|
|||||||
class DefaultDelayGenerator : public DelayGenerator {
|
class DefaultDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(std::size_t length) override;
|
u64 GetReadDelayNs(std::size_t length) override;
|
||||||
|
u64 GetOpenDelayNs() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
@ -55,6 +55,15 @@ public:
|
|||||||
return delay_generator->GetReadDelayNs(length);
|
return delay_generator->GetReadDelayNs(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() {
|
||||||
|
if (delay_generator != nullptr) {
|
||||||
|
return delay_generator->GetOpenDelayNs();
|
||||||
|
}
|
||||||
|
LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default");
|
||||||
|
delay_generator = std::make_unique<DefaultDelayGenerator>();
|
||||||
|
return delay_generator->GetOpenDelayNs();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the file in bytes
|
* Get the size of the file in bytes
|
||||||
* @return Size of the file in bytes
|
* @return Size of the file in bytes
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
IVFCArchive::IVFCArchive(std::shared_ptr<RomFSReader> file) : romfs_file(std::move(file)) {}
|
IVFCArchive::IVFCArchive(std::shared_ptr<RomFSReader> file,
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator_)
|
||||||
|
: romfs_file(std::move(file)) {
|
||||||
|
delay_generator = std::move(delay_generator_);
|
||||||
|
}
|
||||||
|
|
||||||
std::string IVFCArchive::GetName() const {
|
std::string IVFCArchive::GetName() const {
|
||||||
return "IVFC";
|
return "IVFC";
|
||||||
|
@ -31,6 +31,13 @@ class IVFCDelayGenerator : public DelayGenerator {
|
|||||||
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured for a romfs open.
|
||||||
|
// For now we will take that as a default
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(9438006);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RomFSDelayGenerator : public DelayGenerator {
|
class RomFSDelayGenerator : public DelayGenerator {
|
||||||
@ -45,6 +52,14 @@ public:
|
|||||||
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/eb1d70619c65c7e6f02141d71e79a36e
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(9438006);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExeFSDelayGenerator : public DelayGenerator {
|
class ExeFSDelayGenerator : public DelayGenerator {
|
||||||
@ -59,6 +74,14 @@ public:
|
|||||||
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/eb1d70619c65c7e6f02141d71e79a36e
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(9438006);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +91,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
class IVFCArchive : public ArchiveBackend {
|
class IVFCArchive : public ArchiveBackend {
|
||||||
public:
|
public:
|
||||||
IVFCArchive(std::shared_ptr<RomFSReader> file);
|
IVFCArchive(std::shared_ptr<RomFSReader> file,
|
||||||
|
std::unique_ptr<DelayGenerator> delay_generator_);
|
||||||
|
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
|
|
||||||
|
@ -25,6 +25,14 @@ public:
|
|||||||
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
u64 IPCDelayNanoseconds = std::max<u64>(static_cast<u64>(length) * slope + offset, minimum);
|
||||||
return IPCDelayNanoseconds;
|
return IPCDelayNanoseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GetOpenDelayNs() override {
|
||||||
|
// This is the delay measured on O3DS and O2DS with
|
||||||
|
// https://gist.github.com/FearlessTobi/c37e143c314789251f98f2c45cd706d2
|
||||||
|
// from the results the average of each length was taken.
|
||||||
|
static constexpr u64 IPCDelayNanoseconds(269082);
|
||||||
|
return IPCDelayNanoseconds;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path,
|
ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path,
|
||||||
|
@ -77,19 +77,21 @@ ResultCode ArchiveManager::RegisterArchiveType(std::unique_ptr<FileSys::ArchiveF
|
|||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle,
|
std::tuple<ResultVal<std::shared_ptr<File>>, std::chrono::nanoseconds>
|
||||||
const FileSys::Path& path,
|
ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path,
|
||||||
const FileSys::Mode mode) {
|
const FileSys::Mode mode) {
|
||||||
ArchiveBackend* archive = GetArchive(archive_handle);
|
ArchiveBackend* archive = GetArchive(archive_handle);
|
||||||
if (archive == nullptr)
|
if (archive == nullptr)
|
||||||
return FileSys::ERR_INVALID_ARCHIVE_HANDLE;
|
return std::make_tuple(FileSys::ERR_INVALID_ARCHIVE_HANDLE,
|
||||||
|
static_cast<std::chrono::nanoseconds>(0));
|
||||||
|
|
||||||
|
std::chrono::nanoseconds open_timeout_ns{archive->GetOpenDelayNs()};
|
||||||
auto backend = archive->OpenFile(path, mode);
|
auto backend = archive->OpenFile(path, mode);
|
||||||
if (backend.Failed())
|
if (backend.Failed())
|
||||||
return backend.Code();
|
return std::make_tuple(backend.Code(), open_timeout_ns);
|
||||||
|
|
||||||
auto file = std::shared_ptr<File>(new File(system, std::move(backend).Unwrap(), path));
|
auto file = std::shared_ptr<File>(new File(system, std::move(backend).Unwrap(), path));
|
||||||
return MakeResult<std::shared_ptr<File>>(std::move(file));
|
return std::make_tuple(MakeResult<std::shared_ptr<File>>(std::move(file)), open_timeout_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle,
|
ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle,
|
||||||
|
@ -77,11 +77,10 @@ public:
|
|||||||
* @param archive_handle Handle to an open Archive object
|
* @param archive_handle Handle to an open Archive object
|
||||||
* @param path Path to the File inside of the Archive
|
* @param path Path to the File inside of the Archive
|
||||||
* @param mode Mode under which to open the File
|
* @param mode Mode under which to open the File
|
||||||
* @return The opened File object
|
* @return Tuple of the opened File object and the open delay
|
||||||
*/
|
*/
|
||||||
ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handle,
|
std::tuple<ResultVal<std::shared_ptr<File>>, std::chrono::nanoseconds> OpenFileFromArchive(
|
||||||
const FileSys::Path& path,
|
ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode);
|
||||||
const FileSys::Mode mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a File from an Archive
|
* Delete a File from an Archive
|
||||||
|
@ -71,12 +71,12 @@ void File::Read(Kernel::HLERequestContext& ctx) {
|
|||||||
rb.PushMappedBuffer(buffer);
|
rb.PushMappedBuffer(buffer);
|
||||||
|
|
||||||
std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)};
|
std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)};
|
||||||
ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(), "file::read",
|
ctx.SleepClientThread(
|
||||||
read_timeout_ns,
|
system.Kernel().GetThreadManager().GetCurrentThread(), "file::read", read_timeout_ns,
|
||||||
[](Kernel::SharedPtr<Kernel::Thread> thread,
|
[](Kernel::SharedPtr<Kernel::Thread> /*thread*/, Kernel::HLERequestContext& /*ctx*/,
|
||||||
Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) {
|
Kernel::ThreadWakeupReason /*reason*/) {
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void File::Write(Kernel::HLERequestContext& ctx) {
|
void File::Write(Kernel::HLERequestContext& ctx) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
#include "core/hle/kernel/server_session.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
@ -59,7 +60,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) {
|
|||||||
|
|
||||||
LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes);
|
LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes);
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<File>> file_res =
|
const auto [file_res, open_timeout_ns] =
|
||||||
archives.OpenFileFromArchive(archive_handle, file_path, mode);
|
archives.OpenFileFromArchive(archive_handle, file_path, mode);
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||||
rb.Push(file_res.Code());
|
rb.Push(file_res.Code());
|
||||||
@ -70,6 +71,13 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) {
|
|||||||
rb.PushMoveObjects<Kernel::Object>(nullptr);
|
rb.PushMoveObjects<Kernel::Object>(nullptr);
|
||||||
LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr());
|
LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.SleepClientThread(
|
||||||
|
system.Kernel().GetThreadManager().GetCurrentThread(), "fs_user::open", open_timeout_ns,
|
||||||
|
[](Kernel::SharedPtr<Kernel::Thread> /*thread*/, Kernel::HLERequestContext& /*ctx*/,
|
||||||
|
Kernel::ThreadWakeupReason /*reason*/) {
|
||||||
|
// Nothing to do here
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
|
void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
|
||||||
@ -110,7 +118,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
|
|||||||
}
|
}
|
||||||
SCOPE_EXIT({ archives.CloseArchive(*archive_handle); });
|
SCOPE_EXIT({ archives.CloseArchive(*archive_handle); });
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<File>> file_res =
|
const auto [file_res, open_timeout_ns] =
|
||||||
archives.OpenFileFromArchive(*archive_handle, file_path, mode);
|
archives.OpenFileFromArchive(*archive_handle, file_path, mode);
|
||||||
rb.Push(file_res.Code());
|
rb.Push(file_res.Code());
|
||||||
if (file_res.Succeeded()) {
|
if (file_res.Succeeded()) {
|
||||||
@ -121,6 +129,14 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
|
|||||||
LOG_ERROR(Service_FS, "failed to get a handle for file {} mode={} attributes={}",
|
LOG_ERROR(Service_FS, "failed to get a handle for file {} mode={} attributes={}",
|
||||||
file_path.DebugStr(), mode.hex, attributes);
|
file_path.DebugStr(), mode.hex, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(),
|
||||||
|
"fs_user::open_directly", open_timeout_ns,
|
||||||
|
[](Kernel::SharedPtr<Kernel::Thread> /*thread*/,
|
||||||
|
Kernel::HLERequestContext& /*ctx*/,
|
||||||
|
Kernel::ThreadWakeupReason /*reason*/) {
|
||||||
|
// Nothing to do here
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) {
|
void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) {
|
||||||
|
Loading…
Reference in New Issue
Block a user