diff options
author | Pekka Pessi <Pekka.Pessi@nokia.com> | 2011-01-18 23:27:08 +0200 |
---|---|---|
committer | Aki Niemi <aki.niemi@nokia.com> | 2011-01-18 23:31:47 +0200 |
commit | e72e5444af1df26fbe6fa230a5bbc113704f1058 (patch) | |
tree | 8796b6492491ebb90b9cc5fa5143531d70a505d5 /gisi/modem.c | |
parent | fef6de49af4fc37649422275a4b686d528b8e535 (diff) | |
download | ofono-e72e5444af1df26fbe6fa230a5bbc113704f1058.tar.gz |
gisi: simplify pending management
Client or server mark their pending objects with
the function g_isi_pending_set_owner().
When client or server get destroyed or reset the pending objects are
removed with the function g_isi_remove_pending_by_owner(). As a client
or server always uses only a particular resource, all the pending
objects are conveniently stored into a single list.
Diffstat (limited to 'gisi/modem.c')
-rw-r--r-- | gisi/modem.c | 63 |
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) |