summaryrefslogtreecommitdiffstats
path: root/plugins/alsa/alsa-transaction.c
diff options
context:
space:
mode:
authorStephane Desneux <stephane.desneux@iot.bzh>2018-12-22 11:51:54 +0100
committerStephane Desneux <stephane.desneux@iot.bzh>2018-12-22 11:51:54 +0100
commitc85fd2f131c73e8c21e05e1ea80b55d6a787dda6 (patch)
tree248aca4a75556e3546a3c89cac43bcffe3ccf634 /plugins/alsa/alsa-transaction.c
parente0f57e523112e1bc73a04e8615d7a21355f0ce0e (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-transaction.c')
-rw-r--r--plugins/alsa/alsa-transaction.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/plugins/alsa/alsa-transaction.c b/plugins/alsa/alsa-transaction.c
index bd32603..1958c87 100644
--- a/plugins/alsa/alsa-transaction.c
+++ b/plugins/alsa/alsa-transaction.c
@@ -5,23 +5,30 @@
#include "alsa-transaction.h"
#include "wrap-json.h"
+
+void AlsaMixerTransactionDelete(AlsaMixerTransaction * transaction) {
+ free((char*)transaction->uid);
+ free(transaction);
+}
+
AlsaMixerTransaction * AlsaMixerTransactionNew(struct SoftMixerT_ * mixer, const char * uid) {
- AlsaMixerTransaction * newList = (AlsaMixerTransaction *) malloc(sizeof(AlsaMixerTransaction));
- if (newList == NULL)
+ AlsaMixerTransaction * transaction = (AlsaMixerTransaction *) malloc(sizeof(AlsaMixerTransaction));
+ if (transaction == NULL)
goto fail;
- CDS_INIT_LIST_HEAD(&newList->list);
- newList->uid = strdup(uid);
- if (newList->uid == NULL) {
+ CDS_INIT_LIST_HEAD(&transaction->item_list);
+ transaction->uid = strdup(uid);
+ if (transaction->uid == NULL) {
goto fail_list;
}
- newList->mixer = mixer;
+ transaction->mixer = mixer;
+ cds_list_add(&transaction->transaction_node, &mixer->transactionList);
- return newList;
+ return transaction;
fail_list:
- free(newList);
+ free(transaction);
fail:
return NULL;
}
@@ -30,6 +37,15 @@ void AlsaMixerTransactionDataListDestroy(AlsaMixerTransaction* list) {
free(list);
}
+void AlsaMixerTransactionObjectForget(AlsaMixerTransaction* list, void * object) {
+ AlsaMixerTransactionDataItem *item, *tmp;
+ cds_list_for_each_entry_safe(item, tmp, &list->item_list, list_entry)
+ if (item->object == object) {
+ cds_list_del(&item->list_entry);
+ free(item);
+ }
+ }
+
bool AlsaMixerTransactionObjectAdd(AlsaMixerTransaction* list, void* object, AlsaTransactionDestructor destructor) {
bool ret = false;
AlsaMixerTransactionDataItem * newItem = NULL;
@@ -43,7 +59,7 @@ bool AlsaMixerTransactionObjectAdd(AlsaMixerTransaction* list, void* object, Als
CDS_INIT_LIST_HEAD(&newItem->list_entry);
newItem->object = object;
newItem->destructor = destructor;
- cds_list_add(&newItem->list_entry, &list->list);
+ cds_list_add(&newItem->list_entry, &list->item_list);
ret = true;
fail:
@@ -54,13 +70,17 @@ fail:
void AlsaMixerTransactionDoCleanup(AlsaMixerTransaction* transaction) {
AlsaMixerTransactionDataItem * item, *sav;
- cds_list_for_each_entry_safe(item, sav, &transaction->list, list_entry) {
+ AFB_ApiInfo(transaction->mixer->api, "%s for transaction %s", __func__, transaction->uid);
+
+ cds_list_for_each_entry_safe(item, sav, &transaction->item_list, list_entry) {
if (item->destructor)
item->destructor(transaction->mixer, item->object);
cds_list_del(&item->list_entry);
free(item);
}
+
+ AFB_ApiInfo(transaction->mixer->api, "%s for transaction %s .. DONE !", __func__, transaction->uid);
}
void AlsaMixerTransactionVerbCB(AFB_ReqT request) {
@@ -69,43 +89,47 @@ void AlsaMixerTransactionVerbCB(AFB_ReqT request) {
json_object *argsJ = afb_req_json(request);
int error;
char * action = NULL;
- const char * uid;
+ const char * uid = NULL;
error = wrap_json_unpack(argsJ, "{ss!}",
"action", &action);
if (error) {
AFB_ReqFailF(request, "missing action", "%s: missing 'action' field: %s", transaction->uid, json_object_get_string(argsJ));
- goto OnErrorExit;
+ goto fail;
}
uid = strdup(transaction->uid);
if (!uid) {
SOFTMIXER_NOMEM(transaction->mixer->api);
- goto OnErrorExit;
+ goto fail;
}
if (strcmp(action, "remove") == 0) {
AlsaMixerTransactionDoCleanup(transaction);
- error = afb_api_del_verb(transaction->mixer->api, transaction->uid, (void**)transaction);
+
+ // remove this transaction for the list of mixer
+ cds_list_del(&transaction->transaction_node);
+
+ error = afb_api_del_verb(transaction->mixer->api, transaction->uid, (void**)NULL);
if (error) {
AFB_ReqFail(request, "verb deletion" , "verb was not removed");
- goto OnErrorExit;
+ goto fail;
}
+ AlsaMixerTransactionDelete(transaction);
+
} else {
AFB_ReqFailF(request, "unsupported action", "%s: unsupported action %s (supported ones are ['remove']", transaction->uid, action);
- goto OnErrorExit;
+ goto fail;
}
responseJ=json_object_new_object();
json_object_object_add(responseJ, "result", json_object_new_string("OK"));
AFB_ReqSuccess(request, responseJ, uid);
+fail:
free((char*)uid);
return;
-OnErrorExit:
- return;
-
}