summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gatchat/gatchat.c110
1 files changed, 64 insertions, 46 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
index cfe21887..e69cd4e2 100644
--- a/gatchat/gatchat.c
+++ b/gatchat/gatchat.c
@@ -63,6 +63,9 @@ struct at_notify_node {
GDestroyNotify notify;
};
+typedef gboolean (*node_remove_func)(struct at_notify_node *node,
+ gpointer user_data);
+
struct at_notify {
GSList *nodes;
gboolean pdu;
@@ -154,6 +157,57 @@ static gint at_command_compare_by_id(gconstpointer a, gconstpointer b)
return 0;
}
+static gboolean at_chat_unregister_all(struct at_chat *chat,
+ node_remove_func func,
+ gpointer userdata)
+{
+ GHashTableIter iter;
+ struct at_notify *notify;
+ struct at_notify_node *node;
+ gpointer key, value;
+ GSList *p;
+ GSList *c;
+ GSList *t;
+
+ if (chat->notify_list == NULL)
+ return FALSE;
+
+ g_hash_table_iter_init(&iter, chat->notify_list);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ notify = value;
+
+ p = NULL;
+ c = notify->nodes;
+
+ while (c) {
+ node = c->data;
+
+ if (func(node, userdata) != TRUE) {
+ p = c;
+ c = c->next;
+ continue;
+ }
+
+ if (p)
+ p->next = c->next;
+ else
+ notify->nodes = c->next;
+
+ at_notify_node_destroy(node, NULL);
+
+ t = c;
+ c = c->next;
+ g_slist_free_1(t);
+ }
+
+ if (notify->nodes == NULL)
+ g_hash_table_iter_remove(&iter);
+ }
+
+ return TRUE;
+}
+
static struct at_command *at_command_create(guint gid, const char *cmd,
const char **prefix_list,
gboolean expect_pdu,
@@ -1099,53 +1153,15 @@ static gboolean at_chat_unregister(struct at_chat *chat, guint group, guint id)
return FALSE;
}
-static gboolean at_chat_unregister_group(struct at_chat *chat, guint group)
+static gboolean node_compare_by_group(struct at_notify_node *node,
+ gpointer userdata)
{
- GHashTableIter iter;
- struct at_notify *notify;
- struct at_notify_node *node;
- gpointer key, value;
- GSList *p;
- GSList *c;
- GSList *t;
-
- if (chat->notify_list == NULL)
- return FALSE;
-
- g_hash_table_iter_init(&iter, chat->notify_list);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- notify = value;
-
- p = NULL;
- c = notify->nodes;
-
- while (c) {
- node = c->data;
+ guint group = GPOINTER_TO_UINT(userdata);
- if (node->gid != group) {
- p = c;
- c = c->next;
- continue;
- }
-
- if (p)
- p->next = c->next;
- else
- notify->nodes = c->next;
-
- at_notify_node_destroy(node, NULL);
-
- t = c;
- c = c->next;
- g_slist_free_1(t);
- }
-
- if (notify->nodes == NULL)
- g_hash_table_iter_remove(&iter);
- }
+ if (node->gid == group)
+ return TRUE;
- return TRUE;
+ return FALSE;
}
static struct at_chat *create_chat(GIOChannel *channel, GIOFlags flags,
@@ -1310,7 +1326,7 @@ void g_at_chat_unref(GAtChat *chat)
return;
at_chat_cancel_group(chat->parent, chat->group);
- at_chat_unregister_group(chat->parent, chat->group);
+ g_at_chat_unregister_all(chat);
at_chat_unref(chat->parent);
g_free(chat);
@@ -1431,5 +1447,7 @@ gboolean g_at_chat_unregister_all(GAtChat *chat)
if (chat == NULL)
return FALSE;
- return at_chat_unregister_group(chat->parent, chat->group);
+ return at_chat_unregister_all(chat->parent,
+ node_compare_by_group,
+ GUINT_TO_POINTER(chat->group));
}