Split SessionRequestHandler::HandleSyncRequest into HandleSyncRequest, TranslateRequest and HandleSyncRequestImpl.

HandleSyncRequest now takes care of calling the command buffer translate function before actually invoking the command handler for HLE services.
This commit is contained in:
Subv 2016-12-05 12:05:00 -05:00
parent 29d809b6e1
commit 00f0c77570
6 changed files with 59 additions and 22 deletions

View file

@ -4,6 +4,7 @@
#include "common/assert.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/server_session.h"

View file

@ -4,6 +4,7 @@
#pragma once
#include <memory>
#include <string>
#include <tuple>
#include "common/common_types.h"

View file

@ -93,7 +93,7 @@ File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path&
File::~File() {}
ResultCode File::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
void File::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
u32* cmd_buff = Kernel::GetCommandBuffer();
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
switch (cmd) {
@ -116,7 +116,7 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> serv
ResultVal<size_t> read = backend->Read(offset, data.size(), data.data());
if (read.Failed()) {
cmd_buff[1] = read.Code().raw;
return read.Code();
return;
}
Memory::WriteBlock(address, data.data(), *read);
cmd_buff[2] = static_cast<u32>(*read);
@ -137,7 +137,7 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> serv
ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data());
if (written.Failed()) {
cmd_buff[1] = written.Code().raw;
return written.Code();
return;
}
cmd_buff[2] = static_cast<u32>(*written);
break;
@ -195,10 +195,9 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> serv
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
ResultCode error = UnimplementedFunction(ErrorModule::FS);
cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
return error;
return;
}
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
return RESULT_SUCCESS;
}
Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend,
@ -207,7 +206,7 @@ Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend,
Directory::~Directory() {}
ResultCode Directory::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
void Directory::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
u32* cmd_buff = Kernel::GetCommandBuffer();
DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
switch (cmd) {
@ -237,10 +236,9 @@ ResultCode Directory::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession>
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
ResultCode error = UnimplementedFunction(ErrorModule::FS);
cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
return RESULT_SUCCESS;
return;
}
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
return RESULT_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -50,11 +50,12 @@ public:
return "Path: " + path.DebugStr();
}
ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
FileSys::Path path; ///< Path of the file
u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
protected:
void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
};
class Directory : public SessionRequestHandler {
@ -66,10 +67,11 @@ public:
return "Directory: " + path.DebugStr();
}
ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
FileSys::Path path; ///< Path of the directory
std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface
protected:
void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
};
/**

View file

@ -64,7 +64,27 @@ static std::string MakeFunctionString(const char* name, const char* port_name,
return function_string;
}
ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
ResultCode SessionRequestHandler::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
// Attempt to translate the incoming request's command buffer.
ResultCode result = TranslateRequest(server_session);
if (result.IsError())
return result;
// Actually handle the request
HandleSyncRequestImpl(server_session);
// TODO(Subv): Translate the response command buffer.
return RESULT_SUCCESS;
}
ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
// TODO(Subv): Implement this function once multiple concurrent processes are supported.
return RESULT_SUCCESS;
}
void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) {
// TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command.
u32* cmd_buff = Kernel::GetCommandBuffer();
@ -80,14 +100,12 @@ ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession>
// TODO(bunnei): Hack - ignore error
cmd_buff[1] = 0;
return RESULT_SUCCESS;
return;
}
LOG_TRACE(Service, "%s",
MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
itr->second.func(this);
return RESULT_SUCCESS; // TODO: Implement return from actual function, it should fail if the parameter translation fails
}
void Interface::Register(const FunctionInfo* functions, size_t n) {
@ -179,4 +197,5 @@ void Shutdown() {
g_kernel_named_ports.clear();
LOG_DEBUG(Service, "shutdown OK");
}
}

View file

@ -187,11 +187,27 @@ public:
* Dispatches and handles a sync request from the emulated application.
* @param server_session The ServerSession that was triggered for this sync request,
* it should be used to differentiate which client (As in ClientSession) we're answering to.
* TODO(Subv): Make a HandleSyncRequestParent function that is called from the outside and does { ReturnIfError(Translate()); HandleSyncRequest(); }
* The Translate() function would copy the command buffer from the ServerSession thread's TLS into a temporary buffer, and pass it to HandleSyncRequest.
* TODO(Subv): HandleSyncRequest's return type should be void.
* @returns ResultCode the result code of the translate operation.
*/
virtual ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) = 0;
ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session);
protected:
/**
* Handles a sync request from the emulated application and writes the response to the command buffer.
* TODO(Subv): Use a wrapper structure to hold all the information relevant to
* this request (ServerSession, Originator thread, Translated command buffer, etc).
*/
virtual void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) = 0;
private:
/**
* Performs command buffer translation for this request.
* The command buffer from the ServerSession thread's TLS is copied into a
* buffer and all descriptors in the buffer are processed.
* TODO(Subv): Implement this function, currently we do not support multiple processes running at once,
* but once that is implemented we'll need to properly translate all descriptors in the command buffer.
*/
ResultCode TranslateRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session);
};
/**
@ -231,9 +247,9 @@ public:
return "[UNKNOWN SERVICE PORT]";
}
ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
protected:
void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override;
/**
* Registers the functions in the service
*/