Commit 045ee8ae authored by David Reid's avatar David Reid

Experimental fix for a memory leak in the resource manager.

parent eef66940
...@@ -6361,44 +6361,44 @@ static ma_result ma_resource_manager_data_buffer_uninit_internal(ma_resource_man ...@@ -6361,44 +6361,44 @@ static ma_result ma_resource_manager_data_buffer_uninit_internal(ma_resource_man
ma_resource_manager_data_buffer_uninit_connector(pDataBuffer->pResourceManager, pDataBuffer); ma_resource_manager_data_buffer_uninit_connector(pDataBuffer->pResourceManager, pDataBuffer);
pDataBuffer->connectorType = ma_resource_manager_data_buffer_connector_unknown; pDataBuffer->connectorType = ma_resource_manager_data_buffer_connector_unknown;
/* Free the node last. */ /* With the connector uninitialized we can decrement the ref count of the node and free it if required. */
ma_resource_manager_data_buffer_node_free(pDataBuffer->pResourceManager, pDataBuffer->pNode); ma_resource_manager_data_buffer_bst_lock(pDataBuffer->pResourceManager);
{
return MA_SUCCESS; ma_result result;
}
static ma_result ma_resource_manager_data_buffer_uninit_nolock(ma_resource_manager_data_buffer* pDataBuffer)
{
ma_uint32 result;
ma_uint32 refCount; ma_uint32 refCount;
MA_ASSERT(pDataBuffer != NULL);
result = ma_resource_manager_data_buffer_node_decrement_ref(pDataBuffer->pResourceManager, pDataBuffer->pNode, &refCount); result = ma_resource_manager_data_buffer_node_decrement_ref(pDataBuffer->pResourceManager, pDataBuffer->pNode, &refCount);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; return result;
} }
/* If the reference count has hit zero it means we need to delete the data buffer and it's backing data (so long as it's owned by the resource manager). */
if (refCount == 0) { if (refCount == 0) {
ma_bool32 asyncUninit = MA_TRUE;
result = ma_resource_manager_data_buffer_node_remove(pDataBuffer->pResourceManager, pDataBuffer->pNode); result = ma_resource_manager_data_buffer_node_remove(pDataBuffer->pResourceManager, pDataBuffer->pNode);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
return result; /* An error occurred when trying to remove the data buffer. This should never happen. */ return result; /* An error occurred when trying to remove the data buffer. This should never happen. */
} }
if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_SUCCESS) { /* Mark the node as unavailable just to be safe. */
asyncUninit = MA_FALSE; c89atomic_exchange_i32(&pDataBuffer->pNode->result, MA_UNAVAILABLE);
/* Free the node last. */
ma_resource_manager_data_buffer_node_free(pDataBuffer->pResourceManager, pDataBuffer->pNode);
}
} }
ma_resource_manager_data_buffer_bst_unlock(pDataBuffer->pResourceManager);
/* return MA_SUCCESS;
The data buffer has been removed from the BST so now we need to delete the underyling data. This needs to be done in a separate thread. We don't }
want to delete anything if the data is owned by the application. Also, just to be safe, we set the result to MA_UNAVAILABLE.
*/
c89atomic_exchange_i32(&pDataBuffer->pNode->result, MA_UNAVAILABLE);
if (asyncUninit == MA_FALSE) { MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data_buffer* pDataBuffer)
{
ma_result result;
if (pDataBuffer == NULL) {
return MA_INVALID_ARGS;
}
if (ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) == MA_SUCCESS) {
/* The data buffer can be deleted synchronously. */ /* The data buffer can be deleted synchronously. */
return ma_resource_manager_data_buffer_uninit_internal(pDataBuffer); return ma_resource_manager_data_buffer_uninit_internal(pDataBuffer);
} else { } else {
...@@ -6429,24 +6429,6 @@ static ma_result ma_resource_manager_data_buffer_uninit_nolock(ma_resource_manag ...@@ -6429,24 +6429,6 @@ static ma_result ma_resource_manager_data_buffer_uninit_nolock(ma_resource_manag
ma_resource_manager_inline_notification_wait(&notification); ma_resource_manager_inline_notification_wait(&notification);
ma_resource_manager_inline_notification_uninit(&notification); ma_resource_manager_inline_notification_uninit(&notification);
} }
}
return MA_SUCCESS;
}
MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data_buffer* pDataBuffer)
{
ma_result result;
if (pDataBuffer == NULL) {
return MA_INVALID_ARGS;
}
ma_resource_manager_data_buffer_bst_lock(pDataBuffer->pResourceManager);
{
result = ma_resource_manager_data_buffer_uninit_nolock(pDataBuffer);
}
ma_resource_manager_data_buffer_bst_unlock(pDataBuffer->pResourceManager);
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment