Improve UI responsiveness + experimental [PATCH]
- From: Emmanuel <e allaud wanadoo fr>
- To: ML de Balsa <balsa-list gnome org>
- Subject: Improve UI responsiveness + experimental [PATCH]
- Date: Tue, 16 Apr 2002 15:49:05 +0200
Hi all,
here is a suggestion that improves UI responsiveness of Balsa A LOT (I'be
tried that on my laptop, and it's really far better). Basically it consist
of tracking all places in balsa sources where we hold the gdk_lock for
long operations, and place a gdk_threads_leave(); before the long op and a
gdk_threeads_enter() after. This can be done extensively but with care to
avoid deadlocks. Moreover it will enable testing the MT more aggressively
and perhaps will lead to bad locking discovery.
Good examples are all mutt calls within libbalsa funcs (these are always
called with gdk lock held). These are generally long (like
mx_open_mailbox,mx_check_mailbox and others) and AFAIK does not make call
to gtk so it's safe to drop the gdk lock before calling them. The next
step would be to improve the threading code. I guess that we should do the
threading on an auxiliary structure (a glib tree) and the export it as a
gtkctree (and I hope all these things will go away with 2.0 port).
Here is also a very experimental patch that does the threading without
clearing the index the reloads it to have a "fresh" index before threading
("fresh" means a flat index). You'll also see a lot of
gdk_threads_leave/enter() calls. This is the more experimental part, it
should perhaps not be enabled to begin.
This is beta work (and I'm optimist ;-), but if someone has more time than
me nowadays I hope this could be the base for better perf of balsa
threading.
Bye
Manu
--- balsa/src/balsa-index-threading.c Tue Apr 16 10:00:49 2002
+++ balsa-new/src/balsa-index-threading.c Sun Mar 31 18:18:32 2002
@@ -72,10 +72,12 @@
GHashTable* msg_table);
static void dump(GNode *node, int indent);
+static void flatten(GtkCTree * ctree,GtkCTreeNode * parent);
void
balsa_index_threading(BalsaIndex* bindex)
{
+ flatten(bindex->ctree,NULL);
switch (bindex->threading_type){
case BALSA_INDEX_THREADING_SIMPLE:
threading_simple(bindex);
@@ -106,15 +108,17 @@
(GtkCTreeFunc)gen_container,
(gpointer)id_table);
+ gdk_threads_leave();
g_hash_table_foreach(id_table,
(GHFunc)find_root_set,
&root_set);
-
+ gdk_threads_enter();
balsa_window_setup_progress(BALSA_WINDOW(bindex->window),
g_slist_length(root_set)*3);
foo=root_set;
while(foo) {
+ gdk_threads_leave();
g_node_traverse(foo->data,
/*G_PRE_ORDER,*/
G_POST_ORDER,
@@ -123,9 +127,10 @@
(GNodeTraverseFunc)prune,
root_set);
foo=g_slist_next(foo);
+ gdk_threads_enter();
balsa_window_increment_progress(BALSA_WINDOW(bindex->window));
}
-
+ gdk_threads_leave();
subject_table = g_hash_table_new(g_str_hash, g_str_equal);
g_slist_foreach(root_set, (GFunc)subject_gather, subject_table);
@@ -135,9 +140,12 @@
if(foo->data!=NULL)
subject_merge(foo->data, subject_table, root_set, &save_node);
foo=g_slist_next(foo);
+ gdk_threads_enter();
balsa_window_increment_progress(BALSA_WINDOW(bindex->window));
+ gdk_threads_leave();
}
+ gdk_threads_enter();
foo = root_set;
while(foo) {
if(foo->data!=NULL)
@@ -164,12 +172,14 @@
g_slist_free(save_node);
balsa_window_clear_progress(BALSA_WINDOW(bindex->window));
+ gdk_threads_leave();
g_hash_table_destroy(subject_table);
g_hash_table_foreach(id_table, (GHFunc)free_node, NULL);
g_hash_table_destroy(id_table);
if(root_set!=NULL)
g_slist_free(root_set);
+ gdk_threads_enter();
}
static void
@@ -931,4 +941,32 @@
foo=g_hash_table_lookup(msg_table, message->message_id);
if(foo==NULL)
g_hash_table_insert(msg_table, message->message_id, node);
+}
+
+/* Just puts all nodes in rows, ie break all the hierarchy down
+ to a simple list.
+ Should be called with node==NULL */
+
+static void flatten(GtkCTree * ctree,GtkCTreeNode * parent)
+{
+ GtkCTreeNode * current;
+ static depth=0;
+
+ if (!parent) {
+ for (current=gtk_ctree_node_nth(ctree,1);current;current=GTK_CTREE_ROW(current)->sibling)
+ if (GTK_CTREE_ROW(current)->children)
+ flatten(ctree,current);
+ return;
+ }
+
+ depth++;
+ for (;current = GTK_CTREE_ROW(parent)->children;) {
+ while (GTK_CTREE_ROW(current)->children) {
+ /* if current node has children, just move them before we can
+ move current */
+ flatten(ctree,current);
+ }
+ /* OK now current is a leaf, just move it to the top */
+ gtk_ctree_move(ctree,current,NULL,NULL);
+ }
}
--- balsa/src/balsa-index.c Tue Apr 16 10:00:49 2002
+++ balsa-new/src/balsa-index.c Mon Apr 1 21:57:46 2002
@@ -690,7 +690,7 @@
default setting
*/
mbnode->threading_type = balsa_app.threading_type;
- balsa_index_set_threading_type(bindex, mbnode->threading_type);
+ balsa_index_set_threading_type(bindex, mbnode->threading_type,TRUE);
balsa_index_set_first_new_message(bindex);
gtk_idle_add((GtkFunction) moveto_handler, bindex);
@@ -2363,7 +2401,7 @@
recreated. This should not be necessary.
*/
void
-balsa_index_set_threading_type(BalsaIndex * bindex, int thtype)
+balsa_index_set_threading_type(BalsaIndex * bindex, int thtype,gboolean fill)
{
GList *list;
LibBalsaMailbox* mailbox = NULL;
@@ -2385,10 +2423,13 @@
mailbox = bindex->mailbox_node->mailbox;
gtk_clist_freeze(clist);
- gtk_clist_clear(clist);
+ if (fill) {
+ g_print("Filling Index\n");
+ gtk_clist_clear(clist);
- for (list = mailbox->message_list; list; list = list->next)
- balsa_index_add(bindex, LIBBALSA_MESSAGE(list->data));
+ for (list = mailbox->message_list; list; list = list->next)
+ balsa_index_add(bindex, LIBBALSA_MESSAGE(list->data));
+ }
/* do threading */
balsa_index_threading(bindex);
--- balsa/src/balsa-index.h Tue Apr 16 10:00:49 2002
+++ balsa-new/src/balsa-index.h Sat Mar 30 22:40:56 2002
@@ -80,7 +80,7 @@
BalsaMailboxNode * mbnode);
void balsa_index_refresh(BalsaIndex * bindex);
void balsa_index_update_tree(BalsaIndex *bindex, gboolean expand);
- void balsa_index_set_threading_type(BalsaIndex * bindex, int thtype);
+ void balsa_index_set_threading_type(BalsaIndex * bindex, int thtype,gboolean fill);
void balsa_index_set_sort_order(BalsaIndex * bindex, int column,
GtkSortType order);
void balsa_index_set_first_new_message(BalsaIndex * bindex);
--- balsa/src/main-window.c Tue Apr 16 10:00:50 2002
+++ balsa-new/src/main-window.c Sat Mar 30 15:48:17 2002
@@ -2444,7 +2458,7 @@
BALSA_MAILBOX_NODE(gnode->data)->threading_type =
BALSA_INDEX_THREADING_FLAT;
balsa_index_set_threading_type(BALSA_INDEX(index),
- BALSA_INDEX_THREADING_FLAT);
+ BALSA_INDEX_THREADING_FLAT,FALSE);
}
static void
@@ -2462,7 +2476,7 @@
BALSA_MAILBOX_NODE(gnode->data)->threading_type =
BALSA_INDEX_THREADING_SIMPLE;
balsa_index_set_threading_type(BALSA_INDEX(index),
- BALSA_INDEX_THREADING_SIMPLE);
+ BALSA_INDEX_THREADING_SIMPLE,FALSE);
}
static void
@@ -2480,7 +2494,7 @@
BALSA_MAILBOX_NODE(gnode->data)->threading_type =
BALSA_INDEX_THREADING_JWZ;
balsa_index_set_threading_type(BALSA_INDEX(index),
- BALSA_INDEX_THREADING_JWZ);
+ BALSA_INDEX_THREADING_JWZ,FALSE);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]