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) {
return X_STATUS_INVALID_HANDLE;
}
std::lock_guard<xe::recursive_mutex> lock(table_mutex_); std::lock_guard<xe::recursive_mutex> lock(table_mutex_);
if (entry->object) {
auto object = entry->object;
entry->object = nullptr;
entry->handle_ref_count = 0;
// Lower 2 bits are ignored. // Release now that the object has been removed from the table.
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) {
// Release the object handle now that it is out of the table.
object->ReleaseHandle();
object->Release(); object->Release();
} }
return result; return X_STATUS_SUCCESS;
} }
ObjectTable::ObjectTableEntry* ObjectTable::LookupTable(X_HANDLE handle) { ObjectTable::ObjectTableEntry* ObjectTable::LookupTable(X_HANDLE handle) {