Created
December 6, 2014 06:38
-
-
Save archshift/b7381db5b39ed2c3a234 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp | |
index 647f0de..2e6c73b 100644 | |
--- a/src/core/hle/kernel/archive.cpp | |
+++ b/src/core/hle/kernel/archive.cpp | |
@@ -178,7 +178,7 @@ public: | |
case FileCommand::Close: | |
{ | |
DEBUG_LOG(KERNEL, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); | |
- Kernel::g_object_pool.Destroy<File>(GetHandle()); | |
+ Kernel::g_object_pool.Destroy(GetHandle()); | |
break; | |
} | |
@@ -233,7 +233,7 @@ public: | |
case DirectoryCommand::Close: | |
{ | |
DEBUG_LOG(KERNEL, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); | |
- Kernel::g_object_pool.Destroy<Directory>(GetHandle()); | |
+ Kernel::g_object_pool.Destroy(GetHandle()); | |
break; | |
} | |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp | |
index 80a34c2..e327d44 100644 | |
--- a/src/core/hle/kernel/kernel.cpp | |
+++ b/src/core/hle/kernel/kernel.cpp | |
@@ -31,6 +31,7 @@ Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) { | |
if (!occupied[i]) { | |
occupied[i] = true; | |
pool[i] = obj; | |
+ pool[i]->ref_count++; | |
pool[i]->handle = i + HANDLE_OFFSET; | |
return i + HANDLE_OFFSET; | |
} | |
@@ -52,8 +53,12 @@ bool ObjectPool::IsValid(Handle handle) const { | |
void ObjectPool::Clear() { | |
for (int i = 0; i < MAX_COUNT; i++) { | |
//brutally clear everything, no validation | |
- if (occupied[i]) | |
- delete pool[i]; | |
+ if (occupied[i]) { | |
+ if (pool[i]->ref_count == 1) | |
+ delete pool[i]; | |
+ else | |
+ pool[i]->ref_count--; | |
+ } | |
occupied[i] = false; | |
} | |
pool.fill(nullptr); | |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h | |
index 00a2228..46e1c9b 100644 | |
--- a/src/core/hle/kernel/kernel.h | |
+++ b/src/core/hle/kernel/kernel.h | |
@@ -66,6 +66,8 @@ public: | |
* @return True if the current thread should wait as a result of the wait | |
*/ | |
virtual ResultVal<bool> WaitSynchronization() = 0; | |
+ | |
+ int ref_count; | |
}; | |
class ObjectPool : NonCopyable { | |
@@ -78,15 +80,29 @@ public: | |
static Object* CreateByIDType(int type); | |
- template <class T> | |
+ bool IsValid(Handle handle) const; | |
+ | |
void Destroy(Handle handle) { | |
- if (Get<T>(handle)) { | |
- occupied[handle - HANDLE_OFFSET] = false; | |
- delete pool[handle - HANDLE_OFFSET]; | |
+ if (IsValid(handle)) { | |
+ Handle real_handle = handle - HANDLE_OFFSET; | |
+ occupied[real_handle] = false; | |
+ if (pool[real_handle]->ref_count == 1) { | |
+ delete pool[real_handle]; | |
+ pool[real_handle] = nullptr; | |
+ } else { | |
+ pool[real_handle]->ref_count--; | |
+ } | |
} | |
} | |
- bool IsValid(Handle handle) const; | |
+ Object* Get(Handle handle) { | |
+ if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { | |
+ if (handle != 0) | |
+ WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); | |
+ return nullptr; | |
+ } | |
+ return pool[handle - HANDLE_OFFSET]; | |
+ } | |
template <class T> | |
T* Get(Handle handle) { | |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h | |
index 20e7fb4..a91c0dd 100644 | |
--- a/src/core/hle/service/service.h | |
+++ b/src/core/hle/service/service.h | |
@@ -69,9 +69,8 @@ public: | |
} | |
/// Frees a handle from the service | |
- template <class T> | |
void DeleteHandle(const Handle handle) { | |
- Kernel::g_object_pool.Destroy<T>(handle); | |
+ Kernel::g_object_pool.Destroy(handle); | |
m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); | |
} | |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp | |
index a5805ed..403a63c 100644 | |
--- a/src/core/hle/svc.cpp | |
+++ b/src/core/hle/svc.cpp | |
@@ -107,8 +107,9 @@ static Result SendSyncRequest(Handle handle) { | |
/// Close a handle | |
static Result CloseHandle(Handle handle) { | |
- // ImplementMe | |
- ERROR_LOG(SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle); | |
+ Kernel::g_object_pool.Destroy(handle); | |
+ | |
+ ERROR_LOG(SVC, "called handle=0x%08X", handle); | |
return 0; | |
} | |
@@ -310,11 +311,10 @@ static Result DuplicateHandle(Handle* out, Handle handle) { | |
if (handle == Kernel::CurrentThread) { | |
handle = Kernel::GetCurrentThreadHandle(); | |
} | |
- _assert_msg_(KERNEL, (handle != Kernel::CurrentProcess), | |
- "(UNIMPLEMENTED) process handle duplication!"); | |
- // TODO(bunnei): FixMe - This is a hack to return the handle that we were asked to duplicate. | |
- *out = handle; | |
+ *out = Kernel::g_object_pool.Create(Kernel::g_object_pool.Get(handle)); | |
+ | |
+ DEBUG_LOG(SVC, "called handle=0x%08X", handle); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment