diff options
-rw-r--r-- | include/gsmd/atcmd.h | 3 | ||||
-rw-r--r-- | src/gsmd/atcmd.c | 27 | ||||
-rw-r--r-- | src/gsmd/usock.c | 4 |
3 files changed, 32 insertions, 2 deletions
diff --git a/include/gsmd/atcmd.h b/include/gsmd/atcmd.h index e328934..60bca8e 100644 --- a/include/gsmd/atcmd.h +++ b/include/gsmd/atcmd.h @@ -13,8 +13,9 @@ extern int atcmd_submit(struct gsmd *g, struct gsmd_atcmd *cmd); extern int cancel_atcmd(struct gsmd *g, struct gsmd_atcmd *cmd); extern int atcmd_init(struct gsmd *g, int sockfd); extern void atcmd_drain(int fd); +extern int atcmd_terminate_matching(struct gsmd *g, void *ctx); extern void atcmd_wake_pending_queue (struct gsmd *g); -extern void atcmd_wait_pending_queue (struct gsmd *g); +extern void atcmd_wait_pending_queue (struct gsmd *g); #endif /* __GSMD__ */ diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index 747000b..2b5825a 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -719,3 +719,30 @@ int atcmd_init(struct gsmd *g, int sockfd) return gsmd_register_fd(&g->gfd_uart); } + +/* remove from the queues any command whose .ctx matches given */ +int atcmd_terminate_matching(struct gsmd *g, void *ctx) +{ + int num = 0; + struct gsmd_atcmd *cmd, *pos; + + llist_for_each_entry_safe(cmd, pos, &g->busy_atcmds, list) + if (cmd->ctx == ctx) { + cmd->ret = -ESHUTDOWN; + cmd->cb(cmd, cmd->ctx, "ERROR"); + cmd->cb = NULL; + cmd->ctx = NULL; + num ++; + } + + llist_for_each_entry_safe(cmd, pos, &g->pending_atcmds, list) + if (cmd->ctx == ctx) { + llist_del(&cmd->list); + cmd->ret = -ESHUTDOWN; + cmd->cb(cmd, cmd->ctx, "ERROR"); + talloc_free(cmd); + num ++; + } + + return num; +} diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 6b29125..3dc74d3 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -1205,9 +1205,11 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data) /* EOF, this client has just vanished */ gsmd_unregister_fd(&gu->gfd); close(fd); + /* finish pending atcmd's from this client thus + * destroying references to the user structure. */ + atcmd_terminate_matching(gu->gsmd, gu); /* destroy whole user structure */ llist_del(&gu->list); - /* FIXME: delete busy ucmds from finished_ucmds */ talloc_free(gu); return 0; } else if (rcvlen < 0) |