From 6238c27ba5653583d76176ee178b357f80064e0e Mon Sep 17 00:00:00 2001 From: Pekka Pessi Date: Wed, 12 Jan 2011 21:24:09 +0200 Subject: [PATCH] gisi: remove before notify Just in case, remove pending operations before calling notifys. The notify function can remove client, service or modem. --- gisi/client.c | 6 +++--- gisi/modem.c | 69 ++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/gisi/client.c b/gisi/client.c index 03ed5de..85e1fa7 100644 --- a/gisi/client.c +++ b/gisi/client.c @@ -66,11 +66,11 @@ static void pending_resp_notify(const GIsiMessage *msg, void *data) if (pd == NULL) return; - if (pd->notify != NULL) - pd->notify(msg, pd->data); - pd->client->pending = g_slist_remove(pd->client->pending, g_isi_pending_from_msg(msg)); + + if (pd->notify != NULL) + pd->notify(msg, pd->data); } static void pending_notify(const GIsiMessage *msg, void *data) diff --git a/gisi/modem.c b/gisi/modem.c index 0682666..1655929 100644 --- a/gisi/modem.c +++ b/gisi/modem.c @@ -155,9 +155,41 @@ static void pending_dispatch(GIsiPending *pend, GIsiMessage *msg) g_isi_msg_resource(msg), g_isi_msg_id(msg), g_isi_msg_utid(msg)); + msg->private = pend; + pend->notify(msg, pend->data); } +static void pending_remove_and_dispatch(GIsiPending *op, GIsiMessage *msg) +{ + GIsiModem *modem; + + op->service->pending = g_slist_remove(op->service->pending, op); + + if (op->notify == NULL || msg == NULL) + goto destroy; + + modem = op->service->modem; + + ISIDBG(modem, "%s %s to %p [res=0x%02X, id=0x%02X, utid=0x%02X]", + g_isi_msg_strerror(msg), pend_type_to_str(op->type), op, + g_isi_msg_resource(msg), g_isi_msg_id(msg), + g_isi_msg_utid(msg)); + + msg->private = op; + + op->notify(msg, op->data); + +destroy: + if (op->timeout > 0) + g_source_remove(op->timeout); + + if (op->destroy != NULL) + op->destroy(op->data); + + g_free(op); +} + static void service_dispatch(GIsiServiceMux *mux, GIsiMessage *msg, gboolean is_indication) { @@ -169,7 +201,6 @@ static void service_dispatch(GIsiServiceMux *mux, GIsiMessage *msg, while (l != NULL) { GSList *next = l->next; GIsiPending *pend = l->data; - msg->private = pend; /* * REQs, NTFs and INDs are dispatched on message ID. While @@ -194,22 +225,16 @@ static void service_dispatch(GIsiServiceMux *mux, GIsiMessage *msg, } else if (pend->type == GISI_MESSAGE_TYPE_RESP && !is_indication && pend->utid == utid) { - pending_dispatch(pend, msg); - pend->notify = NULL; - - g_isi_pending_remove(pend); + pending_remove_and_dispatch(pend, msg); break; } else if (pend->type == GISI_MESSAGE_TYPE_COMMON && msgid == COMMON_MESSAGE && pend->msgid == COMM_ISI_VERSION_GET_REQ) { - pending_dispatch(pend, msg); - pend->notify = NULL; - - g_isi_pending_remove(pend); - + pending_remove_and_dispatch(pend, msg); } + l = next; } } @@ -634,16 +659,15 @@ static void vtrace(struct sockaddr_pn *dst, static gboolean resp_timeout(gpointer data) { - GIsiPending *resp = data; + GIsiPending *op = data; GIsiMessage msg = { .error = ETIMEDOUT, - .private = resp, }; - pending_dispatch(resp, &msg); - resp->notify = NULL; + op->timeout = 0; + + pending_remove_and_dispatch(op, &msg); - g_isi_pending_remove(resp); return FALSE; } @@ -755,8 +779,6 @@ void g_isi_pending_remove(GIsiPending *op) if (op == NULL) return; - op->service->pending = g_slist_remove(op->service->pending, op); - if (op->type == GISI_MESSAGE_TYPE_IND) service_subs_decr(op->service); @@ -766,12 +788,14 @@ void g_isi_pending_remove(GIsiPending *op) if (op->type == GISI_MESSAGE_TYPE_RESP && op->notify != NULL) { GIsiMessage msg = { .error = ESHUTDOWN, - .private = op, }; - op->notify(&msg, op->data); - op->notify = NULL; + + pending_remove_and_dispatch(op, &msg); + return; } + op->service->pending = g_slist_remove(op->service->pending, op); + pending_destroy(op, NULL); } @@ -1045,14 +1069,11 @@ static gboolean reachable_notify(gpointer data) }; GIsiMessage msg = { .version = &mux->version, - .private = pong, .addr = &addr, }; - pending_dispatch(pong, &msg); - pong->notify = NULL; + pending_remove_and_dispatch(pong, &msg); - g_isi_pending_remove(pong); return FALSE; } -- 2.7.4