LookupObject helper.
This commit is contained in:
parent
120e09f8e7
commit
018e9a96e1
|
@ -21,7 +21,7 @@ ObjectTable::ObjectTable()
|
||||||
: table_capacity_(0), table_(nullptr), last_free_entry_(0) {}
|
: table_capacity_(0), table_(nullptr), last_free_entry_(0) {}
|
||||||
|
|
||||||
ObjectTable::~ObjectTable() {
|
ObjectTable::~ObjectTable() {
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Release all objects.
|
// Release all objects.
|
||||||
for (uint32_t n = 0; n < table_capacity_; n++) {
|
for (uint32_t n = 0; n < table_capacity_; n++) {
|
||||||
|
@ -89,7 +89,7 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||||
|
|
||||||
uint32_t slot = 0;
|
uint32_t slot = 0;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Find a free slot.
|
// Find a free slot.
|
||||||
result = FindFreeSlot(&slot);
|
result = FindFreeSlot(&slot);
|
||||||
|
@ -122,7 +122,7 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
||||||
|
|
||||||
XObject* object = NULL;
|
XObject* object = NULL;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
uint32_t slot = handle >> 2;
|
uint32_t slot = handle >> 2;
|
||||||
|
@ -153,16 +153,12 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
||||||
|
|
||||||
X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object,
|
X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object,
|
||||||
bool already_locked) {
|
bool already_locked) {
|
||||||
assert_not_null(out_object);
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
handle = TranslateHandle(handle);
|
handle = TranslateHandle(handle);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
return X_STATUS_INVALID_HANDLE;
|
return X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
XObject* object = NULL;
|
XObject* object = nullptr;
|
||||||
if (!already_locked) {
|
if (!already_locked) {
|
||||||
table_mutex_.lock();
|
table_mutex_.lock();
|
||||||
}
|
}
|
||||||
|
@ -171,14 +167,10 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object,
|
||||||
uint32_t slot = handle >> 2;
|
uint32_t slot = handle >> 2;
|
||||||
|
|
||||||
// Verify slot.
|
// Verify slot.
|
||||||
if (slot > table_capacity_) {
|
if (slot < table_capacity_) {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
|
||||||
} else {
|
|
||||||
ObjectTableEntry& entry = table_[slot];
|
ObjectTableEntry& entry = table_[slot];
|
||||||
if (entry.object) {
|
if (entry.object) {
|
||||||
object = entry.object;
|
object = entry.object;
|
||||||
} else {
|
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +184,41 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_object = object;
|
*out_object = object;
|
||||||
return result;
|
return object ? X_STATUS_SUCCESS : X_STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) {
|
||||||
|
handle = TranslateHandle(handle);
|
||||||
|
if (!handle) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
XObject* object = nullptr;
|
||||||
|
if (!already_locked) {
|
||||||
|
table_mutex_.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower 2 bits are ignored.
|
||||||
|
uint32_t slot = handle >> 2;
|
||||||
|
|
||||||
|
// Verify slot.
|
||||||
|
if (slot < table_capacity_) {
|
||||||
|
ObjectTableEntry& entry = table_[slot];
|
||||||
|
if (entry.object) {
|
||||||
|
object = entry.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retain the object pointer.
|
||||||
|
if (object) {
|
||||||
|
object->Retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!already_locked) {
|
||||||
|
table_mutex_.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) {
|
X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) {
|
||||||
|
@ -209,7 +235,7 @@ X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::AddNameMapping(const std::string& name, X_HANDLE handle) {
|
X_STATUS ObjectTable::AddNameMapping(const std::string& name, X_HANDLE handle) {
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
if (name_table_.count(name)) {
|
if (name_table_.count(name)) {
|
||||||
return X_STATUS_OBJECT_NAME_COLLISION;
|
return X_STATUS_OBJECT_NAME_COLLISION;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +244,7 @@ X_STATUS ObjectTable::AddNameMapping(const std::string& name, X_HANDLE handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTable::RemoveNameMapping(const std::string& name) {
|
void ObjectTable::RemoveNameMapping(const std::string& name) {
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
auto it = name_table_.find(name);
|
auto it = name_table_.find(name);
|
||||||
if (it != name_table_.end()) {
|
if (it != name_table_.end()) {
|
||||||
name_table_.erase(it);
|
name_table_.erase(it);
|
||||||
|
@ -227,7 +253,7 @@ void ObjectTable::RemoveNameMapping(const std::string& name) {
|
||||||
|
|
||||||
X_STATUS ObjectTable::GetObjectByName(const std::string& name,
|
X_STATUS ObjectTable::GetObjectByName(const std::string& name,
|
||||||
X_HANDLE* out_handle) {
|
X_HANDLE* out_handle) {
|
||||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
std::lock_guard<xe::mutex> lock(table_mutex_);
|
||||||
auto it = name_table_.find(name);
|
auto it = name_table_.find(name);
|
||||||
if (it == name_table_.end()) {
|
if (it == name_table_.end()) {
|
||||||
*out_handle = X_INVALID_HANDLE_VALUE;
|
*out_handle = X_INVALID_HANDLE_VALUE;
|
||||||
|
@ -236,8 +262,8 @@ X_STATUS ObjectTable::GetObjectByName(const std::string& name,
|
||||||
*out_handle = it->second;
|
*out_handle = it->second;
|
||||||
|
|
||||||
// We need to ref the handle. I think.
|
// We need to ref the handle. I think.
|
||||||
XObject* obj = nullptr;
|
auto obj = LookupObject(it->second, true);
|
||||||
if (XSUCCEEDED(GetObject(it->second, &obj, true))) {
|
if (obj) {
|
||||||
obj->RetainHandle();
|
obj->RetainHandle();
|
||||||
obj->Release();
|
obj->Release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,18 +30,26 @@ class ObjectTable {
|
||||||
X_STATUS RemoveHandle(X_HANDLE handle);
|
X_STATUS RemoveHandle(X_HANDLE handle);
|
||||||
X_STATUS GetObject(X_HANDLE handle, XObject** out_object,
|
X_STATUS GetObject(X_HANDLE handle, XObject** out_object,
|
||||||
bool already_locked = false);
|
bool already_locked = false);
|
||||||
|
template <typename T>
|
||||||
|
object_ref<T> LookupObject(X_HANDLE handle) {
|
||||||
|
auto object = LookupObject(handle, false);
|
||||||
|
auto result = object_ref<T>(reinterpret_cast<T*>(object));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
X_STATUS AddNameMapping(const std::string& name, X_HANDLE handle);
|
X_STATUS AddNameMapping(const std::string& name, X_HANDLE handle);
|
||||||
void RemoveNameMapping(const std::string& name);
|
void RemoveNameMapping(const std::string& name);
|
||||||
X_STATUS GetObjectByName(const std::string& name, X_HANDLE* out_handle);
|
X_STATUS GetObjectByName(const std::string& name, X_HANDLE* out_handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
XObject* LookupObject(X_HANDLE handle, bool already_locked);
|
||||||
|
|
||||||
X_HANDLE TranslateHandle(X_HANDLE handle);
|
X_HANDLE TranslateHandle(X_HANDLE handle);
|
||||||
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
||||||
|
|
||||||
typedef struct { XObject* object; } ObjectTableEntry;
|
typedef struct { XObject* object; } ObjectTableEntry;
|
||||||
|
|
||||||
std::mutex table_mutex_;
|
xe::mutex table_mutex_;
|
||||||
uint32_t table_capacity_;
|
uint32_t table_capacity_;
|
||||||
ObjectTableEntry* table_;
|
ObjectTableEntry* table_;
|
||||||
uint32_t last_free_entry_;
|
uint32_t last_free_entry_;
|
||||||
|
|
Loading…
Reference in New Issue