mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-04 07:38:47 +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
					
				
					 16 changed files with 164 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -77,19 +77,21 @@ ResultCode ArchiveManager::RegisterArchiveType(std::unique_ptr<FileSys::ArchiveF
 | 
			
		|||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle,
 | 
			
		||||
                                                                     const FileSys::Path& path,
 | 
			
		||||
                                                                     const FileSys::Mode mode) {
 | 
			
		||||
std::tuple<ResultVal<std::shared_ptr<File>>, std::chrono::nanoseconds>
 | 
			
		||||
ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path,
 | 
			
		||||
                                    const FileSys::Mode mode) {
 | 
			
		||||
    ArchiveBackend* archive = GetArchive(archive_handle);
 | 
			
		||||
    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);
 | 
			
		||||
    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));
 | 
			
		||||
    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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,11 +77,10 @@ public:
 | 
			
		|||
     * @param archive_handle Handle to an open Archive object
 | 
			
		||||
     * @param path Path to the File inside of the Archive
 | 
			
		||||
     * @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,
 | 
			
		||||
                                                         const FileSys::Path& path,
 | 
			
		||||
                                                         const FileSys::Mode mode);
 | 
			
		||||
    std::tuple<ResultVal<std::shared_ptr<File>>, std::chrono::nanoseconds> OpenFileFromArchive(
 | 
			
		||||
        ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete a File from an Archive
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,12 +71,12 @@ void File::Read(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
    rb.PushMappedBuffer(buffer);
 | 
			
		||||
 | 
			
		||||
    std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)};
 | 
			
		||||
    ctx.SleepClientThread(system.Kernel().GetThreadManager().GetCurrentThread(), "file::read",
 | 
			
		||||
                          read_timeout_ns,
 | 
			
		||||
                          [](Kernel::SharedPtr<Kernel::Thread> thread,
 | 
			
		||||
                             Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) {
 | 
			
		||||
                              // Nothing to do here
 | 
			
		||||
                          });
 | 
			
		||||
    ctx.SleepClientThread(
 | 
			
		||||
        system.Kernel().GetThreadManager().GetCurrentThread(), "file::read", read_timeout_ns,
 | 
			
		||||
        [](Kernel::SharedPtr<Kernel::Thread> /*thread*/, Kernel::HLERequestContext& /*ctx*/,
 | 
			
		||||
           Kernel::ThreadWakeupReason /*reason*/) {
 | 
			
		||||
            // Nothing to do here
 | 
			
		||||
        });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void File::Write(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/client_port.h"
 | 
			
		||||
#include "core/hle/kernel/client_session.h"
 | 
			
		||||
#include "core/hle/kernel/event.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/server_session.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);
 | 
			
		||||
 | 
			
		||||
    ResultVal<std::shared_ptr<File>> file_res =
 | 
			
		||||
    const auto [file_res, open_timeout_ns] =
 | 
			
		||||
        archives.OpenFileFromArchive(archive_handle, file_path, mode);
 | 
			
		||||
    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
 | 
			
		||||
    rb.Push(file_res.Code());
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +71,13 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
        rb.PushMoveObjects<Kernel::Object>(nullptr);
 | 
			
		||||
        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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +118,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
    }
 | 
			
		||||
    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);
 | 
			
		||||
    rb.Push(file_res.Code());
 | 
			
		||||
    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={}",
 | 
			
		||||
                  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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue