diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 6929454cb..dbeb03344 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -262,21 +262,19 @@ void KernelState::OnThreadExit(XThread* thread) { } } -XThread* KernelState::GetThreadByID(uint32_t thread_id) { +object_ref KernelState::GetThreadByID(uint32_t thread_id) { std::lock_guard lock(object_mutex_); XThread* thread = nullptr; auto it = threads_by_id_.find(thread_id); if (it != threads_by_id_.end()) { thread = it->second; - // Caller must release. - thread->Retain(); } - return thread; + return retain_object(thread); } void KernelState::RegisterNotifyListener(XNotifyListener* listener) { std::lock_guard lock(object_mutex_); - notify_listeners_.push_back(listener); + notify_listeners_.push_back(retain_object(listener)); // Games seem to expect a few notifications on startup, only for the first // listener. @@ -300,9 +298,9 @@ void KernelState::RegisterNotifyListener(XNotifyListener* listener) { void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { std::lock_guard lock(object_mutex_); - for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); + for (auto& it = notify_listeners_.begin(); it != notify_listeners_.end(); ++it) { - if (*it == listener) { + if ((*it).get() == listener) { notify_listeners_.erase(it); break; } diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index c6ad778b0..dd4bb9181 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -88,7 +88,7 @@ class KernelState { void UnregisterThread(XThread* thread); void OnThreadExecute(XThread* thread); void OnThreadExit(XThread* thread); - XThread* GetThreadByID(uint32_t thread_id); + object_ref GetThreadByID(uint32_t thread_id); void RegisterNotifyListener(XNotifyListener* listener); void UnregisterNotifyListener(XNotifyListener* listener); @@ -118,7 +118,7 @@ class KernelState { ObjectTable* object_table_; xe::recursive_mutex object_mutex_; std::unordered_map threads_by_id_; - std::vector notify_listeners_; + std::vector> notify_listeners_; bool has_notified_startup_; uint32_t process_type_; diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 4ee9eb13b..f58f17df8 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -36,7 +36,6 @@ const xe_xex2_header_t* XUserModule::xex_header() { X_STATUS XUserModule::LoadFromFile(std::string path) { X_STATUS result = X_STATUS_UNSUCCESSFUL; - XFile* file = NULL; // Resolve the file to open. // TODO(benvanik): make this code shared? @@ -66,12 +65,11 @@ X_STATUS XUserModule::LoadFromFile(std::string path) { std::vector buffer(file_info.file_length); // Open file for reading. + XFile* file_ptr = nullptr; result = kernel_state()->file_system()->Open( - std::move(fs_entry), kernel_state(), fs::Mode::READ, false, &file); + std::move(fs_entry), kernel_state(), fs::Mode::READ, false, &file_ptr); + object_ref file(file_ptr); if (result) { - if (file) { - file->Release(); - } return result; } @@ -80,9 +78,6 @@ X_STATUS XUserModule::LoadFromFile(std::string path) { size_t bytes_read = 0; result = file->Read(buffer.data(), buffer.size(), 0, &bytes_read); if (result) { - if (file) { - file->Release(); - } return result; } @@ -90,9 +85,6 @@ X_STATUS XUserModule::LoadFromFile(std::string path) { result = LoadFromMemory(buffer.data(), bytes_read); } - if (file) { - file->Release(); - } return result; } @@ -167,8 +159,9 @@ X_STATUS XUserModule::Launch(uint32_t flags) { Dump(); // Create a thread to run in. - XThread* thread = new XThread(kernel_state(), header->exe_stack_size, 0, - header->exe_entry_point, NULL, 0); + auto thread = + object_ref(new XThread(kernel_state(), header->exe_stack_size, 0, + header->exe_entry_point, 0, 0)); X_STATUS result = thread->Create(); if (XFAILED(result)) { @@ -177,9 +170,7 @@ X_STATUS XUserModule::Launch(uint32_t flags) { } // Wait until thread completes. - thread->Wait(0, 0, 0, NULL); - - thread->Release(); + thread->Wait(0, 0, 0, nullptr); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/xam_notify.cc b/src/xenia/kernel/xam_notify.cc index 6cf67085e..7b2bc2430 100644 --- a/src/xenia/kernel/xam_notify.cc +++ b/src/xenia/kernel/xam_notify.cc @@ -26,12 +26,11 @@ SHIM_CALL XamNotifyCreateListener_shim(PPCContext* ppc_state, // r4=1 may indicate user process? - XNotifyListener* listener = new XNotifyListener(state); + auto listener = object_ref(new XNotifyListener(state)); listener->Initialize(mask); // Handle ref is incremented, so return that. uint32_t handle = listener->handle(); - listener->Release(); SHIM_SET_RETURN_64(handle); } diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index fc050507e..e021e8efe 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -249,11 +249,10 @@ SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) { assert_true(thread_info->type == 0x1000); const char* name = (const char*)SHIM_MEM_ADDR(thread_info->name_ptr); - XThread* thread = NULL; + object_ref thread; if (thread_info->thread_id == -1) { // Current thread. - thread = XThread::GetCurrentThread(); - thread->Retain(); + thread = retain_object(XThread::GetCurrentThread()); } else { // Lookup thread by ID. thread = state->GetThreadByID(thread_info->thread_id); @@ -262,7 +261,6 @@ SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) { if (thread) { XELOGD("SetThreadName(%d, %s)", thread->thread_id(), name); thread->set_name(name); - thread->Release(); } // TODO(benvanik): unwinding required here? diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 9fab96aa5..b8201e5f2 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -117,7 +117,7 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state, } } - XFile* file = nullptr; + object_ref file; if (!entry) { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; @@ -131,15 +131,16 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state, } else { mode = fs::Mode::READ; } + XFile* file_ptr = nullptr; result = fs->Open(std::move(entry), state, mode, false, // TODO(benvanik): pick async mode, if needed. - &file); + &file_ptr); + file = object_ref(file_ptr); } if (XSUCCEEDED(result)) { // Handle ref is incremented, so return that. handle = file->handle(); - file->Release(); result = X_STATUS_SUCCESS; info = X_FILE_OPENED; } @@ -299,9 +300,6 @@ SHIM_CALL NtReadFile_shim(PPCContext* ppc_state, KernelState* state) { SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } - if (file) { - file->Release(); - } if (ev) { if (signal_event) { ev->Set(0, false); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 0e31117e8..98da73484 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -112,13 +112,13 @@ SHIM_CALL ExCreateThread_shim(PPCContext* ppc_state, KernelState* state) { // Stack must be aligned to 16kb pages stack_size = std::max((uint32_t)0x4000, ((stack_size + 0xFFF) & 0xFFFFF000)); - XThread* thread = new XThread(state, stack_size, xapi_thread_startup, - start_address, start_context, creation_flags); + auto thread = object_ref( + new XThread(state, stack_size, xapi_thread_startup, start_address, + start_context, creation_flags)); X_STATUS result = thread->Create(); if (XFAILED(result)) { // Failed! - thread->Release(); XELOGE("Thread creation failed: %.8X", result); SHIM_SET_RETURN_32(result); return;