Fix accidentally releasing the primary handle of a duplicated object when the duplicated handle is removed.

This commit is contained in:
Dr. Chat 2015-07-25 20:00:18 -05:00
parent abf50b477e
commit 30f3994476
1 changed files with 11 additions and 24 deletions

View File

@ -165,35 +165,22 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
return X_STATUS_INVALID_HANDLE; return X_STATUS_INVALID_HANDLE;
} }
XObject* object = NULL; ObjectTableEntry* entry = LookupTable(handle);
{ if (!entry) {
std::lock_guard<xe::recursive_mutex> lock(table_mutex_); return X_STATUS_INVALID_HANDLE;
// Lower 2 bits are ignored.
uint32_t slot = handle >> 2;
// Verify slot.
if (slot > table_capacity_) {
result = X_STATUS_INVALID_HANDLE;
} else {
ObjectTableEntry& entry = table_[slot];
if (entry.object) {
// Release after we lose the lock.
object = entry.object;
} else {
result = X_STATUS_INVALID_HANDLE;
}
entry.object = nullptr;
}
} }
if (object) { std::lock_guard<xe::recursive_mutex> lock(table_mutex_);
// Release the object handle now that it is out of the table. if (entry->object) {
object->ReleaseHandle(); auto object = entry->object;
entry->object = nullptr;
entry->handle_ref_count = 0;
// Release now that the object has been removed from the table.
object->Release(); object->Release();
} }
return result; return X_STATUS_SUCCESS;
} }
ObjectTable::ObjectTableEntry* ObjectTable::LookupTable(X_HANDLE handle) { ObjectTable::ObjectTableEntry* ObjectTable::LookupTable(X_HANDLE handle) {