diff --git a/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp b/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp index 151b0fefd..96b1b4567 100644 --- a/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_install_task_base.cpp @@ -202,7 +202,7 @@ namespace ams::ncm { /* Obtain a reader and get the storage id. */ const auto reader = content_meta.GetReader(); const auto storage_id = reader.GetStorageId(); - R_SUCCEED_IF(storage_id== StorageId::None); + R_SUCCEED_IF(storage_id == StorageId::None); /* Open the relevant content storage. */ ContentStorage content_storage; @@ -340,10 +340,10 @@ namespace ams::ncm { InstallContentMeta content_meta; R_TRY(m_data->Get(std::addressof(content_meta), i)); - /* Update the data (and check result) when we are done. */ - const auto DoUpdate = [&]() ALWAYS_INLINE_LAMBDA { return m_data->Update(content_meta, i); }; + /* Write all prepared content infos. */ { - auto update_guard = SCOPE_GUARD { DoUpdate(); }; + /* If we fail while writing, update (but don't check the result). */ + ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; /* Create a writer. */ const auto writer = content_meta.GetWriter(); @@ -358,11 +358,10 @@ namespace ams::ncm { content_info->install_state = InstallState::Installed; } } - - /* Cancel so we can check the result of updating. */ - update_guard.Cancel(); } - R_TRY(DoUpdate()); + + /* Update our data. */ + R_TRY(m_data->Update(content_meta, i)); } /* Execution has finished, signal this and update the state. */ @@ -370,7 +369,7 @@ namespace ams::ncm { this->SetProgressState(InstallProgressState::Downloaded); - return ResultSuccess(); + R_SUCCEED(); } Result InstallTaskBase::PrepareAndExecute() { @@ -446,13 +445,10 @@ namespace ams::ncm { continue; } - /* Helper for performing an update. */ - const auto DoUpdate = [&]() ALWAYS_INLINE_LAMBDA { return m_data->Update(content_meta, i); }; - /* Commit the current meta. */ { /* Ensure that if something goes wrong during commit, we still try to update. */ - auto update_guard = SCOPE_GUARD { DoUpdate(); }; + ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; /* Open a writer. */ const auto writer = content_meta.GetWriter(); @@ -493,8 +489,8 @@ namespace ams::ncm { update_guard.Cancel(); } - /* Try to update, checking for failure. */ - R_TRY(DoUpdate()); + /* Try to update our data. */ + R_TRY(m_data->Update(content_meta, i)); } /* Commit all applicable content meta databases. */ @@ -513,10 +509,9 @@ namespace ams::ncm { } Result InstallTaskBase::Commit(const StorageContentMetaKey *keys, s32 num_keys) { - auto fatal_guard = SCOPE_GUARD { SetProgressState(InstallProgressState::Fatal); }; - R_TRY(this->SetLastResultOnFailure(this->CommitImpl(keys, num_keys))); - fatal_guard.Cancel(); - return ResultSuccess(); + ON_RESULT_FAILURE { this->SetProgressState(InstallProgressState::Fatal); }; + + R_RETURN(this->SetLastResultOnFailure(this->CommitImpl(keys, num_keys))); } Result InstallTaskBase::IncludesExFatDriver(bool *out) { @@ -642,9 +637,8 @@ namespace ams::ncm { R_TRY(m_data->Get(std::addressof(content_meta), i)); /* Update the data (and check result) when we are done. */ - const auto DoUpdate = [&]() ALWAYS_INLINE_LAMBDA { return m_data->Update(content_meta, i); }; { - auto update_guard = SCOPE_GUARD { DoUpdate(); }; + ON_RESULT_FAILURE { m_data->Update(content_meta, i); }; /* Automatically choose a suitable storage id. */ auto reader = content_meta.GetReader(); @@ -705,15 +699,14 @@ namespace ams::ncm { /* Add the size of this content info to the total size. */ total_size += content_info->GetSize(); } - - /* Cancel so that we can check the result of updating. */ - update_guard.Cancel(); } - R_TRY(DoUpdate()); + + /* Try to update our data. */ + R_TRY(m_data->Update(content_meta, i)); } this->SetTotalSize(total_size); - return ResultSuccess(); + R_SUCCEED(); } Result InstallTaskBase::WriteContentMetaToPlaceHolder(InstallContentInfo *out_install_content_info, ContentStorage *storage, const InstallContentMetaInfo &meta_info, util::optional is_temporary) { @@ -722,7 +715,7 @@ namespace ams::ncm { /* Create the placeholder. */ R_TRY(storage->CreatePlaceHolder(placeholder_id, meta_info.content_id, meta_info.content_size)); - auto placeholder_guard = SCOPE_GUARD { storage->DeletePlaceHolder(placeholder_id); }; + ON_RESULT_FAILURE { storage->DeletePlaceHolder(placeholder_id); } /* Output install content info. */ *out_install_content_info = this->MakeInstallContentInfoFrom(meta_info, placeholder_id, is_temporary); @@ -733,7 +726,7 @@ namespace ams::ncm { /* Don't delete the placeholder. Set state to installed. */ placeholder_guard.Cancel(); out_install_content_info->install_state = InstallState::Installed; - return ResultSuccess(); + R_SUCCEED(); } Result InstallTaskBase::PrepareContentMeta(const InstallContentMetaInfo &meta_info, util::optional expected_key, util::optional source_version) { @@ -749,10 +742,11 @@ namespace ams::ncm { Path path; content_storage.GetPlaceHolderPath(std::addressof(path), content_info.GetPlaceHolderId()); - const bool is_temporary = content_info.is_temporary; - auto temporary_guard = SCOPE_GUARD { content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId()); }; + /* If we fail, delete the placeholder. */ + ON_RESULT_FAILURE { content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId()); }; /* Create a new temporary InstallContentInfo if relevant. */ + const bool is_temporary = content_info.is_temporary; if (is_temporary) { content_info = { .digest = content_info.digest, @@ -782,11 +776,12 @@ namespace ams::ncm { /* Push the data. */ R_TRY(m_data->Push(meta.Get(), meta.GetSize())); - /* Don't delete the placeholder if not temporary. */ - if (!is_temporary) { - temporary_guard.Cancel(); + /* If the placeholder is temporary, delete it. */ + if (is_temporary) { + content_storage.DeletePlaceHolder(content_info.GetPlaceHolderId()); } - return ResultSuccess(); + + R_SUCCEED(); } Result InstallTaskBase::PrepareContentMeta(ContentId content_id, s64 size, ContentMetaType meta_type, AutoBuffer *buffer) { @@ -815,7 +810,7 @@ namespace ams::ncm { Result InstallTaskBase::PrepareSystemUpdateDependency() { /* Cleanup on failure. */ - auto guard = SCOPE_GUARD { this->Cleanup(); }; + ON_RESULT_FAILURE { this->Cleanup(); }; /* Count the number of content meta entries. */ s32 count; @@ -852,8 +847,7 @@ namespace ams::ncm { } } - guard.Cancel(); - return ResultSuccess(); + R_SUCCEED(); } Result InstallTaskBase::GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out) { diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 69fc3c18b..71e74e0f9 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -681,13 +681,10 @@ namespace ams::ldr { /* Load NSOs into process memory. */ { /* Ensure we close the process handle, if we fail. */ - auto process_guard = SCOPE_GUARD { os::CloseNativeHandle(info.process_handle); }; + ON_RESULT_FAILURE { os::CloseNativeHandle(info.process_handle); } /* Load all NSOs. */ R_TRY(LoadAutoLoadModules(std::addressof(info), g_nso_headers, g_has_nso, argument)); - - /* We don't need to close the process handle, since we succeeded. */ - process_guard.Cancel(); } /* Register NSOs with the RoManager. */ @@ -722,7 +719,7 @@ namespace ams::ldr { /* Move the process handle to output. */ *out = info.process_handle; - return ResultSuccess(); + R_SUCCEED(); } Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path) { diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 329ee7fcc..7b1e39f88 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -234,19 +234,21 @@ namespace ams::pm::impl { /* Fix the program location to use the right program id. */ const ncm::ProgramLocation location = ncm::ProgramLocation::Make(program_info.program_id, static_cast(args.location.storage_id)); - /* Pin the program with loader. */ - ldr::PinId pin_id; - R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), location, override_status)); - - /* Ensure resources are available. */ - resource::WaitResourceAvailable(std::addressof(program_info)); - - /* Actually create the process. */ + /* Pin and create the process. */ os::NativeHandle process_handle; + ldr::PinId pin_id; { - auto pin_guard = SCOPE_GUARD { ldr::pm::UnpinProgram(pin_id); }; + /* Pin the program with loader. */ + R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), location, override_status)); + + /* If we fail after now, unpin. */ + ON_RESULT_FAILURE { ldr::pm::UnpinProgram(pin_id); }; + + /* Ensure resources are available. */ + resource::WaitResourceAvailable(std::addressof(program_info)); + + /* Actually create the process. */ R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(args.flags), resource::GetResourceLimitHandle(std::addressof(program_info)))); - pin_guard.Cancel(); } /* Get the process id. */ @@ -264,7 +266,7 @@ namespace ams::pm::impl { } /* Prevent resource leakage if register fails. */ - auto cleanup_guard = SCOPE_GUARD { + ON_RESULT_FAILURE { ProcessListAccessor list(g_process_list); process_info->Cleanup(); CleanupProcessInfo(list, process_info); @@ -304,11 +306,8 @@ namespace ams::pm::impl { R_TRY(StartProcess(process_info, std::addressof(program_info))); } - /* We succeeded, so we can cancel our cleanup. */ - cleanup_guard.Cancel(); - *args.out_process_id = process_id; - return ResultSuccess(); + R_SUCCEED(); } void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info) { diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp index 08ec61c0d..609510166 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -99,14 +99,11 @@ namespace ams::pm::resource { const u64 old_memory_limit = g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax]; g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax] = new_memory_limit; - { - /* If we fail, restore the old memory limit. */ - auto limit_guard = SCOPE_GUARD { g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax] = old_memory_limit; }; - R_TRY(svc::SetResourceLimitLimitValue(GetResourceLimitHandle(group), svc::LimitableResource_PhysicalMemoryMax, g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax])); - limit_guard.Cancel(); - } + /* Restore the old memory limit if we fail. */ + ON_RESULT_FAILURE { g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax] = old_memory_limit; }; - return ResultSuccess(); + /* Set the resource limit. */ + R_RETURN(svc::SetResourceLimitLimitValue(GetResourceLimitHandle(group), svc::LimitableResource_PhysicalMemoryMax, g_resource_limits[group][svc::LimitableResource_PhysicalMemoryMax])); } Result SetResourceLimitLimitValues(ResourceLimitGroup group, u64 new_memory_limit) {