gmime r1454 - in trunk: . gmime
- From: fejj svn gnome org
- To: svn-commits-list gnome org
- Subject: gmime r1454 - in trunk: . gmime
- Date: Mon, 15 Sep 2008 03:50:41 +0000 (UTC)
Author: fejj
Date: Mon Sep 15 03:50:41 2008
New Revision: 1454
URL: http://svn.gnome.org/viewvc/gmime?rev=1454&view=rev
Log:
2008-09-15 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-message.c: Use the new InternetAddressList event
system.
* gmime/internet-address.c: Implemented a custom event system
which gains us another 20% performance improvement.
Modified:
trunk/ChangeLog
trunk/gmime/gmime-message.c
trunk/gmime/internet-address.c
trunk/gmime/internet-address.h
Modified: trunk/gmime/gmime-message.c
==============================================================================
--- trunk/gmime/gmime-message.c (original)
+++ trunk/gmime/gmime-message.c Mon Sep 15 03:50:41 2008
@@ -45,6 +45,15 @@
* A #GMimeMessage represents an rfc822 message.
**/
+
+typedef void (* EventCallback) (gpointer sender, gpointer args);
+
+void _internet_address_list_block_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
+void _internet_address_list_unblock_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
+void _internet_address_list_add_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
+void _internet_address_list_remove_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
+
+
static void g_mime_message_class_init (GMimeMessageClass *klass);
static void g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass);
static void g_mime_message_finalize (GObject *object);
@@ -73,11 +82,11 @@
static struct {
const char *name;
- GCallback changed_cb;
+ EventCallback changed_cb;
} recipient_types[] = {
- { "To", G_CALLBACK (to_list_changed) },
- { "Cc", G_CALLBACK (cc_list_changed) },
- { "Bcc", G_CALLBACK (bcc_list_changed) }
+ { "To", (EventCallback) to_list_changed },
+ { "Cc", (EventCallback) cc_list_changed },
+ { "Bcc", (EventCallback) bcc_list_changed }
};
#define N_RECIPIENT_TYPES G_N_ELEMENTS (recipient_types)
@@ -139,19 +148,6 @@
object_class->write_to_stream = message_write_to_stream;
}
-static gulong
-lookup_recipient_changed_id (GMimeMessage *message, GMimeRecipientType type)
-{
- InternetAddressList *list;
- GCallback changed_cb;
-
- changed_cb = recipient_types[type].changed_cb;
- list = message->recipients[type];
-
- return g_signal_handler_find (list, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, changed_cb, message);
-}
-
static void
connect_changed_event (GMimeMessage *message, GMimeRecipientType type)
{
@@ -159,40 +155,37 @@
list = message->recipients[type];
- g_signal_connect (list, "changed", recipient_types[type].changed_cb, message);
+ _internet_address_list_add_event_handler (list, recipient_types[type].changed_cb, message);
}
static void
disconnect_changed_event (GMimeMessage *message, GMimeRecipientType type)
{
InternetAddressList *list;
- gulong id;
list = message->recipients[type];
- id = lookup_recipient_changed_id (message, type);
- g_signal_handler_disconnect (list, id);
+
+ _internet_address_list_remove_event_handler (list, recipient_types[type].changed_cb, message);
}
static void
block_changed_event (GMimeMessage *message, GMimeRecipientType type)
{
InternetAddressList *list;
- gulong id;
list = message->recipients[type];
- id = lookup_recipient_changed_id (message, type);
- g_signal_handler_block (list, id);
+
+ _internet_address_list_block_event_handler (list, recipient_types[type].changed_cb, message);
}
static void
unblock_changed_event (GMimeMessage *message, GMimeRecipientType type)
{
InternetAddressList *list;
- gulong id;
list = message->recipients[type];
- id = lookup_recipient_changed_id (message, type);
- g_signal_handler_unblock (list, id);
+
+ _internet_address_list_block_event_handler (list, recipient_types[type].changed_cb, message);
}
static void
Modified: trunk/gmime/internet-address.c
==============================================================================
--- trunk/gmime/internet-address.c (original)
+++ trunk/gmime/internet-address.c Mon Sep 15 03:50:41 2008
@@ -33,6 +33,7 @@
#include "gmime-parse-utils.h"
#include "gmime-iconv-utils.h"
#include "gmime-utils.h"
+#include "list.h"
#ifdef ENABLE_WARNINGS
@@ -62,13 +63,130 @@
INTERNET_ADDRESS_FOLD = 1 << 1,
};
-enum {
- CHANGED,
- LAST_SIGNAL
-};
-static guint address_signals[LAST_SIGNAL] = { 0 };
-static guint list_signals[LAST_SIGNAL] = { 0 };
+typedef void (* EventCallback) (gpointer sender, gpointer args);
+
+typedef struct _EventListener {
+ struct _EventListener *next;
+ struct _EventListener *prev;
+ EventCallback callback;
+ gpointer user_data;
+ int blocked;
+} EventListener;
+
+static EventListener *
+event_listener_new (EventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ listener = g_slice_new (EventListener);
+ listener->user_data = user_data;
+ listener->callback = callback;
+ listener->prev = NULL;
+ listener->next = NULL;
+ listener->blocked = 0;
+
+ return listener;
+}
+
+static void
+event_listener_free (EventListener *listener)
+{
+ g_slice_free (EventListener, listener);
+}
+
+
+static List *
+event_list_new (void)
+{
+ List *list;
+
+ list = g_slice_new (List);
+ list_init (list);
+
+ return list;
+}
+
+static void
+event_list_free (List *list)
+{
+ EventListener *node, *next;
+
+ node = (EventListener *) list->head;
+ while (node->next) {
+ next = node->next;
+ event_listener_free (node);
+ node = next;
+ }
+
+ g_slice_free (List, list);
+}
+
+static EventListener *
+event_list_find_listener (List *list, EventCallback callback, gpointer user_data)
+{
+ EventListener *node, *next;
+
+ node = (EventListener *) list->head;
+ while (node->next) {
+ if (node->callback == callback && node->user_data == user_data)
+ return node;
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+static void
+event_list_block (List *list, EventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = event_list_find_listener (list, callback, user_data)))
+ listener->blocked++;
+}
+
+static void
+event_list_unblock (List *list, EventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = event_list_find_listener (list, callback, user_data)))
+ listener->blocked--;
+}
+
+static void
+event_list_add (List *list, EventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ listener = event_listener_new (callback, user_data);
+ list_append (list, (ListNode *) listener);
+}
+
+static void
+event_list_remove (List *list, EventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = event_list_find_listener (list, callback, user_data))) {
+ list_unlink ((ListNode *) listener);
+ event_listener_free (listener);
+ }
+}
+
+static void
+event_list_emit (List *list, gpointer sender)
+{
+ EventListener *node;
+
+ node = (EventListener *) list->head;
+ while (node->next) {
+ if (node->blocked <= 0)
+ node->callback (sender, node->user_data);
+ node = node->next;
+ }
+}
static void internet_address_class_init (InternetAddressClass *klass);
@@ -115,22 +233,12 @@
object_class->finalize = internet_address_finalize;
klass->to_string = NULL;
-
- /* signals */
- address_signals[CHANGED] =
- g_signal_new ("changed",
- INTERNET_ADDRESS_TYPE,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
internet_address_init (InternetAddress *ia, InternetAddressClass *klass)
{
+ ia->priv = event_list_new ();
ia->name = NULL;
}
@@ -139,6 +247,7 @@
{
InternetAddress *ia = (InternetAddress *) object;
+ event_list_free (ia->priv);
g_free (ia->name);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -175,7 +284,7 @@
_internet_address_set_name (ia, name);
- g_signal_emit (ia, address_signals[CHANGED], 0);
+ event_list_emit (ia->priv, ia);
}
@@ -335,7 +444,7 @@
g_free (mailbox->addr);
mailbox->addr = g_strdup (addr);
- g_signal_emit (mailbox, address_signals[CHANGED], 0);
+ event_list_emit (((InternetAddress *) mailbox)->priv, mailbox);
}
@@ -407,7 +516,7 @@
static void
members_changed (InternetAddressList *members, InternetAddress *group)
{
- g_signal_emit (group, address_signals[CHANGED], 0);
+ event_list_emit (((InternetAddress *) group)->priv, group);
}
static void
@@ -415,7 +524,7 @@
{
group->members = internet_address_list_new ();
- g_signal_connect (group->members, "changed", G_CALLBACK (members_changed), group);
+ event_list_add (group->members->priv, (EventCallback) members_changed, group);
}
static void
@@ -423,9 +532,7 @@
{
InternetAddressGroup *group = (InternetAddressGroup *) object;
- g_signal_handlers_disconnect_matched (group->members, MATCH_ID_FUNC_DATA,
- list_signals[CHANGED], 0, NULL,
- G_CALLBACK (members_changed), group);
+ event_list_remove (group->members->priv, (EventCallback) members_changed, group);
g_object_unref (group->members);
@@ -471,21 +578,18 @@
return;
if (group->members) {
- g_signal_handlers_disconnect_matched (group->members, MATCH_ID_FUNC_DATA,
- list_signals[CHANGED], 0, NULL,
- G_CALLBACK (members_changed), group);
-
+ event_list_remove (group->members->priv, (EventCallback) members_changed, group);
g_object_unref (group->members);
}
if (members) {
- g_signal_connect (members, "changed", G_CALLBACK (members_changed), group);
+ event_list_add (group->members->priv, (EventCallback) members_changed, group);
g_object_ref (members);
}
group->members = members;
- g_signal_emit (group, address_signals[CHANGED], 0);
+ event_list_emit (((InternetAddress *) group)->priv, group);
}
@@ -569,29 +673,19 @@
list_parent_class = g_type_class_ref (G_TYPE_OBJECT);
object_class->finalize = internet_address_list_finalize;
-
- /* signals */
- list_signals[CHANGED] =
- g_signal_new ("changed",
- INTERNET_ADDRESS_LIST_TYPE,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
internet_address_list_init (InternetAddressList *list, InternetAddressListClass *klass)
{
+ list->priv = event_list_new ();
list->array = g_ptr_array_new ();
}
static void
address_changed (InternetAddress *ia, InternetAddressList *list)
{
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
static void
@@ -603,14 +697,12 @@
for (i = 0; i < list->array->len; i++) {
ia = (InternetAddress *) list->array->pdata[i];
-
- g_signal_handlers_disconnect_matched (ia, MATCH_ID_FUNC_DATA,
- address_signals[CHANGED], 0, NULL,
- G_CALLBACK (address_changed), list);
-
+ event_list_remove (ia->priv, (EventCallback) address_changed, list);
g_object_unref (ia);
}
+ event_list_free (list->priv);
+
g_ptr_array_free (list->array, TRUE);
G_OBJECT_CLASS (list_parent_class)->finalize (object);
@@ -664,17 +756,13 @@
for (i = 0; i < list->array->len; i++) {
ia = (InternetAddress *) list->array->pdata[i];
-
- g_signal_handlers_disconnect_matched (ia, MATCH_ID_FUNC_DATA,
- address_signals[CHANGED], 0, NULL,
- G_CALLBACK (address_changed), list);
-
+ event_list_remove (ia->priv, (EventCallback) address_changed, list);
g_object_unref (ia);
}
g_ptr_array_set_size (list->array, 0);
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
@@ -683,7 +771,7 @@
{
int index;
- g_signal_connect (ia, "changed", G_CALLBACK (address_changed), list);
+ event_list_add (ia->priv, (EventCallback) address_changed, list);
index = list->array->len;
g_ptr_array_add (list->array, ia);
@@ -712,7 +800,7 @@
index = _internet_address_list_add (list, ia);
g_object_ref (ia);
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
return index;
}
@@ -748,12 +836,12 @@
for (i = 0; i < prepend->array->len; i++) {
ia = (InternetAddress *) prepend->array->pdata[i];
- g_signal_connect (ia, "changed", G_CALLBACK (address_changed), list);
+ event_list_add (ia->priv, (EventCallback) address_changed, list);
list->array->pdata[i] = ia;
g_object_ref (ia);
}
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
@@ -778,12 +866,12 @@
for (i = 0; i < append->array->len; i++) {
ia = (InternetAddress *) append->array->pdata[i];
- g_signal_connect (ia, "changed", G_CALLBACK (address_changed), list);
+ event_list_add (ia->priv, (EventCallback) address_changed, list);
list->array->pdata[len + i] = ia;
g_object_ref (ia);
}
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
@@ -806,7 +894,7 @@
g_return_if_fail (IS_INTERNET_ADDRESS (ia));
g_return_if_fail (index >= 0);
- g_signal_connect (ia, "changed", G_CALLBACK (address_changed), list);
+ event_list_add (ia->priv, (EventCallback) address_changed, list);
g_object_ref (ia);
if ((guint) index < list->array->len) {
@@ -823,7 +911,7 @@
g_ptr_array_add (list->array, ia);
}
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
@@ -877,14 +965,12 @@
return FALSE;
ia = list->array->pdata[index];
- g_signal_handlers_disconnect_matched (ia, MATCH_ID_FUNC_DATA,
- address_signals[CHANGED], 0, NULL,
- G_CALLBACK (address_changed), list);
+ event_list_remove (ia->priv, (EventCallback) address_changed, list);
g_object_unref (ia);
g_ptr_array_remove_index (list->array, index);
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
return TRUE;
}
@@ -988,16 +1074,14 @@
if ((old = list->array->pdata[index]) == ia)
return;
- g_signal_handlers_disconnect_matched (old, MATCH_ID_FUNC_DATA,
- address_signals[CHANGED], 0, NULL,
- G_CALLBACK (address_changed), list);
+ event_list_remove (old->priv, (EventCallback) address_changed, list);
g_object_unref (old);
- g_signal_connect (ia, "changed", G_CALLBACK (address_changed), list);
+ event_list_add (ia->priv, (EventCallback) address_changed, list);
list->array->pdata[index] = ia;
g_object_ref (ia);
- g_signal_emit (list, list_signals[CHANGED], 0);
+ event_list_emit (list->priv, list);
}
@@ -1525,3 +1609,31 @@
return addrlist;
}
+
+
+void
+_internet_address_list_block_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
+{
+ event_list_block (list->priv, callback, user_data);
+}
+
+
+void
+_internet_address_list_unblock_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
+{
+ event_list_unblock (list->priv, callback, user_data);
+}
+
+
+void
+_internet_address_list_add_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
+{
+ event_list_add (list->priv, callback, user_data);
+}
+
+
+void
+_internet_address_list_remove_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
+{
+ event_list_remove (list->priv, callback, user_data);
+}
Modified: trunk/gmime/internet-address.h
==============================================================================
--- trunk/gmime/internet-address.h (original)
+++ trunk/gmime/internet-address.h Mon Sep 15 03:50:41 2008
@@ -69,12 +69,14 @@
/**
* InternetAddress:
* @parent_object: parent #GObject
+ * @priv: private data
* @name: display name
*
* An RFC 2822 Address object.
**/
struct _InternetAddress {
GObject parent_object;
+ gpointer priv;
char *name;
};
@@ -154,12 +156,14 @@
/**
* InternetAddressList:
* @parent_object: parent #GObject
+ * @priv: private data
* @array: The array of #InternetAddress objects.
*
* A collection of #InternetAddress objects.
**/
struct _InternetAddressList {
GObject parent_object;
+ gpointer priv;
GPtrArray *array;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]