Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
045ee8ae
Commit
045ee8ae
authored
Mar 21, 2021
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experimental fix for a memory leak in the resource manager.
parent
eef66940
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
45 additions
and
63 deletions
+45
-63
research/miniaudio_engine.h
research/miniaudio_engine.h
+45
-63
No files found.
research/miniaudio_engine.h
View file @
045ee8ae
...
@@ -6361,75 +6361,31 @@ static ma_result ma_resource_manager_data_buffer_uninit_internal(ma_resource_man
...
@@ -6361,75 +6361,31 @@ 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
;
}
ma_uint32
refCount
;
static
ma_result
ma_resource_manager_data_buffer_uninit_nolock
(
ma_resource_manager_data_buffer
*
pDataBuffer
)
{
ma_uint32
result
;
ma_uint32
refCount
;
MA_ASSERT
(
pDataBuffer
!=
NULL
);
result
=
ma_resource_manager_data_buffer_node_decrement_ref
(
pDataBuffer
->
pResourceManager
,
pDataBuffer
->
pNode
,
&
refCount
);
if
(
result
!=
MA_SUCCESS
)
{
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
)
{
ma_bool32
asyncUninit
=
MA_TRUE
;
result
=
ma_resource_manager_data_buffer_node_
remove
(
pDataBuffer
->
pResourceManager
,
pDataBuffer
->
pNode
);
result
=
ma_resource_manager_data_buffer_node_
decrement_ref
(
pDataBuffer
->
pResourceManager
,
pDataBuffer
->
pNode
,
&
refCount
);
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
;
}
if
(
ma_resource_manager_data_buffer_node_result
(
pDataBuffer
->
pNode
)
==
MA_SUCCESS
)
{
asyncUninit
=
MA_FALSE
;
}
}
/*
if
(
refCount
==
0
)
{
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
result
=
ma_resource_manager_data_buffer_node_remove
(
pDataBuffer
->
pResourceManager
,
pDataBuffer
->
pNode
);
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
)
{
/* The data buffer can be deleted synchronously. */
return
ma_resource_manager_data_buffer_uninit_internal
(
pDataBuffer
);
}
else
{
/*
The data buffer needs to be deleted asynchronously because it's still loading. With the status set to MA_UNAVAILABLE, no more pages will
be loaded and the uninitialization should happen fairly quickly. Since the caller owns the data buffer, we need to wait for this event
to get processed before returning.
*/
ma_resource_manager_inline_notification
notification
;
ma_job
job
;
result
=
ma_resource_manager_inline_notification_init
(
pDataBuffer
->
pResourceManager
,
&
notification
);
if
(
result
!=
MA_SUCCESS
)
{
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
/*
Failed to create the notification. This should rarely, if ever,
happen. */
return
result
;
/*
An error occurred when trying to remove the data buffer. This should never
happen. */
}
}
job
=
ma_job_init
(
MA_JOB_FREE_DATA_BUFFER
);
/* Mark the node as unavailable just to be safe. */
job
.
order
=
ma_resource_manager_data_buffer_next_execution_order
(
pDataBuffer
);
c89atomic_exchange_i32
(
&
pDataBuffer
->
pNode
->
result
,
MA_UNAVAILABLE
);
job
.
freeDataBuffer
.
pDataBuffer
=
pDataBuffer
;
job
.
freeDataBuffer
.
pNotification
=
&
notification
;
result
=
ma_resource_manager_post_job
(
pDataBuffer
->
pResourceManager
,
&
job
);
if
(
result
!=
MA_SUCCESS
)
{
ma_resource_manager_inline_notification_uninit
(
&
notification
);
return
result
;
}
ma_resource_manager_inline_notification_wait
(
&
notification
);
/* Free the node last. */
ma_resource_manager_
inline_notification_uninit
(
&
notification
);
ma_resource_manager_
data_buffer_node_free
(
pDataBuffer
->
pResourceManager
,
pDataBuffer
->
pNode
);
}
}
}
}
ma_resource_manager_data_buffer_bst_unlock
(
pDataBuffer
->
pResourceManager
);
return
MA_SUCCESS
;
return
MA_SUCCESS
;
}
}
...
@@ -6442,11 +6398,37 @@ MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data
...
@@ -6442,11 +6398,37 @@ MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data
return
MA_INVALID_ARGS
;
return
MA_INVALID_ARGS
;
}
}
ma_resource_manager_data_buffer_bst_lock
(
pDataBuffer
->
pResourceManager
);
if
(
ma_resource_manager_data_buffer_node_result
(
pDataBuffer
->
pNode
)
==
MA_SUCCESS
)
{
{
/* The data buffer can be deleted synchronously. */
result
=
ma_resource_manager_data_buffer_uninit_nolock
(
pDataBuffer
);
return
ma_resource_manager_data_buffer_uninit_internal
(
pDataBuffer
);
}
else
{
/*
The data buffer needs to be deleted asynchronously because it's still loading. With the status set to MA_UNAVAILABLE, no more pages will
be loaded and the uninitialization should happen fairly quickly. Since the caller owns the data buffer, we need to wait for this event
to get processed before returning.
*/
ma_resource_manager_inline_notification
notification
;
ma_job
job
;
result
=
ma_resource_manager_inline_notification_init
(
pDataBuffer
->
pResourceManager
,
&
notification
);
if
(
result
!=
MA_SUCCESS
)
{
return
result
;
/* Failed to create the notification. This should rarely, if ever, happen. */
}
job
=
ma_job_init
(
MA_JOB_FREE_DATA_BUFFER
);
job
.
order
=
ma_resource_manager_data_buffer_next_execution_order
(
pDataBuffer
);
job
.
freeDataBuffer
.
pDataBuffer
=
pDataBuffer
;
job
.
freeDataBuffer
.
pNotification
=
&
notification
;
result
=
ma_resource_manager_post_job
(
pDataBuffer
->
pResourceManager
,
&
job
);
if
(
result
!=
MA_SUCCESS
)
{
ma_resource_manager_inline_notification_uninit
(
&
notification
);
return
result
;
}
ma_resource_manager_inline_notification_wait
(
&
notification
);
ma_resource_manager_inline_notification_uninit
(
&
notification
);
}
}
ma_resource_manager_data_buffer_bst_unlock
(
pDataBuffer
->
pResourceManager
);
return
result
;
return
result
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment