From 628d612ceaff0753a49ae79ee39b2b396d41fdcc Mon Sep 17 00:00:00 2001 From: Ronan Le Martret Date: Wed, 27 Dec 2017 15:11:40 +0000 Subject: 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 --- alsa-hook/PolicyAlsaHook.c | 81 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 15 deletions(-) (limited to 'alsa-hook') 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 -- cgit 1.2.3-korg