diff options
author | Stephane Desneux <stephane.desneux@iot.bzh> | 2018-12-22 11:51:54 +0100 |
---|---|---|
committer | Stephane Desneux <stephane.desneux@iot.bzh> | 2018-12-22 11:51:54 +0100 |
commit | c85fd2f131c73e8c21e05e1ea80b55d6a787dda6 (patch) | |
tree | 248aca4a75556e3546a3c89cac43bcffe3ccf634 /plugins/alsa/alsa-api-loop.c | |
parent | e0f57e523112e1bc73a04e8615d7a21355f0ce0e (diff) |
Implemented the bug cleanup at application exit
Fixes most memory leaks in softmixer.
The concept of 'transaction' for dynamic streams has
been generalized to the objects created at startup.
The cleanup is done via a handle set through a atexit()
call.
Also added a missing strdup in alsa-api-loop, that fixes
a double free.
Warning, the bluez-alsa PCM are not closed in this
version. This is intentional due to a BUG in the
bluealsa ioplug PCM, that crashes upon close
(pthread_cancel is used to terminate the io_thread
and things get very bad. I have a pending fix for
that, relying on a cancellation pipe, but deeper
testing must be done).
As an effect, only one phone call can be made,
else 4a needs to be restarted
Change-Id: Idb84cafe15f17c0ef02fcc70296d541dc55a2dcf
Signed-off-by: Thierry Bultel <thierry.bultel@iot.bzh>
Signed-off-by: Stephane Desneux <stephane.desneux@iot.bzh>
Diffstat (limited to 'plugins/alsa/alsa-api-loop.c')
-rw-r--r-- | plugins/alsa/alsa-api-loop.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/plugins/alsa/alsa-api-loop.c b/plugins/alsa/alsa-api-loop.c index 16491a0..ffab6bc 100644 --- a/plugins/alsa/alsa-api-loop.c +++ b/plugins/alsa/alsa-api-loop.c @@ -40,20 +40,25 @@ PUBLIC AlsaLoopSubdevT *ApiLoopFindSubdev(SoftMixerT *mixer, const char *streamU AlsaLoopSubdevT * subdev; cds_list_for_each_entry(subdev, &_loop->subdevs.list, list) { if (!subdev->uid) { - subdev->uid = streamUid; + subdev->uid = strdup(streamUid); + if (!subdev->uid) { + SOFTMIXER_NOMEM(mixer->api); + goto fail; + } *loop = _loop; return subdev; } } } } +fail: return NULL; } STATIC AlsaLoopSubdevT *ProcessOneSubdev(SoftMixerT *mixer, AlsaSndLoopT *loop, json_object *subdevJ) { - AFB_ApiDebug(mixer->api, "%s", __func__); + AFB_ApiDebug(mixer->api, "%s : %s", __func__, json_object_get_string(subdevJ)); AlsaLoopSubdevT *subdev = calloc(1, sizeof (AlsaLoopSubdevT)); if (subdev == NULL) { @@ -69,7 +74,7 @@ STATIC AlsaLoopSubdevT *ProcessOneSubdev(SoftMixerT *mixer, AlsaSndLoopT *loop, if (error) { AFB_ApiError(mixer->api, "%s: loop=%s missing (uid|subdev|numid) error=%s json=%s", - __func__, loop->uid, wrap_json_get_error_string(error),json_object_get_string(subdevJ)); + __func__, loop->uid, wrap_json_get_error_string(error), json_object_get_string(subdevJ)); goto fail_subdev; } @@ -100,6 +105,7 @@ STATIC AlsaLoopSubdevT *ProcessOneSubdev(SoftMixerT *mixer, AlsaSndLoopT *loop, pcmCtl->closeAtDeletion = true; // free PCM as we only open loop to assert it's a valid capture device + AlsaMixerTransactionObjectForget(mixer->transaction, pcmCtl); AlsaPcmCtlDelete(mixer, pcmCtl); AFB_ApiDebug(mixer->api, "%s DONE", __func__); @@ -114,9 +120,8 @@ fail: return NULL; } -static void freeSubdev(AlsaLoopSubdevT * subdev) { - if (subdev->uid) - free((char*)subdev->uid); +static void freeSubdev(SoftMixerT* mixer, AlsaLoopSubdevT * subdev) { + free(subdev->uid); free(subdev); } @@ -219,7 +224,7 @@ fail_loop_subdev: { AlsaLoopSubdevT * subdev, *tmp; cds_list_for_each_entry_safe(subdev, tmp, &loop->subdevs.list, list) { cds_list_del(&subdev->list); - freeSubdev(subdev); + freeSubdev(mixer, subdev); } } @@ -235,37 +240,38 @@ fail: static void loopDestroy(SoftMixerT * mixer, void* arg) { AlsaSndLoopT * loop = (AlsaSndLoopT*) arg; - AFB_ApiDebug(mixer->api, "%s... %s not implemented", __func__, loop->uid); - return; - - if (loop->sndcard) { - if (loop->sndcard->ctl) { - snd_ctl_close(loop->sndcard->ctl); - free(loop->sndcard->ctl); - } - free(loop->sndcard); - } + AFB_ApiDebug(mixer->api, "%s... %s", __func__, loop->uid); AlsaLoopSubdevT * subdev, *tmp; cds_list_for_each_entry_safe(subdev, tmp, &loop->subdevs.list, list) { cds_list_del(&subdev->list); - freeSubdev(subdev); + freeSubdev(mixer, subdev); } + + if (loop->sndcard->ctl) + snd_ctl_close(loop->sndcard->ctl); + mixer->nbLoops--; + cds_list_del(&loop->list); free(loop); + AFB_ApiDebug(mixer->api, "DONE !"); } static AlsaSndLoopT * loopCreate(SoftMixerT *mixer, const char *uid, json_object *argsJ) { + AlsaSndLoopT * newLoop = AttachOneLoop(mixer, uid, argsJ); if (!newLoop) { goto fail; } mixer->nbLoops++; - cds_list_add_tail(&newLoop->list, &mixer->loops.list); + cds_list_add(&newLoop->list, &mixer->loops.list); AlsaMixerTransactionObjectAdd(mixer->transaction, newLoop, loopDestroy); + loopsDisplay(mixer); + + fail: return newLoop; } @@ -315,3 +321,21 @@ fail_loop: fail: return -1; } + + +static void subdevDisplay(SoftMixerT *mixer, AlsaLoopSubdevT * subdev) { + AFB_ApiInfo(mixer->api, "\t\tsubdev id %d, uid %s", subdev->numid, subdev->uid); +} + +PUBLIC void loopsDisplay(SoftMixerT *mixer) { + AlsaSndLoopT * loop; + AFB_ApiInfo(mixer->api, "Mixer %s LOOPS:", mixer->uid); + cds_list_for_each_entry(loop, &mixer->loops.list, list) { + AFB_ApiInfo(mixer->api, "\tLOOP %s", loop->uid); + AlsaLoopSubdevT * subdev; + cds_list_for_each_entry(subdev, &loop->subdevs.list, list) { + subdevDisplay(mixer, subdev); + } + } + AFB_ApiInfo(mixer->api, "--------------"); +} |