From: Pekka Pessi pekka.pe...@nokia.com
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 | 71 +
2 files changed, 49 insertions(+), 28 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..14827d8 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
@@ -192,24 +223,18 @@ static void service_dispatch(GIsiServiceMux *mux,
GIsiMessage *msg,
pending_dispatch(pend, msg);
} else if (pend-type == GISI_MESSAGE_TYPE_RESP
- !is_indication pend-utid == utid) {
+!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