Просмотр исходного кода

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.
Subv 9 лет назад
Родитель
Сommit
00f0c77570

+ 1 - 0
src/core/hle/kernel/client_port.cpp

@@ -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"

+ 1 - 0
src/core/hle/kernel/server_port.h

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

+ 6 - 8
src/core/hle/service/fs/archive.cpp

@@ -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;
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////

+ 6 - 4
src/core/hle/service/fs/archive.h

@@ -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;
 };
 
 /**

+ 23 - 4
src/core/hle/service/service.cpp

@@ -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");
 }
+
 }

+ 22 - 6
src/core/hle/service/service.h

@@ -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
      */