More object_ref'ing.

This commit is contained in:
Ben Vanik 2015-05-24 20:50:52 -07:00
parent 5cfb69434c
commit d746743d20
7 changed files with 24 additions and 40 deletions

View File

@ -262,21 +262,19 @@ void KernelState::OnThreadExit(XThread* thread) {
}
}
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
object_ref<XThread> KernelState::GetThreadByID(uint32_t thread_id) {
std::lock_guard<xe::recursive_mutex> 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<xe::recursive_mutex> 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<xe::recursive_mutex> 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;
}

View File

@ -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<XThread> 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<uint32_t, XThread*> threads_by_id_;
std::vector<XNotifyListener*> notify_listeners_;
std::vector<object_ref<XNotifyListener>> notify_listeners_;
bool has_notified_startup_;
uint32_t process_type_;

View File

@ -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<uint8_t> 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<XFile> 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<XThread>(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;
}

View File

@ -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<XNotifyListener>(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);
}

View File

@ -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<XThread> 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?

View File

@ -117,7 +117,7 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
}
}
XFile* file = nullptr;
object_ref<XFile> 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<XFile>(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);

View File

@ -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<XThread>(
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;