diff options
author | bunnei <bunneidev@gmail.com> | 2021-04-04 04:11:46 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2021-05-06 01:40:50 +0200 |
commit | da7e9553dea4b1eaefb71aca8642ccce7c7f50fb (patch) | |
tree | 3da10a60005ddcc4237900eb5e7473fe7b006152 /src/core/hle/kernel/handle_table.cpp | |
parent | hle: kernel: svc: Migrate GetThreadPriority, StartThread, and ExitThread. (diff) | |
download | yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar.gz yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar.bz2 yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar.lz yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar.xz yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.tar.zst yuzu-da7e9553dea4b1eaefb71aca8642ccce7c7f50fb.zip |
Diffstat (limited to 'src/core/hle/kernel/handle_table.cpp')
-rw-r--r-- | src/core/hle/kernel/handle_table.cpp | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index f96d34078..8eec8a3b5 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -72,6 +72,33 @@ ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) { return MakeResult<Handle>(handle); } +ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { + ASSERT(obj != nullptr); + + const u16 slot = next_free_slot; + if (slot >= table_size) { + LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); + return ResultHandleTableFull; + } + next_free_slot = generations[slot]; + + const u16 generation = next_generation++; + + // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. + // Horizon OS uses zero to represent an invalid handle, so skip to 1. + if (next_generation >= (1 << 15)) { + next_generation = 1; + } + + generations[slot] = generation; + objects_new[slot] = obj; + obj->Open(); + + *out_handle = generation | (slot << 15); + + return RESULT_SUCCESS; +} + ResultVal<Handle> HandleTable::Duplicate(Handle handle) { std::shared_ptr<Object> object = GetGeneric(handle); if (object == nullptr) { @@ -81,30 +108,36 @@ ResultVal<Handle> HandleTable::Duplicate(Handle handle) { return Create(std::move(object)); } -ResultCode HandleTable::Close(Handle handle) { +bool HandleTable::Remove(Handle handle) { if (!IsValid(handle)) { LOG_ERROR(Kernel, "Handle is not valid! handle={:08X}", handle); - return ResultInvalidHandle; + return {}; } const u16 slot = GetSlot(handle); - if (objects[slot].use_count() == 1) { - objects[slot]->Finalize(); + if (objects[slot]) { + objects[slot]->Close(); + } + + if (objects_new[slot]) { + objects_new[slot]->Close(); } objects[slot] = nullptr; + objects_new[slot] = nullptr; generations[slot] = next_free_slot; next_free_slot = slot; - return RESULT_SUCCESS; + + return true; } bool HandleTable::IsValid(Handle handle) const { const std::size_t slot = GetSlot(handle); const u16 generation = GetGeneration(handle); - - return slot < table_size && objects[slot] != nullptr && generations[slot] == generation; + const bool is_object_valid = (objects[slot] != nullptr) || (objects_new[slot] != nullptr); + return slot < table_size && is_object_valid && generations[slot] == generation; } std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const { @@ -124,6 +157,7 @@ void HandleTable::Clear() { for (u16 i = 0; i < table_size; ++i) { generations[i] = static_cast<u16>(i + 1); objects[i] = nullptr; + objects_new[i] = nullptr; } next_free_slot = 0; } |