Commit 27ab9e7
committed
audio: plug leak and skip redundant copy in mixer add_stream
audio_driver_mixer_add_stream unconditionally malloc+memcpy'd the
incoming buf before handing it to the format loader. This was both
wasteful and leaky:
* For OGG/FLAC/MP3/MOD, the loader stores the pointer into
sound->types.XXX.data and audio_mixer_destroy() free()s it on
sound completion. With the internal memcpy, that destroy path
freed the internal copy, not the caller-owned original - and the
original had no free path at all. Every one of the ten callers
in task_audio_mixer.c passes img->buf without freeing it after
the call, expecting the mixer to take ownership, so every loaded
mixer sound leaked the entire source buffer (typical size: tens
of kB to a few MB per sound).
* For WAV, the loader converts to PCM and free()s the input buffer
inline, so only the per-call copy was wasted - no leak, just the
duplicate.
task_translation.c has the opposite expectation: it passes
response->sound_data and explicitly free()s it after the call,
requiring a copy.
Resolve the ambiguity with an explicit buf_owned flag on
audio_mixer_stream_params_t:
* true => add_stream takes ownership, either free()ing directly
(WAV) or via audio_mixer_destroy (OGG/FLAC/MP3/MOD). On
any early failure (bad params, no free slot, loader
returns NULL), the buffer is freed so ownership is
respected uniformly.
* false => add_stream makes a private copy (previous behavior).
Caller retains ownership of the original.
All ten task_audio_mixer.c callers are updated to set
buf_owned = true; the single task_translation.c caller sets it false
explicitly with an explanatory comment.
This also restructures the early-failure paths to a single 'error:'
label so the ownership discipline is expressed once and can't drift.
Scope note: the modified API (audio_driver_mixer_add_stream, the
audio_mixer_stream_params_t struct) is frontend-only. It lives in
audio/audio_driver.{c,h}, is not exposed via libretro.h, is not
part of libretro-common, and cannot be reached from cores. The
lower-level audio_mixer_* API in libretro-common/audio/audio_mixer.c
is unchanged.
Thread-safety: add_stream runs on the main thread (task callbacks
fire from task_queue_check, which is called from retroarch.c's main
loop). audio_mixer_mix runs on the main thread in the normal case
and on the audio thread when a core uses the libretro audio-callback
extension. The existing code had no locking around mixer slot state;
this patch neither introduces nor closes that pre-existing race. The
only state change relative to the old code is which pointer lives in
stream->buf - same publication visibility, same memory ordering
concerns as before.1 parent b9d45ba commit 27ab9e7
4 files changed
Lines changed: 45 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1419 | 1419 | | |
1420 | 1420 | | |
1421 | 1421 | | |
1422 | | - | |
| 1422 | + | |
1423 | 1423 | | |
1424 | 1424 | | |
1425 | 1425 | | |
| |||
1436 | 1436 | | |
1437 | 1437 | | |
1438 | 1438 | | |
1439 | | - | |
| 1439 | + | |
1440 | 1440 | | |
1441 | 1441 | | |
1442 | 1442 | | |
1443 | 1443 | | |
1444 | | - | |
1445 | | - | |
1446 | | - | |
1447 | | - | |
| 1444 | + | |
1448 | 1445 | | |
1449 | | - | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
1450 | 1460 | | |
1451 | 1461 | | |
1452 | 1462 | | |
| |||
1521 | 1531 | | |
1522 | 1532 | | |
1523 | 1533 | | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
1524 | 1542 | | |
1525 | 1543 | | |
1526 | 1544 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
76 | 84 | | |
77 | 85 | | |
78 | 86 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| |||
147 | 148 | | |
148 | 149 | | |
149 | 150 | | |
| 151 | + | |
150 | 152 | | |
151 | 153 | | |
152 | 154 | | |
| |||
178 | 180 | | |
179 | 181 | | |
180 | 182 | | |
| 183 | + | |
181 | 184 | | |
182 | 185 | | |
183 | 186 | | |
| |||
209 | 212 | | |
210 | 213 | | |
211 | 214 | | |
| 215 | + | |
212 | 216 | | |
213 | 217 | | |
214 | 218 | | |
| |||
240 | 244 | | |
241 | 245 | | |
242 | 246 | | |
| 247 | + | |
243 | 248 | | |
244 | 249 | | |
245 | 250 | | |
| |||
271 | 276 | | |
272 | 277 | | |
273 | 278 | | |
| 279 | + | |
274 | 280 | | |
275 | 281 | | |
276 | 282 | | |
| |||
302 | 308 | | |
303 | 309 | | |
304 | 310 | | |
| 311 | + | |
305 | 312 | | |
306 | 313 | | |
307 | 314 | | |
| |||
333 | 340 | | |
334 | 341 | | |
335 | 342 | | |
| 343 | + | |
336 | 344 | | |
337 | 345 | | |
338 | 346 | | |
| |||
365 | 373 | | |
366 | 374 | | |
367 | 375 | | |
| 376 | + | |
368 | 377 | | |
369 | 378 | | |
370 | 379 | | |
| |||
396 | 405 | | |
397 | 406 | | |
398 | 407 | | |
| 408 | + | |
399 | 409 | | |
400 | 410 | | |
401 | 411 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
559 | 559 | | |
560 | 560 | | |
561 | 561 | | |
| 562 | + | |
| 563 | + | |
562 | 564 | | |
563 | 565 | | |
564 | 566 | | |
| |||
0 commit comments