summaryrefslogtreecommitdiffstats
path: root/gisi/modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'gisi/modem.c')
-rw-r--r--gisi/modem.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/gisi/modem.c b/gisi/modem.c
index 1655929e..f80d671d 100644
--- a/gisi/modem.c
+++ b/gisi/modem.c
@@ -73,6 +73,7 @@ struct _GIsiModem {
struct _GIsiPending {
enum GIsiMessageType type;
GIsiServiceMux *service;
+ gpointer owner;
guint timeout;
GIsiNotifyFunc notify;
GDestroyNotify destroy;
@@ -799,6 +800,68 @@ void g_isi_pending_remove(GIsiPending *op)
pending_destroy(op, NULL);
}
+static void foreach_destroy(GIsiPending *op)
+{
+ if (op->type == GISI_MESSAGE_TYPE_IND)
+ service_subs_decr(op->service);
+
+ if (op->type == GISI_MESSAGE_TYPE_REQ)
+ service_regs_decr(op->service);
+
+ if (op->type == GISI_MESSAGE_TYPE_RESP && op->notify != NULL) {
+ GIsiMessage msg = {
+ .error = ESHUTDOWN,
+ };
+
+ pending_dispatch(op, &msg);
+ }
+
+ pending_destroy(op, NULL);
+}
+
+void g_isi_pending_set_owner(GIsiPending *op, gpointer owner)
+{
+ if (op == NULL)
+ return;
+
+ op->owner = owner;
+}
+
+void g_isi_remove_pending_by_owner(GIsiModem *modem, uint8_t resource,
+ gpointer owner)
+{
+ GIsiServiceMux *mux;
+ GSList *l;
+ GSList *next;
+ GIsiPending *op;
+ GSList *owned = NULL;
+
+ mux = service_get(modem, resource);
+ if (mux == NULL)
+ return;
+
+ for (l = mux->pending; l != NULL; l = next) {
+ next = l->next;
+ op = l->data;
+
+ if (op->owner != owner)
+ continue;
+
+ mux->pending = g_slist_remove_link(mux->pending, l);
+
+ l->next = owned;
+ owned = l;
+ }
+
+ for (l = owned; l != NULL; l = l->next) {
+ op = l->data;
+
+ foreach_destroy(op);
+ }
+
+ g_slist_free(owned);
+}
+
GIsiPending *g_isi_ntf_subscribe(GIsiModem *modem, uint8_t resource,
uint8_t msgid, GIsiNotifyFunc notify,
void *data, GDestroyNotify destroy)