Integrate new result macros. (#1780)
* result: try out some experimental shenanigans * result: sketch out some more shenanigans * result: see what it looks like to convert kernel to use result conds instead of guards * make rest of kernel use experimental new macro-ing
This commit is contained in:
@@ -97,7 +97,7 @@ namespace ams::fssrv::impl {
|
||||
|
||||
/* Clear the map, and ensure we remain clear if we fail after this point. */
|
||||
this->ClearImpl();
|
||||
auto clear_guard = SCOPE_GUARD { this->ClearImpl(); };
|
||||
ON_RESULT_FAILURE { this->ClearImpl(); };
|
||||
|
||||
/* Add each info to the list. */
|
||||
for (int i = 0; i < count; ++i) {
|
||||
@@ -115,8 +115,7 @@ namespace ams::fssrv::impl {
|
||||
}
|
||||
|
||||
/* We successfully imported the map. */
|
||||
clear_guard.Cancel();
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
private:
|
||||
void ClearImpl() {
|
||||
|
||||
@@ -143,12 +143,11 @@ namespace ams::fssystem::save {
|
||||
Result StoreOrDestroyBuffer(const MemoryRange &range, CacheEntry *entry) {
|
||||
AMS_ASSERT(entry != nullptr);
|
||||
|
||||
auto buf_guard = SCOPE_GUARD { this->DestroyBuffer(entry, range); };
|
||||
ON_RESULT_FAILURE { this->DestroyBuffer(entry, range); };
|
||||
|
||||
R_TRY(this->StoreAssociateBuffer(range, *entry));
|
||||
|
||||
buf_guard.Cancel();
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FlushCacheEntry(CacheIndex index, bool invalidate);
|
||||
|
||||
@@ -325,19 +325,18 @@ namespace ams::kvdb {
|
||||
/* Allocate memory for value. */
|
||||
void *new_value = m_memory_resource->Allocate(value_size);
|
||||
R_UNLESS(new_value != nullptr, kvdb::ResultAllocationFailed());
|
||||
auto value_guard = SCOPE_GUARD { m_memory_resource->Deallocate(new_value, value_size); };
|
||||
|
||||
/* If we fail before adding to the index, deallocate our value. */
|
||||
ON_RESULT_FAILURE { m_memory_resource->Deallocate(new_value, value_size); };
|
||||
|
||||
/* Read key and value. */
|
||||
Key key;
|
||||
R_TRY(reader.ReadEntry(std::addressof(key), sizeof(key), new_value, value_size));
|
||||
R_TRY(m_index.AddUnsafe(key, new_value, value_size));
|
||||
|
||||
/* We succeeded, so cancel the value guard to prevent deallocation. */
|
||||
value_guard.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Save(bool destructive = false) {
|
||||
|
||||
@@ -98,15 +98,14 @@ namespace ams::sf::hipc {
|
||||
/* Allocate session. */
|
||||
ServerSession *session_memory = this->AllocateSession();
|
||||
R_UNLESS(session_memory != nullptr, sf::hipc::ResultOutOfSessionMemory());
|
||||
ON_RESULT_FAILURE { this->DestroySession(session_memory); };
|
||||
|
||||
/* Register session. */
|
||||
auto register_guard = SCOPE_GUARD { this->DestroySession(session_memory); };
|
||||
R_TRY(ctor(session_memory));
|
||||
|
||||
/* Save new session to output. */
|
||||
register_guard.Cancel();
|
||||
*out = session_memory;
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
void DestroySession(ServerSession *session);
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace ams::tipc {
|
||||
};
|
||||
static_assert(std::is_standard_layout<DeferrableBaseImpl>::value);
|
||||
|
||||
#define TIPC_REGISTER_RETRY_ON_RESULT_REQUEST_DEFERRED(KEY) ON_RESULT_INCLUDED(tipc::ResultRequestDeferred) { this->RegisterRetry(KEY); }
|
||||
|
||||
template<size_t _MessageBufferRequiredSize>
|
||||
class DeferrableBaseImplWithBuffer : public DeferrableBaseImpl {
|
||||
private:
|
||||
|
||||
@@ -145,38 +145,44 @@ namespace ams::tipc {
|
||||
/* Get the method id. */
|
||||
const auto method_id = svc::ipc::MessageBuffer::MessageHeader(message_buffer).GetTag();
|
||||
|
||||
/* Ensure that we clean up any handles that get sent our way. */
|
||||
auto handle_guard = SCOPE_GUARD {
|
||||
const svc::ipc::MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const svc::ipc::MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
/* Process for the method id. */
|
||||
{
|
||||
/* Ensure that if we fail, we clean up any handles that get sent our way. */
|
||||
ON_RESULT_FAILURE {
|
||||
const svc::ipc::MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const svc::ipc::MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
|
||||
/* Determine the offset to the start of handles. */
|
||||
auto offset = message_buffer.GetSpecialDataIndex(message_header, special_header);
|
||||
if (special_header.GetHasProcessId()) {
|
||||
offset += sizeof(u64) / sizeof(u32);
|
||||
}
|
||||
/* Determine the offset to the start of handles. */
|
||||
auto offset = message_buffer.GetSpecialDataIndex(message_header, special_header);
|
||||
if (special_header.GetHasProcessId()) {
|
||||
offset += sizeof(u64) / sizeof(u32);
|
||||
}
|
||||
|
||||
/* Close all copy handles. */
|
||||
for (auto i = 0; i < special_header.GetCopyHandleCount(); ++i) {
|
||||
svc::CloseHandle(message_buffer.GetHandle(offset));
|
||||
offset += sizeof(ams::svc::Handle) / sizeof(u32);
|
||||
}
|
||||
};
|
||||
/* Close all copy handles. */
|
||||
for (auto i = 0; i < special_header.GetCopyHandleCount(); ++i) {
|
||||
svc::CloseHandle(message_buffer.GetHandle(offset));
|
||||
offset += sizeof(ams::svc::Handle) / sizeof(u32);
|
||||
}
|
||||
};
|
||||
|
||||
/* Check that the method id is valid. */
|
||||
R_UNLESS(method_id != MethodId_Invalid, tipc::ResultInvalidMethod());
|
||||
/* Check that the method id is valid. */
|
||||
R_UNLESS(method_id != MethodId_Invalid, tipc::ResultInvalidMethod());
|
||||
|
||||
/* If we're closing the object, do so. */
|
||||
if (method_id == MethodId_CloseSession) {
|
||||
/* Validate the command format. */
|
||||
{
|
||||
/* Process the request. */
|
||||
if (method_id != MethodId_CloseSession) {
|
||||
/* Process the generic method for the object. */
|
||||
R_TRY(object.GetObject()->ProcessRequest());
|
||||
} else {
|
||||
/* Validate that the close request is of valid format. */
|
||||
using CloseSessionCommandMeta = impl::CommandMetaInfo<MethodId_CloseSession, std::tuple<>>;
|
||||
using CloseSessionProcessor = impl::CommandProcessor<CloseSessionCommandMeta>;
|
||||
|
||||
/* Validate that the command is valid. */
|
||||
R_TRY(CloseSessionProcessor::ValidateCommandFormat(message_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
/* If we were asked to close the object, do so. */
|
||||
if (method_id == MethodId_CloseSession) {
|
||||
/* Get the object handle. */
|
||||
const auto handle = object.GetHandle();
|
||||
|
||||
@@ -187,17 +193,12 @@ namespace ams::tipc {
|
||||
/* NOTE: Nintendo does not check that this succeeds. */
|
||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||
|
||||
/* Return result to signify we closed the object (and don't close input handles). */
|
||||
handle_guard.Cancel();
|
||||
return tipc::ResultSessionClosed();
|
||||
/* Return an error to signify we closed the object. */
|
||||
R_THROW(tipc::ResultSessionClosed());
|
||||
}
|
||||
|
||||
/* Process the generic method for the object. */
|
||||
R_TRY(object.GetObject()->ProcessRequest());
|
||||
|
||||
/* We successfully processed, so we don't need to clean up handles. */
|
||||
handle_guard.Cancel();
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -488,13 +484,10 @@ namespace ams::ncm {
|
||||
|
||||
/* Mark storage id to be committed later. */
|
||||
commit_list.Push(reader.GetStorageId());
|
||||
|
||||
/* We successfully commited this meta, so we want to check for errors when updating. */
|
||||
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 +506,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 +634,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 +696,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<bool> is_temporary) {
|
||||
@@ -722,7 +712,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);
|
||||
@@ -731,9 +721,8 @@ namespace ams::ncm {
|
||||
R_TRY(this->WritePlaceHolder(meta_info.key, out_install_content_info));
|
||||
|
||||
/* 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<ContentMetaKey> expected_key, util::optional<u32> source_version) {
|
||||
@@ -749,10 +738,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 +772,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 +806,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 +843,7 @@ namespace ams::ncm {
|
||||
}
|
||||
}
|
||||
|
||||
guard.Cancel();
|
||||
return ResultSuccess();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result InstallTaskBase::GetSystemUpdateTaskApplyInfo(SystemUpdateTaskApplyInfo *out) {
|
||||
|
||||
Reference in New Issue
Block a user