aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonan Le Martret <ronan.lemartret@iot.bzh>2017-12-27 15:11:40 +0000
committerRonan Le Martret <ronan.lemartret@iot.bzh>2017-12-27 17:50:06 +0100
commit628d612ceaff0753a49ae79ee39b2b396d41fdcc (patch)
treeb87c44ca1e2593a0dd280dd8f0b2d35b4263d70b
parent4b80d0f17ce24d160f13f6e1d19021cbb2717429 (diff)
Fix undeclared event crash on 4A
- Add comment to Alsa Hook - Free resource when closing PCM - Fix Mainloop freeze on the second query Bug-AGL: SPEC-1110 Change-Id: I296f30b82cc85d4a57c1300518627ff1f8685c57 Signed-off-by: Ronan Le Martret <ronan.lemartret@iot.bzh>
-rw-r--r--alsa-hook/PolicyAlsaHook.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/alsa-hook/PolicyAlsaHook.c b/alsa-hook/PolicyAlsaHook.c
index 49e1559..38d3402 100644
--- a/alsa-hook/PolicyAlsaHook.c
+++ b/alsa-hook/PolicyAlsaHook.c
@@ -84,7 +84,6 @@ typedef struct {
typedef struct {
char *name;
- const char *api;
char *uid;
snd_pcm_t *pcm;
const char *uri;
@@ -111,15 +110,16 @@ static void *LoopInThread(void *handle) {
/* loop until end */
for (;;) {
- if (afbClient->verbose) printf("ON-MAINLOOP ping=%d\n", count++);
+ if (afbClient->verbose) printf("ON-MAINLOOP Session=%s ping=%d\n", afbClient->uid, count++);
int res = sd_event_run(afbClient->sdLoop, watchdog);
if ( res < 0 )
{
- printf("ERROR in LoopInThread \"%i\" Break ON-MAINLOOP.\n", res);
+ printf("ERROR in LoopInThread \"%i\" Break ON-MAINLOOP errno=%s.\n", res, strerror(errno));
break;
}
}
+ pthread_exit(0);
}
// lost connect with the AudioDaemon
@@ -147,7 +147,7 @@ void OnEventCB(void *handle, const char *event, int evtid, struct json_object *d
// if no event handler just ignore events
if (!afbEvent) goto OnErrorExit;
- if (afbClient->verbose) printf("ON-EVENT processing signal event=%s search=%s\n", event, json_object_get_string(dataJ));
+ if (afbClient->verbose) printf("ON-EVENT processing signal event=%s search=%s session=%s\n", event, json_object_get_string(dataJ), afbClient->uid);
// loop on event/signal mapping table
for (index=0; afbEvent[index]!= NULL; index++) {
@@ -239,7 +239,7 @@ static struct afb_proto_ws_client_itf itf = {
int OnTimeoutCB (sd_event_source* source, uint64_t timer, void* handle) {
afbClientT *afbClient= (afbClientT*)handle;
- SNDERR("\nON-TIMEOUT Call Request Fail URI=%s\n", afbClient->uri);
+ SNDERR("\nON-TIMEOUT Call Request Fail session=%s\n", afbClient->uid );
// Close PCM and release waiting client
afbClient->errcount=1;
@@ -254,7 +254,7 @@ static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int c
int err;
// create a unique tag for request
- (void) asprintf(&afbRequest->callIdTag, "%d:%s", count, afbRequest->apiverb);
+ int res= asprintf(&afbRequest->callIdTag, "%d:%s", count, afbRequest->apiverb);
// create a timer with ~250us accuracy
sd_event_now(afbClient->sdLoop, CLOCK_MONOTONIC, &usec);
@@ -262,8 +262,9 @@ static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int c
// release action is optional
if (afbRequest->apiverb) {
- if (afbClient->verbose) printf("CALL-REQUEST verb=%s query=%s tag=%s session=%s\n", afbRequest->apiverb, json_object_get_string(afbRequest->queryJ), afbRequest->callIdTag, afbClient->uid);
err = afb_proto_ws_client_call(afbClient->pws, afbRequest->apiverb, afbRequest->queryJ, afbClient->uid, afbRequest);
+ if (afbClient->verbose) printf("CALL-REQUEST verb=%s query=%s tag=%s session=%s err=%d\n", afbRequest->apiverb, json_object_get_string(afbRequest->queryJ), afbRequest->callIdTag, afbClient->uid, err);
+
if (err < 0 ) goto OnErrorExit;
}
@@ -274,7 +275,10 @@ static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int c
// in synchronous mode we wait for CB to return
if (afbClient->synchronous) {
sem_wait(&afbClient->semaphore);
- if (afbClient->errcount) goto OnErrorExit;
+ if (afbClient->errcount) {
+ printf("CALL-REQUEST FAILED afbClient->errcount=%d session=%s \n", afbClient->errcount,afbClient->uid);
+ goto OnErrorExit;
+ }
}
return 0;
@@ -293,14 +297,14 @@ static int LaunchCallRequest(afbClientT *afbClient, hookActionT action) {
switch (action) {
case HOOK_INSTALL: {
-
+ if (afbClient->verbose) printf("HOOK_INSTALL Session=%s\n", afbClient->uid);
// init waiting counting semaphore
if (sem_init(&afbClient->semaphore, 1, 0) == -1) {
fprintf(stderr, "LaunchCallRequest: Fail Semaphore Init: %s\n", afbClient->uri);
}
// Create a main loop
- err = sd_event_default(&afbClient->sdLoop);
+ err = sd_event_new(&afbClient->sdLoop);
if (err < 0) {
fprintf(stderr, "LaunchCallRequest: Connection to default event loop failed: %s\n", strerror(-err));
goto OnErrorExit;
@@ -338,7 +342,7 @@ static int LaunchCallRequest(afbClientT *afbClient, hookActionT action) {
}
case HOOK_CLOSE: {
-
+ if (afbClient->verbose) printf("HOOK_CLOSE Session=%s\n", afbClient->uid);
// If no request exit now
if (!afbClient->release) {
if (afbClient->verbose) printf("LaunchCallRequest:optional HOOK_CLOSE no release control call\n");
@@ -366,6 +370,38 @@ OnErrorExit:
return -1;
}
+static void AlsaHookClean (afbClientT *afbClient)
+{
+ free(afbClient->uid);
+ free(afbClient->name);
+ free(afbClient->uri);
+ if (afbClient->event) {
+ afbEventT **afbEvent=afbClient->event;
+ for (int index=0; afbEvent[index]!= NULL; index++) {
+ free(afbEvent[index]->search);
+ free(afbEvent[index]->value);
+ }
+ free(afbEvent);
+ }
+ if (afbClient->request) {
+ afbRequestT **afbRequest=afbClient->request;
+ for (int index=0; afbRequest[index]!= NULL; index++) {
+ free(afbRequest[index]->apiverb);
+ json_object_put(afbRequest[index]->queryJ);
+ }
+ free(afbRequest);
+ }
+ if (afbClient->release) {
+ afbRequestT **afbRelease=afbClient->release;
+ for (int index=0; afbRelease[index]!= NULL; index++) {
+ free(afbRelease[index]->apiverb);
+ json_object_put(afbRelease[index]->queryJ);
+ }
+ free(afbRelease);
+ }
+ free(afbClient);
+}
+
static int AlsaCloseHook(snd_pcm_hook_t *hook) {
afbClientT *afbClient = (afbClientT*) snd_pcm_hook_get_private (hook);
@@ -378,15 +414,30 @@ static int AlsaCloseHook(snd_pcm_hook_t *hook) {
}
// wait for all call request to return
- if (!afbClient->synchronous) sem_wait(&afbClient->semaphore);
if (afbClient->errcount) {
fprintf (stderr, "AlsaCloseHook: Notice exit before audio-4a response\n");
goto OnErrorExit;
}
- pthread_cancel(afbClient->tid);
+ // request main loop to terminate without signal
+ if (afbClient->verbose) printf("AlsaCloseHook: Start pthread_cancel request\n");
+ int s = pthread_cancel(afbClient->tid);
+ if (s != 0)
+ printf("AlsaCloseHook: ERROR on pthread_cancel err %d\n",s);
+
+ /* Join with thread to see what its exit status was */
+ void *res;
+ s = pthread_join(afbClient->tid, &res);
+ if (s != 0)
+ printf("AlsaCloseHook: ERROR on pthread_join err %d\n",s);
+
+ if (res == PTHREAD_CANCELED)
+ if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Close Success PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri);
+ else
+ printf("AlsaCloseHook: EventLoop thread failed to canceled (shouldn't happen!)\n");
+
+ AlsaHookClean(afbClient);
- if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Close Success PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri);
return 0;
OnErrorExit:
@@ -567,7 +618,7 @@ OnErrorExit:
int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
snd_pcm_hook_t *h_close = NULL;
snd_config_iterator_t it, next;
- afbClientT *afbClient = malloc(sizeof (afbClientT));
+ afbClientT *afbClient = calloc(1,sizeof (afbClientT));
int err;
// start populating client handle