[Kernel] Improvements to host and guest objects handling
This commit is contained in:
committed by
Radosław Gliński
parent
5b0fe5aada
commit
40f6b5b3ac
@@ -132,7 +132,13 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
|||||||
entry.object = object;
|
entry.object = object;
|
||||||
entry.handle_ref_count = 1;
|
entry.handle_ref_count = 1;
|
||||||
handle = slot << 2;
|
handle = slot << 2;
|
||||||
if (!host_object) handle += XObject::kHandleBase;
|
if (!host_object) {
|
||||||
|
if (object->type() != XObject::Type::Socket) {
|
||||||
|
handle += XObject::kHandleBase;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handle += XObject::kHandleHostBase;
|
||||||
|
}
|
||||||
object->handles().push_back(handle);
|
object->handles().push_back(handle);
|
||||||
|
|
||||||
// Retain so long as the object is in the table.
|
// Retain so long as the object is in the table.
|
||||||
@@ -286,10 +292,9 @@ ObjectTable::ObjectTableEntry* ObjectTable::LookupTableInLock(X_HANDLE handle) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
const bool is_host_object = XObject::is_handle_host_object(handle);
|
||||||
bool host = (handle < XObject::kHandleBase);
|
uint32_t slot = GetHandleSlot(handle, is_host_object);
|
||||||
uint32_t slot = GetHandleSlot(handle, host);
|
if (is_host_object) {
|
||||||
if (host) {
|
|
||||||
if (slot <= host_table_capacity_) {
|
if (slot <= host_table_capacity_) {
|
||||||
return &host_table_[slot];
|
return &host_table_[slot];
|
||||||
}
|
}
|
||||||
@@ -320,12 +325,11 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) {
|
|||||||
global_critical_region_.mutex().lock();
|
global_critical_region_.mutex().lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
const bool is_host_object = XObject::is_handle_host_object(handle);
|
||||||
bool host = (handle < XObject::kHandleBase);
|
uint32_t slot = GetHandleSlot(handle, is_host_object);
|
||||||
uint32_t slot = GetHandleSlot(handle, host);
|
|
||||||
|
|
||||||
// Verify slot.
|
// Verify slot.
|
||||||
if (host) {
|
if (is_host_object) {
|
||||||
if (slot < host_table_capacity_) {
|
if (slot < host_table_capacity_) {
|
||||||
ObjectTableEntry& entry = host_table_[slot];
|
ObjectTableEntry& entry = host_table_[slot];
|
||||||
if (entry.object) {
|
if (entry.object) {
|
||||||
@@ -461,13 +465,13 @@ bool ObjectTable::Restore(ByteStream* stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) {
|
X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) {
|
||||||
bool host = (handle < XObject::kHandleBase);
|
const bool is_host_object = XObject::is_handle_host_object(handle);
|
||||||
uint32_t slot = GetHandleSlot(handle, host);
|
uint32_t slot = GetHandleSlot(handle, is_host_object);
|
||||||
uint32_t capacity = host ? host_table_capacity_ : table_capacity_;
|
uint32_t capacity = is_host_object ? host_table_capacity_ : table_capacity_;
|
||||||
assert_true(capacity >= slot);
|
assert_true(capacity >= slot);
|
||||||
|
|
||||||
if (capacity >= slot) {
|
if (capacity >= slot) {
|
||||||
auto& entry = host ? host_table_[slot] : table_[slot];
|
auto& entry = is_host_object ? host_table_[slot] : table_[slot];
|
||||||
entry.object = object;
|
entry.object = object;
|
||||||
object->Retain();
|
object->Retain();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ class ObjectTable {
|
|||||||
X_STATUS RestoreHandle(X_HANDLE handle, XObject* object);
|
X_STATUS RestoreHandle(X_HANDLE handle, XObject* object);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
object_ref<T> LookupObject(X_HANDLE handle, bool already_locked = false) {
|
object_ref<T> LookupObject(X_HANDLE handle, bool already_locked = false) {
|
||||||
if (T::kObjectType == XObject::Type::Socket) {
|
|
||||||
handle |= XObject::kHandleBase;
|
|
||||||
}
|
|
||||||
auto object = LookupObject(handle, already_locked);
|
auto object = LookupObject(handle, already_locked);
|
||||||
if (object) {
|
if (object) {
|
||||||
assert_true(object->type() == T::kObjectType);
|
assert_true(object->type() == T::kObjectType);
|
||||||
@@ -96,7 +93,7 @@ class ObjectTable {
|
|||||||
|
|
||||||
X_HANDLE TranslateHandle(X_HANDLE handle);
|
X_HANDLE TranslateHandle(X_HANDLE handle);
|
||||||
static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) {
|
static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) {
|
||||||
if (!host) handle -= XObject::kHandleBase;
|
handle &= host ? ~XObject::kHandleHostBase : ~XObject::kHandleBase;
|
||||||
return handle >> 2;
|
return handle >> 2;
|
||||||
}
|
}
|
||||||
X_STATUS FindFreeSlot(uint32_t* out_slot, bool host);
|
X_STATUS FindFreeSlot(uint32_t* out_slot, bool host);
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (socket->handle() & 0x00FFFFFF);
|
return socket->handle();
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(NetDll_socket, kNetworking, kImplemented);
|
DECLARE_XAM_EXPORT1(NetDll_socket, kNetworking, kImplemented);
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class XObject {
|
|||||||
// Instead of receiving address that starts with 0x82... we're receiving
|
// Instead of receiving address that starts with 0x82... we're receiving
|
||||||
// one with 0x8A... which causes crash
|
// one with 0x8A... which causes crash
|
||||||
static constexpr uint32_t kHandleBase = 0xF8000000;
|
static constexpr uint32_t kHandleBase = 0xF8000000;
|
||||||
|
static constexpr uint32_t kHandleHostBase = 0x01000000;
|
||||||
|
|
||||||
enum class Type : uint32_t {
|
enum class Type : uint32_t {
|
||||||
Undefined,
|
Undefined,
|
||||||
@@ -175,6 +176,9 @@ class XObject {
|
|||||||
static object_ref<XObject> Restore(KernelState* kernel_state, Type type,
|
static object_ref<XObject> Restore(KernelState* kernel_state, Type type,
|
||||||
ByteStream* stream);
|
ByteStream* stream);
|
||||||
|
|
||||||
|
static constexpr bool is_handle_host_object(X_HANDLE handle) {
|
||||||
|
return handle > XObject::kHandleHostBase && handle < XObject::kHandleBase;
|
||||||
|
};
|
||||||
// Reference()
|
// Reference()
|
||||||
// Dereference()
|
// Dereference()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user