More object_ref'ing.
This commit is contained in:
parent
5cfb69434c
commit
d746743d20
|
@ -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_);
|
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||||
XThread* thread = nullptr;
|
XThread* thread = nullptr;
|
||||||
auto it = threads_by_id_.find(thread_id);
|
auto it = threads_by_id_.find(thread_id);
|
||||||
if (it != threads_by_id_.end()) {
|
if (it != threads_by_id_.end()) {
|
||||||
thread = it->second;
|
thread = it->second;
|
||||||
// Caller must release.
|
|
||||||
thread->Retain();
|
|
||||||
}
|
}
|
||||||
return thread;
|
return retain_object(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
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
|
// Games seem to expect a few notifications on startup, only for the first
|
||||||
// listener.
|
// listener.
|
||||||
|
@ -300,9 +298,9 @@ void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
||||||
|
|
||||||
void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
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) {
|
++it) {
|
||||||
if (*it == listener) {
|
if ((*it).get() == listener) {
|
||||||
notify_listeners_.erase(it);
|
notify_listeners_.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ class KernelState {
|
||||||
void UnregisterThread(XThread* thread);
|
void UnregisterThread(XThread* thread);
|
||||||
void OnThreadExecute(XThread* thread);
|
void OnThreadExecute(XThread* thread);
|
||||||
void OnThreadExit(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 RegisterNotifyListener(XNotifyListener* listener);
|
||||||
void UnregisterNotifyListener(XNotifyListener* listener);
|
void UnregisterNotifyListener(XNotifyListener* listener);
|
||||||
|
@ -118,7 +118,7 @@ class KernelState {
|
||||||
ObjectTable* object_table_;
|
ObjectTable* object_table_;
|
||||||
xe::recursive_mutex object_mutex_;
|
xe::recursive_mutex object_mutex_;
|
||||||
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
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_;
|
bool has_notified_startup_;
|
||||||
|
|
||||||
uint32_t process_type_;
|
uint32_t process_type_;
|
||||||
|
|
|
@ -36,7 +36,6 @@ const xe_xex2_header_t* XUserModule::xex_header() {
|
||||||
|
|
||||||
X_STATUS XUserModule::LoadFromFile(std::string path) {
|
X_STATUS XUserModule::LoadFromFile(std::string path) {
|
||||||
X_STATUS result = X_STATUS_UNSUCCESSFUL;
|
X_STATUS result = X_STATUS_UNSUCCESSFUL;
|
||||||
XFile* file = NULL;
|
|
||||||
|
|
||||||
// Resolve the file to open.
|
// Resolve the file to open.
|
||||||
// TODO(benvanik): make this code shared?
|
// 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);
|
std::vector<uint8_t> buffer(file_info.file_length);
|
||||||
|
|
||||||
// Open file for reading.
|
// Open file for reading.
|
||||||
|
XFile* file_ptr = nullptr;
|
||||||
result = kernel_state()->file_system()->Open(
|
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 (result) {
|
||||||
if (file) {
|
|
||||||
file->Release();
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +78,6 @@ X_STATUS XUserModule::LoadFromFile(std::string path) {
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
result = file->Read(buffer.data(), buffer.size(), 0, &bytes_read);
|
result = file->Read(buffer.data(), buffer.size(), 0, &bytes_read);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (file) {
|
|
||||||
file->Release();
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,9 +85,6 @@ X_STATUS XUserModule::LoadFromFile(std::string path) {
|
||||||
result = LoadFromMemory(buffer.data(), bytes_read);
|
result = LoadFromMemory(buffer.data(), bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file) {
|
|
||||||
file->Release();
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,8 +159,9 @@ X_STATUS XUserModule::Launch(uint32_t flags) {
|
||||||
Dump();
|
Dump();
|
||||||
|
|
||||||
// Create a thread to run in.
|
// Create a thread to run in.
|
||||||
XThread* thread = new XThread(kernel_state(), header->exe_stack_size, 0,
|
auto thread =
|
||||||
header->exe_entry_point, NULL, 0);
|
object_ref<XThread>(new XThread(kernel_state(), header->exe_stack_size, 0,
|
||||||
|
header->exe_entry_point, 0, 0));
|
||||||
|
|
||||||
X_STATUS result = thread->Create();
|
X_STATUS result = thread->Create();
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
|
@ -177,9 +170,7 @@ X_STATUS XUserModule::Launch(uint32_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until thread completes.
|
// Wait until thread completes.
|
||||||
thread->Wait(0, 0, 0, NULL);
|
thread->Wait(0, 0, 0, nullptr);
|
||||||
|
|
||||||
thread->Release();
|
|
||||||
|
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,11 @@ SHIM_CALL XamNotifyCreateListener_shim(PPCContext* ppc_state,
|
||||||
|
|
||||||
// r4=1 may indicate user process?
|
// r4=1 may indicate user process?
|
||||||
|
|
||||||
XNotifyListener* listener = new XNotifyListener(state);
|
auto listener = object_ref<XNotifyListener>(new XNotifyListener(state));
|
||||||
listener->Initialize(mask);
|
listener->Initialize(mask);
|
||||||
|
|
||||||
// Handle ref is incremented, so return that.
|
// Handle ref is incremented, so return that.
|
||||||
uint32_t handle = listener->handle();
|
uint32_t handle = listener->handle();
|
||||||
listener->Release();
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_64(handle);
|
SHIM_SET_RETURN_64(handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,11 +249,10 @@ SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
assert_true(thread_info->type == 0x1000);
|
assert_true(thread_info->type == 0x1000);
|
||||||
const char* name = (const char*)SHIM_MEM_ADDR(thread_info->name_ptr);
|
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) {
|
if (thread_info->thread_id == -1) {
|
||||||
// Current thread.
|
// Current thread.
|
||||||
thread = XThread::GetCurrentThread();
|
thread = retain_object(XThread::GetCurrentThread());
|
||||||
thread->Retain();
|
|
||||||
} else {
|
} else {
|
||||||
// Lookup thread by ID.
|
// Lookup thread by ID.
|
||||||
thread = state->GetThreadByID(thread_info->thread_id);
|
thread = state->GetThreadByID(thread_info->thread_id);
|
||||||
|
@ -262,7 +261,6 @@ SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
if (thread) {
|
if (thread) {
|
||||||
XELOGD("SetThreadName(%d, %s)", thread->thread_id(), name);
|
XELOGD("SetThreadName(%d, %s)", thread->thread_id(), name);
|
||||||
thread->set_name(name);
|
thread->set_name(name);
|
||||||
thread->Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benvanik): unwinding required here?
|
// TODO(benvanik): unwinding required here?
|
||||||
|
|
|
@ -117,7 +117,7 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XFile* file = nullptr;
|
object_ref<XFile> file;
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
result = X_STATUS_NO_SUCH_FILE;
|
result = X_STATUS_NO_SUCH_FILE;
|
||||||
info = X_FILE_DOES_NOT_EXIST;
|
info = X_FILE_DOES_NOT_EXIST;
|
||||||
|
@ -131,15 +131,16 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
|
||||||
} else {
|
} else {
|
||||||
mode = fs::Mode::READ;
|
mode = fs::Mode::READ;
|
||||||
}
|
}
|
||||||
|
XFile* file_ptr = nullptr;
|
||||||
result = fs->Open(std::move(entry), state, mode,
|
result = fs->Open(std::move(entry), state, mode,
|
||||||
false, // TODO(benvanik): pick async mode, if needed.
|
false, // TODO(benvanik): pick async mode, if needed.
|
||||||
&file);
|
&file_ptr);
|
||||||
|
file = object_ref<XFile>(file_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
// Handle ref is incremented, so return that.
|
// Handle ref is incremented, so return that.
|
||||||
handle = file->handle();
|
handle = file->handle();
|
||||||
file->Release();
|
|
||||||
result = X_STATUS_SUCCESS;
|
result = X_STATUS_SUCCESS;
|
||||||
info = X_FILE_OPENED;
|
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
|
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file) {
|
|
||||||
file->Release();
|
|
||||||
}
|
|
||||||
if (ev) {
|
if (ev) {
|
||||||
if (signal_event) {
|
if (signal_event) {
|
||||||
ev->Set(0, false);
|
ev->Set(0, false);
|
||||||
|
|
|
@ -112,13 +112,13 @@ SHIM_CALL ExCreateThread_shim(PPCContext* ppc_state, KernelState* state) {
|
||||||
// Stack must be aligned to 16kb pages
|
// Stack must be aligned to 16kb pages
|
||||||
stack_size = std::max((uint32_t)0x4000, ((stack_size + 0xFFF) & 0xFFFFF000));
|
stack_size = std::max((uint32_t)0x4000, ((stack_size + 0xFFF) & 0xFFFFF000));
|
||||||
|
|
||||||
XThread* thread = new XThread(state, stack_size, xapi_thread_startup,
|
auto thread = object_ref<XThread>(
|
||||||
start_address, start_context, creation_flags);
|
new XThread(state, stack_size, xapi_thread_startup, start_address,
|
||||||
|
start_context, creation_flags));
|
||||||
|
|
||||||
X_STATUS result = thread->Create();
|
X_STATUS result = thread->Create();
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
// Failed!
|
// Failed!
|
||||||
thread->Release();
|
|
||||||
XELOGE("Thread creation failed: %.8X", result);
|
XELOGE("Thread creation failed: %.8X", result);
|
||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue