summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gsmd/atcmd.h3
-rw-r--r--src/gsmd/atcmd.c27
-rw-r--r--src/gsmd/usock.c4
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)
personal git repositories of Harald Welte. Your mileage may vary