mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-30 16:51:14 +00:00
136 lines
6.1 KiB
C++
136 lines
6.1 KiB
C++
/*
|
|
* Copyright (c) Atmosphère-NX
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include <stratosphere.hpp>
|
|
#include <stratosphere/fs/impl/fs_service_name.hpp>
|
|
#include "fssrv_deferred_process_manager.hpp"
|
|
|
|
namespace ams::fssrv {
|
|
|
|
namespace {
|
|
|
|
struct FileSystemProxyServerOptions {
|
|
static constexpr size_t PointerBufferSize = 0x800;
|
|
static constexpr size_t MaxDomains = 0x40;
|
|
static constexpr size_t MaxDomainObjects = 0x4000;
|
|
static constexpr bool CanDeferInvokeRequest = true;
|
|
static constexpr bool CanManageMitmServers = false;
|
|
};
|
|
|
|
enum PortIndex {
|
|
PortIndex_FileSystemProxy,
|
|
PortIndex_ProgramRegistry,
|
|
PortIndex_FileSystemProxyForLoader,
|
|
PortIndex_Count,
|
|
};
|
|
|
|
constexpr size_t FileSystemProxyMaxSessions = 59;
|
|
constexpr size_t ProgramRegistryMaxSessions = 1;
|
|
constexpr size_t FileSystemProxyForLoaderMaxSessions = 1;
|
|
|
|
constexpr size_t NumSessions = FileSystemProxyMaxSessions + ProgramRegistryMaxSessions + FileSystemProxyForLoaderMaxSessions;
|
|
|
|
constinit os::SemaphoreType g_semaphore_for_file_system_proxy_for_loader = {};
|
|
constinit os::SemaphoreType g_semaphore_for_program_registry = {};
|
|
|
|
class FileSystemProxyServerManager final : public ams::sf::hipc::ServerManager<PortIndex_Count, FileSystemProxyServerOptions, NumSessions> {
|
|
private:
|
|
virtual ams::Result OnNeedsToAccept(int port_index, Server *server) override {
|
|
switch (port_index) {
|
|
case PortIndex_FileSystemProxy:
|
|
{
|
|
return this->AcceptImpl(server, impl::GetFileSystemProxyServiceObject());
|
|
}
|
|
break;
|
|
case PortIndex_ProgramRegistry:
|
|
{
|
|
if (os::TryAcquireSemaphore(std::addressof(g_semaphore_for_program_registry))) {
|
|
auto sema_guard = SCOPE_GUARD { os::ReleaseSemaphore(std::addressof(g_semaphore_for_program_registry)); };
|
|
|
|
R_TRY(this->AcceptImpl(server, impl::GetProgramRegistryServiceObject()));
|
|
|
|
sema_guard.Cancel();
|
|
} else {
|
|
R_TRY(this->AcceptImpl(server, impl::GetInvalidProgramRegistryServiceObject()));
|
|
}
|
|
|
|
return ResultSuccess();
|
|
}
|
|
break;
|
|
case PortIndex_FileSystemProxyForLoader:
|
|
{
|
|
if (os::TryAcquireSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader))) {
|
|
auto sema_guard = SCOPE_GUARD { os::ReleaseSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader)); };
|
|
|
|
R_TRY(this->AcceptImpl(server, impl::GetFileSystemProxyForLoaderServiceObject()));
|
|
|
|
sema_guard.Cancel();
|
|
} else {
|
|
R_TRY(this->AcceptImpl(server, impl::GetInvalidFileSystemProxyForLoaderServiceObject()));
|
|
}
|
|
|
|
return ResultSuccess();
|
|
}
|
|
break;
|
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
|
}
|
|
}
|
|
};
|
|
|
|
constinit util::TypedStorage<FileSystemProxyServerManager> g_server_manager_storage = {};
|
|
constinit FileSystemProxyServerManager *g_server_manager = nullptr;
|
|
|
|
constinit os::BarrierType g_server_loop_barrier = {};
|
|
constinit os::EventType g_resume_wait_event = {};
|
|
|
|
constinit bool g_is_suspended = false;
|
|
|
|
void TemporaryNotifyProcessDeferred(u64) { /* TODO */ }
|
|
|
|
constinit DeferredProcessManager<FileSystemProxyServerManager, TemporaryNotifyProcessDeferred> g_deferred_process_manager;
|
|
|
|
}
|
|
|
|
void InitializeForFileSystemProxy(const FileSystemProxyConfiguration &config) {
|
|
/* TODO FS-REIMPL */
|
|
AMS_UNUSED(config);
|
|
}
|
|
|
|
void InitializeFileSystemProxyServer(int threads) {
|
|
/* Initialize synchronization primitives. */
|
|
os::InitializeBarrier(std::addressof(g_server_loop_barrier), threads + 1);
|
|
os::InitializeEvent(std::addressof(g_resume_wait_event), false, os::EventClearMode_ManualClear);
|
|
g_is_suspended = false;
|
|
os::InitializeSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader), 1, 1);
|
|
os::InitializeSemaphore(std::addressof(g_semaphore_for_program_registry), 1, 1);
|
|
|
|
/* Initialize deferred process manager. */
|
|
g_deferred_process_manager.Initialize();
|
|
|
|
/* Create the server and register our services. */
|
|
AMS_ASSERT(g_server_manager == nullptr);
|
|
g_server_manager = util::ConstructAt(g_server_manager_storage);
|
|
|
|
/* TODO: Manager handler. */
|
|
|
|
R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_FileSystemProxy, fs::impl::FileSystemProxyServiceName, FileSystemProxyMaxSessions));
|
|
R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_ProgramRegistry, fs::impl::ProgramRegistryServiceName, ProgramRegistryMaxSessions));
|
|
R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_FileSystemProxyForLoader, fs::impl::FileSystemProxyForLoaderServiceName, FileSystemProxyForLoaderMaxSessions));
|
|
|
|
/* Enable processing on server. */
|
|
g_server_manager->ResumeProcessing();
|
|
}
|
|
|
|
}
|