[balsa/gtk3] Revert changes moving Gtk access to main thread
- From: Peter Bloomfield <PeterB src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/gtk3] Revert changes moving Gtk access to main thread
- Date: Tue, 18 Sep 2012 01:03:23 +0000 (UTC)
commit e3de8ec07dde3ab1a7625c99c10dffaa6e95ce79
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Mon Sep 17 20:43:56 2012 -0400
Revert changes moving Gtk access to main thread
Revert all changes moving Gtk access from subthreads to main
thread.
ChangeLog | 18 ++++
libbalsa/libbalsa.c | 3 -
libbalsa/mailbox.c | 248 +++++-----------------------------------------
libbalsa/mailbox_local.c | 5 +
src/balsa-app.c | 87 +---------------
src/balsa-index.c | 153 +++++++++--------------------
src/balsa-index.h | 6 +-
src/main-window.c | 129 ++++++++++++++++++++----
src/main.c | 79 +--------------
9 files changed, 218 insertions(+), 510 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 62733a6..47788e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2012-09-17 Peter Bloomfield
+
+ Revert all changes moving Gtk access from subthreads to main
+ thread.
+
+ * libbalsa/libbalsa.c (libbalsa_threads_enter):
+ * libbalsa/mailbox.c (lbm_index_entry_new_from_msg),
+ (libbalsa_mailbox_close), (libbalsa_mailbox_msgno_inserted),
+ (libbalsa_mailbox_msgno_removed),
+ (libbalsa_mailbox_msgno_filt_check), (lbm_cache_message):
+ * libbalsa/mailbox_local.c (libbalsa_mailbox_local_load_messages):
+ * src/balsa-app.c (find_url), (balsa_find_url):
+ * src/balsa-index.c (balsa_index_load_mailbox_node):
+ * src/balsa-index.h:
+ * src/main-window.c:
+ * src/main.c (balsa_progress_set_text),
+ (balsa_progress_set_fraction):
+
2012-09-08 Peter Bloomfield
* configure.in: _NL_MEASUREMENT_MEASUREMENT is an enum and not
diff --git a/libbalsa/libbalsa.c b/libbalsa/libbalsa.c
index 4a090b9..0407cc4 100644
--- a/libbalsa/libbalsa.c
+++ b/libbalsa/libbalsa.c
@@ -761,9 +761,6 @@ libbalsa_threads_enter(void)
self = pthread_self();
- if (libbalsa_am_i_subthread())
- g_warning("Locking a subthread");
-
if (self != libbalsa_threads_id) {
pthread_mutex_lock(&libbalsa_threads_mutex);
libbalsa_threads_id = self;
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index 4186c1e..870a2c3 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -367,6 +367,14 @@ lbm_index_entry_populate_from_msg(LibBalsaMailboxIndexEntry * entry,
libbalsa_mailbox_msgno_changed(msg->mailbox, msg->msgno);
}
+static LibBalsaMailboxIndexEntry*
+lbm_index_entry_new_from_msg(LibBalsaMessage *msg)
+{
+ LibBalsaMailboxIndexEntry *entry = g_new(LibBalsaMailboxIndexEntry,1);
+ lbm_index_entry_populate_from_msg(entry, msg);
+ return entry;
+}
+
#ifdef BALSA_USE_THREADS
static LibBalsaMailboxIndexEntry*
lbm_index_entry_new_pending(void)
@@ -643,10 +651,12 @@ libbalsa_mailbox_close(LibBalsaMailbox * mailbox, gboolean expunge)
/* do not try expunging read-only mailboxes, it's a waste of time */
expunge = expunge && !mailbox->readonly;
LIBBALSA_MAILBOX_GET_CLASS(mailbox)->close_mailbox(mailbox, expunge);
+ gdk_threads_enter();
if(mailbox->msg_tree) {
g_node_destroy(mailbox->msg_tree);
mailbox->msg_tree = NULL;
}
+ gdk_threads_leave();
libbalsa_mailbox_free_mindex(mailbox);
mailbox->stamp++;
mailbox->state = LB_MAILBOX_STATE_CLOSED;
@@ -1339,21 +1349,18 @@ libbalsa_mailbox_msgno_changed(LibBalsaMailbox * mailbox, guint seqno)
gdk_threads_leave();
}
-static void
-lbm_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno, GNode * parent,
- GNode ** sibling)
+void
+libbalsa_mailbox_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno,
+ GNode * parent, GNode ** sibling)
{
GtkTreeIter iter;
GtkTreePath *path;
GSList **unthreaded;
- gdk_threads_enter();
-
- if (!mailbox->msg_tree) {
- gdk_threads_leave();
+ if (!libbalsa_threads_has_lock())
+ g_warning("Thread is not holding gdk lock");
+ if (!mailbox->msg_tree)
return;
- }
-
#undef SANITY_CHECK
#ifdef SANITY_CHECK
g_return_if_fail(!g_node_find(mailbox->msg_tree,
@@ -1382,91 +1389,6 @@ lbm_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno, GNode * parent,
g_slist_prepend(*unthreaded, GUINT_TO_POINTER(seqno));
mailbox->msg_tree_changed = TRUE;
-
- gdk_threads_leave();
-}
-
-#ifdef BALSA_USE_THREADS
-typedef struct {
-#if GLIB_CHECK_VERSION(2, 32, 0)
- GMutex mutex;
- GCond cond;
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- GMutex *mutex;
- GCond *cond;
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
- LibBalsaMailbox *mailbox;
- guint seqno;
- GNode *parent;
- GNode **sibling;
- gboolean wait;
-} LbmMsgnoInsertedInfo;
-
-static gboolean
-lbm_msgno_inserted_idle_cb(LbmMsgnoInsertedInfo * info)
-{
-#if GLIB_CHECK_VERSION(2, 32, 0)
- g_mutex_lock(&info->mutex);
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- g_mutex_lock(info->mutex);
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
-
- lbm_msgno_inserted(info->mailbox, info->seqno, info->parent,
- info->sibling);
- info->wait = FALSE;
-
-#if GLIB_CHECK_VERSION(2, 32, 0)
- g_cond_signal(&info->cond);
- g_mutex_unlock(&info->mutex);
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- g_cond_signal(info->cond);
- g_mutex_unlock(info->mutex);
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
-
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-void
-libbalsa_mailbox_msgno_inserted(LibBalsaMailbox *mailbox, guint seqno,
- GNode * parent, GNode ** sibling)
-{
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- LbmMsgnoInsertedInfo info;
-
- info.mailbox = g_object_ref(mailbox);
- info.seqno = seqno;
- info.parent = parent;
- info.sibling = sibling;
- info.wait = TRUE;
-#if GLIB_CHECK_VERSION(2, 32, 0)
- g_mutex_init(&info.mutex);
- g_cond_init(&info.cond);
- g_mutex_lock(&info.mutex);
- g_idle_add((GSourceFunc) lbm_msgno_inserted_idle_cb, &info);
- while (info.wait)
- g_cond_wait(&info.cond, &info.mutex);
- g_mutex_unlock(&info.mutex);
- g_mutex_clear(&info.mutex);
- g_cond_clear(&info.cond);
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- info.mutex = g_mutex_new();
- info.cond = g_cond_new();
- g_mutex_lock(info.mutex);
- g_idle_add((GSourceFunc) lbm_msgno_inserted_idle_cb, &info);
- while (info.wait)
- g_cond_wait(info.cond, info.mutex);
- g_mutex_unlock(info.mutex);
- g_mutex_free(info.mutex);
- g_cond_free(info.cond);
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
- g_object_unref(mailbox);
- } else
- lbm_msgno_inserted(mailbox, seqno, parent, sibling);
-#else /* BALSA_USE_THREADS */
- lbm_msgno_inserted(mailbox, seqno, parent, sibling);
-#endif /* BALSA_USE_THREADS */
}
static void
@@ -1497,23 +1419,6 @@ libbalsa_mailbox_msgno_filt_in(LibBalsaMailbox *mailbox, guint seqno)
gdk_threads_leave();
}
-#ifdef BALSA_USE_THREADS
-/*
- * Handler for "message-expunged" signal
- *
- * Adjust msgno; it will be invalid (zero) if msgno was expunged.
- */
-static void
-lbm_message_expunged_cb(LibBalsaMailbox * mailbox, guint expunged_msgno,
- guint * msgno)
-{
- if (*msgno > expunged_msgno)
- --*msgno;
- else if (*msgno == expunged_msgno)
- *msgno = 0;
-}
-#endif /* BALSA_USE_THREADS */
-
/*
* libbalsa_mailbox_msgno_removed and helpers
*/
@@ -1534,8 +1439,8 @@ decrease_post(GNode *node, gpointer data)
return FALSE;
}
-static void
-lbm_msgno_removed(LibBalsaMailbox * mailbox, guint seqno)
+void
+libbalsa_mailbox_msgno_removed(LibBalsaMailbox * mailbox, guint seqno)
{
GtkTreeIter iter;
GtkTreePath *path;
@@ -1623,50 +1528,6 @@ lbm_msgno_removed(LibBalsaMailbox * mailbox, guint seqno)
gdk_threads_leave();
}
-#ifdef BALSA_USE_THREADS
-typedef struct {
- LibBalsaMailbox *mailbox;
- guint seqno;
- gulong expunged_cb_handler_id;
-} LbmMsgnoRemovedInfo;
-
-static gboolean
-lbm_msgno_removed_idle_cb(LbmMsgnoRemovedInfo * info)
-{
- g_signal_handler_disconnect(info->mailbox,
- info->expunged_cb_handler_id);
- if (info->seqno)
- lbm_msgno_removed(info->mailbox, info->seqno);
- g_object_unref(info->mailbox);
- g_slice_free(LbmMsgnoRemovedInfo, info);
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-void
-libbalsa_mailbox_msgno_removed(LibBalsaMailbox * mailbox, guint seqno)
-{
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- LbmMsgnoRemovedInfo *info;
-
- info = g_slice_new(LbmMsgnoRemovedInfo);
- info->mailbox = g_object_ref(mailbox);
- info->seqno = seqno;
- info->expunged_cb_handler_id =
- g_signal_connect(mailbox, "message-expunged",
- G_CALLBACK(lbm_message_expunged_cb),
- &info->seqno);
- g_idle_add((GSourceFunc) lbm_msgno_removed_idle_cb,
- info);
- } else {
- lbm_msgno_removed(mailbox, seqno);
- }
-#else /* BALSA_USE_THREADS */
- lbm_msgno_removed(mailbox, seqno);
-#endif /* BALSA_USE_THREADS */
-}
-
static void
libbalsa_mailbox_msgno_filt_out(LibBalsaMailbox * mailbox, GNode * node)
{
@@ -1734,14 +1595,16 @@ libbalsa_mailbox_msgno_filt_out(LibBalsaMailbox * mailbox, GNode * node)
* messages;
* - if it isn't in the view and it matches the condition, filter it in.
*/
-static void
-lbm_msgno_filt_check(LibBalsaMailbox * mailbox, guint seqno,
- LibBalsaMailboxSearchIter * search_iter,
- gboolean hold_selected)
+void
+libbalsa_mailbox_msgno_filt_check(LibBalsaMailbox * mailbox, guint seqno,
+ LibBalsaMailboxSearchIter * search_iter,
+ gboolean hold_selected)
{
gboolean match;
GNode *node;
+ g_return_if_fail(LIBBALSA_IS_MAILBOX(mailbox));
+
gdk_threads_enter();
if (!mailbox->msg_tree) {
@@ -1780,58 +1643,6 @@ lbm_msgno_filt_check(LibBalsaMailbox * mailbox, guint seqno,
gdk_threads_leave();
}
-#ifdef BALSA_USE_THREADS
-typedef struct {
- LibBalsaMailbox *mailbox;
- guint seqno;
- LibBalsaMailboxSearchIter *search_iter;
- gboolean hold_selected;
- gulong expunged_cb_handler_id;
-} LbmMsgnoFiltCheckInfo;
-
-static gboolean
-lbm_msgno_filt_check_idle_cb(LbmMsgnoFiltCheckInfo * info)
-{
- g_signal_handler_disconnect(info->mailbox,
- info->expunged_cb_handler_id);
- if (info->seqno)
- lbm_msgno_filt_check(info->mailbox, info->seqno, info->search_iter,
- info->hold_selected);
- g_object_unref(info->mailbox);
- libbalsa_mailbox_search_iter_unref(info->search_iter);
- g_slice_free(LbmMsgnoFiltCheckInfo, info);
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-void
-libbalsa_mailbox_msgno_filt_check(LibBalsaMailbox * mailbox, guint seqno,
- LibBalsaMailboxSearchIter * search_iter,
- gboolean hold_selected)
-{
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mailbox));
-
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- LbmMsgnoFiltCheckInfo *info;
-
- info = g_slice_new(LbmMsgnoFiltCheckInfo);
- info->mailbox = g_object_ref(mailbox);
- info->seqno = seqno;
- info->expunged_cb_handler_id =
- g_signal_connect(mailbox, "message-expunged",
- G_CALLBACK(lbm_message_expunged_cb),
- &info->seqno);
- info->search_iter = libbalsa_mailbox_search_iter_ref(search_iter);
- info->hold_selected = hold_selected;
- g_idle_add((GSourceFunc) lbm_msgno_filt_check_idle_cb, info);
- } else
- lbm_msgno_filt_check(mailbox, seqno, search_iter, hold_selected);
-#else /* BALSA_USE_THREADS */
- lbm_msgno_filt_check(mailbox, seqno, search_iter, hold_selected);
-#endif /* BALSA_USE_THREADS */
-}
-
/* Search iters */
LibBalsaMailboxSearchIter *
libbalsa_mailbox_search_iter_new(LibBalsaCondition * condition)
@@ -2116,18 +1927,13 @@ lbm_cache_message(LibBalsaMailbox * mailbox, guint msgno,
entry = g_ptr_array_index(mailbox->mindex, msgno - 1);
- if (!entry) {
- /* Assign pointer in mailbox->mindex before populating the
- * entry, because we may recursively enter lbm_cache_message
- * while populating it. */
+ if (!entry)
g_ptr_array_index(mailbox->mindex, msgno - 1) =
- entry = g_new0(LibBalsaMailboxIndexEntry, 1);
- lbm_index_entry_populate_from_msg(entry, message);
+ lbm_index_entry_new_from_msg(message);
#if BALSA_USE_THREADS
- } else if (entry->idle_pending) {
+ else if (entry->idle_pending)
lbm_index_entry_populate_from_msg(entry, message);
#endif /* BALSA_USE_THREADS */
- }
}
LibBalsaMessage *
diff --git a/libbalsa/mailbox_local.c b/libbalsa/mailbox_local.c
index 8eccfa6..5dbb08f 100644
--- a/libbalsa/mailbox_local.c
+++ b/libbalsa/mailbox_local.c
@@ -1023,8 +1023,11 @@ libbalsa_mailbox_local_load_messages(LibBalsaMailbox *mailbox,
g_return_if_fail(LIBBALSA_IS_MAILBOX_LOCAL(mailbox));
+ gdk_threads_enter();
+
if (!mailbox->msg_tree) {
/* Mailbox is closed, or no view has been created. */
+ gdk_threads_leave();
return;
}
@@ -1043,6 +1046,8 @@ libbalsa_mailbox_local_load_messages(LibBalsaMailbox *mailbox,
msg_info->message);
}
+ gdk_threads_leave();
+
if (new_messages) {
libbalsa_mailbox_run_filters_on_reception(mailbox);
libbalsa_mailbox_set_unread_messages_flag(mailbox,
diff --git a/src/balsa-app.c b/src/balsa-app.c
index ededebd..828f27b 100644
--- a/src/balsa-app.c
+++ b/src/balsa-app.c
@@ -694,8 +694,8 @@ balsa_find_dir(LibBalsaServer *server, const gchar * path)
}
static gint
-find_url_func(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
- BalsaFind * bf)
+find_url(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
+ BalsaFind * bf)
{
BalsaMailboxNode *mbnode;
LibBalsaMailbox *mailbox;
@@ -715,8 +715,8 @@ find_url_func(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter,
* returns NULL on failure; caller must unref mbnode when non-NULL.
*/
-static BalsaMailboxNode *
-find_url(const gchar * url)
+BalsaMailboxNode *
+balsa_find_url(const gchar * url)
{
BalsaFind bf;
@@ -726,7 +726,7 @@ find_url(const gchar * url)
bf.mbnode = NULL;
if (balsa_app.mblist_tree_store)
gtk_tree_model_foreach(GTK_TREE_MODEL(balsa_app.mblist_tree_store),
- (GtkTreeModelForeachFunc) find_url_func,
+ (GtkTreeModelForeachFunc) find_url,
&bf);
gdk_threads_leave();
@@ -734,83 +734,6 @@ find_url(const gchar * url)
return bf.mbnode;
}
-#ifdef BALSA_USE_THREADS
-typedef struct {
- const gchar * url;
-#if GLIB_CHECK_VERSION(2, 32, 0)
- GMutex mutex;
- GCond cond;
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- GMutex *mutex;
- GCond *cond;
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
- gboolean wait;
- BalsaMailboxNode *mbnode;
-} BalsaFindUrlInfo;
-
-static gboolean
-find_url_idle_cb(BalsaFindUrlInfo * info)
-{
-#if GLIB_CHECK_VERSION(2, 32, 0)
- g_mutex_lock(&info->mutex);
-
- info->mbnode = find_url(info->url);
- info->wait = FALSE;
-
- g_cond_signal(&info->cond);
- g_mutex_unlock(&info->mutex);
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- g_mutex_lock(info->mutex);
-
- info->mbnode = find_url(info->url);
- info->wait = FALSE;
-
- g_cond_signal(info->cond);
- g_mutex_unlock(info->mutex);
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
-
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-BalsaMailboxNode *
-balsa_find_url(const gchar * url)
-{
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- BalsaFindUrlInfo info;
-
- info.url = url;
- info.wait = TRUE;
-#if GLIB_CHECK_VERSION(2, 32, 0)
- g_mutex_init(&info.mutex);
- g_cond_init(&info.cond);
- g_mutex_lock(&info.mutex);
- g_idle_add((GSourceFunc) find_url_idle_cb, &info);
- while (info.wait)
- g_cond_wait(&info.cond, &info.mutex);
- g_mutex_unlock(&info.mutex);
- g_mutex_clear(&info.mutex);
- g_cond_clear(&info.cond);
-#else /* GLIB_CHECK_VERSION(2, 32, 0) */
- info.mutex = g_mutex_new();
- info.cond = g_cond_new();
- g_mutex_lock(info.mutex);
- g_idle_add((GSourceFunc) find_url_idle_cb, &info);
- while (info.wait)
- g_cond_wait(info.cond, info.mutex);
- g_mutex_unlock(info.mutex);
- g_mutex_free(info.mutex);
- g_cond_free(info.cond);
-#endif /* GLIB_CHECK_VERSION(2, 32, 0) */
- return info.mbnode;
- } else
- return find_url(url);
-#else /* BALSA_USE_THREADS */
- return find_url(url);
-#endif /* BALSA_USE_THREADS */
-}
-
/* balsa_find_mailbox_by_url:
* looks for a mailbox with the given url.
* returns NULL on failure
diff --git a/src/balsa-index.c b/src/balsa-index.c
index 0a8ca25..79365c4 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -885,7 +885,7 @@ bi_view_on_open(struct view_on_open_data *data)
return FALSE;
}
-static void
+void
balsa_index_scroll_on_open(BalsaIndex *index)
{
LibBalsaMailbox *mailbox = index->mailbox_node->mailbox;
@@ -1006,151 +1006,90 @@ bndx_mailbox_message_expunged_cb(LibBalsaMailbox * mailbox, guint msgno,
--bindex->next_msgno;
}
-/*
- * balsa_index_load_mailbox_node:
- */
-
-typedef struct {
- BalsaIndex *index;
- BalsaMailboxNode *mbnode;
- GError *err;
- gboolean successp;
-} bndx_open_mailbox_info;
+/* balsa_index_load_mailbox_node:
+ open mailbox_node, the opening is done in thread to keep UI alive.
-/* Idle callback to complete opening a mailbox */
+ Called NOT holding the gdk lock, so we must wrap gtk calls in
+ gdk_threads_{enter,leave}.
+*/
-static gboolean
-bndx_set_mailbox(bndx_open_mailbox_info * info)
+gboolean
+balsa_index_load_mailbox_node(BalsaIndex * index,
+ BalsaMailboxNode* mbnode, GError **err)
{
GtkTreeView *tree_view;
LibBalsaMailbox *mailbox;
+ gboolean successp;
+ gint try_cnt;
- if (!info->successp) {
- libbalsa_information(LIBBALSA_INFORMATION_ERROR,
- _("Unable to Open Mailbox!\n%s."),
- info->err ?
- info->err->message : _("Unknown error"));
- g_error_free(info->err);
- g_object_unref(g_object_ref_sink(info->index));
- g_free(info);
+ g_return_val_if_fail(BALSA_IS_INDEX(index), TRUE);
+ g_return_val_if_fail(index->mailbox_node == NULL, TRUE);
+ g_return_val_if_fail(BALSA_IS_MAILBOX_NODE(mbnode), TRUE);
+ g_return_val_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox), TRUE);
- return FALSE;
- }
+ mailbox = mbnode->mailbox;
+
+ try_cnt = 0;
+ do {
+ g_clear_error(err);
+ successp = libbalsa_mailbox_open(mailbox, err);
+ if (!balsa_app.main_window)
+ return FALSE;
+
+ if(successp) break;
+ if(*err && (*err)->code != LIBBALSA_MAILBOX_TOOMANYOPEN_ERROR)
+ break;
+ balsa_mblist_close_lru_peer_mbx(balsa_app.mblist, mailbox);
+ } while(try_cnt++<3);
+
+ if (!successp)
+ return TRUE;
/*
* set the new mailbox
*/
- info->index->mailbox_node = info->mbnode;
- g_object_weak_ref(G_OBJECT(info->mbnode),
- (GWeakNotify) bndx_mbnode_weak_notify, info->index);
+ index->mailbox_node = mbnode;
+ g_object_weak_ref(G_OBJECT(mbnode),
+ (GWeakNotify) bndx_mbnode_weak_notify, index);
/*
* rename "from" column to "to" for outgoing mail
*/
- tree_view = GTK_TREE_VIEW(info->index);
- mailbox = info->mbnode->mailbox;
+ gdk_threads_enter();
+ tree_view = GTK_TREE_VIEW(index);
if (libbalsa_mailbox_get_show(mailbox) == LB_MAILBOX_SHOW_TO) {
GtkTreeViewColumn *column =
- gtk_tree_view_get_column(tree_view, LB_MBOX_FROM_COL);
- info->index->filter_no = 1; /* FIXME: this is hack! */
+ gtk_tree_view_get_column(tree_view, LB_MBOX_FROM_COL);
+ index->filter_no = 1; /* FIXME: this is hack! */
gtk_tree_view_column_set_title(column, _("To"));
}
g_signal_connect_swapped(G_OBJECT(mailbox), "changed",
- G_CALLBACK(bndx_mailbox_changed_cb),
- info->index);
+ G_CALLBACK(bndx_mailbox_changed_cb),
+ (gpointer) index);
g_signal_connect(mailbox, "row-inserted",
- G_CALLBACK(bndx_mailbox_row_inserted_cb),
- info->index);
+ G_CALLBACK(bndx_mailbox_row_inserted_cb), index);
g_signal_connect(mailbox, "message-expunged",
- G_CALLBACK(bndx_mailbox_message_expunged_cb),
- info->index);
+ G_CALLBACK(bndx_mailbox_message_expunged_cb), index);
/* Set the tree store */
#ifndef GTK2_FETCHES_ONLY_VISIBLE_CELLS
g_object_set_data(G_OBJECT(mailbox), "tree-view", tree_view);
#endif
gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(mailbox));
+ gdk_threads_leave();
/* Create a search-iter for SEARCH UNDELETED. */
if (!cond_undeleted)
cond_undeleted =
libbalsa_condition_new_flag_enum(TRUE,
LIBBALSA_MESSAGE_FLAG_DELETED);
- info->index->search_iter =
- libbalsa_mailbox_search_iter_new(cond_undeleted);
+ index->search_iter = libbalsa_mailbox_search_iter_new(cond_undeleted);
/* Note when this mailbox was opened, for use in auto-closing. */
- time(&info->index->mailbox_node->last_use);
-
- balsa_index_scroll_on_open(info->index);
-
- g_free(info);
+ time(&index->mailbox_node->last_use);
return FALSE;
}
-/*
- * Subthread to do the actual opening
- */
-static void
-bndx_open_mailbox(bndx_open_mailbox_info * info)
-{
- gint try_cnt;
- LibBalsaMailbox *mailbox;
-
- mailbox = info->mbnode->mailbox;
-
- info->err = NULL;
- try_cnt = 0;
- do {
- g_clear_error(&info->err);
- info->successp = libbalsa_mailbox_open(mailbox, &info->err);
- if (!balsa_app.main_window)
- return;
-
- if (info->successp)
- break;
- if (info->err &&
- info->err->code != LIBBALSA_MAILBOX_TOOMANYOPEN_ERROR)
- break;
- balsa_mblist_close_lru_peer_mbx(balsa_app.mblist, mailbox);
- } while (try_cnt++ < 3);
-
-#ifdef BALSA_USE_THREADS
- gdk_threads_add_idle((GSourceFunc) bndx_set_mailbox, info);
-
- pthread_exit(0);
-#else /* BALSA_USE_THREADS */
- bndx_set_mailbox(info);
-#endif /* BALSA_USE_THREADS */
-}
-
-void
-balsa_index_load_mailbox_node (BalsaIndex * index,
- BalsaMailboxNode* mbnode)
-{
- bndx_open_mailbox_info *info;
-#ifdef BALSA_USE_THREADS
- pthread_t open_thread;
-#endif /* BALSA_USE_THREADS */
-
- g_return_if_fail(BALSA_IS_INDEX(index));
- g_return_if_fail(index->mailbox_node == NULL);
- g_return_if_fail(BALSA_IS_MAILBOX_NODE(mbnode));
- g_return_if_fail(LIBBALSA_IS_MAILBOX(mbnode->mailbox));
-
- info = g_new(bndx_open_mailbox_info, 1);
- info->index = index;
- info->mbnode = mbnode;
-
-#ifdef BALSA_USE_THREADS
- pthread_create(&open_thread, NULL,
- (void*(*)(void*))bndx_open_mailbox, info);
- pthread_detach(open_thread);
-#else /* BALSA_USE_THREADS */
- bndx_open_mailbox(info);
-#endif /* BALSA_USE_THREADS */
-}
-
void
balsa_index_set_width_preference(BalsaIndex *bindex,
BalsaIndexWidthPreference pref)
diff --git a/src/balsa-index.h b/src/balsa-index.h
index f69f679..dc5ab15 100644
--- a/src/balsa-index.h
+++ b/src/balsa-index.h
@@ -105,10 +105,12 @@ extern "C" {
/* sets the mail stream; if it's a new stream, then it's
* contents is loaded into the index */
- void balsa_index_load_mailbox_node(BalsaIndex * bindex,
- BalsaMailboxNode * mbnode);
+ gboolean balsa_index_load_mailbox_node(BalsaIndex * bindex,
+ BalsaMailboxNode * mbnode,
+ GError **err);
void balsa_index_set_width_preference(BalsaIndex *bindex,
BalsaIndexWidthPreference pref);
+ void balsa_index_scroll_on_open(BalsaIndex *index);
void balsa_index_update_tree(BalsaIndex *bindex, gboolean expand);
void balsa_index_set_threading_type(BalsaIndex * bindex, int thtype);
void balsa_index_set_view_filter(BalsaIndex *bindex,
diff --git a/src/main-window.c b/src/main-window.c
index 5591c73..0874dd5 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -2323,20 +2323,22 @@ bw_notebook_label_new(BalsaMailboxNode * mbnode)
return box;
}
-/* Class method */
+/* Called with the gdk lock held (when threads are enabled). */
static void
-balsa_window_real_open_mbnode(BalsaWindow * window,
- BalsaMailboxNode * mbnode,
- gboolean set_current)
+bw_real_open_mbnode(BalsaWindow *window, BalsaMailboxNode * mbnode,
+ gboolean set_current)
{
BalsaIndex * index;
GtkWidget *label;
GtkWidget *scroll;
gint page_num;
+ gboolean failurep;
+ GError *err = NULL;
gchar *message;
LibBalsaMailbox *mailbox;
- if (bw_is_open_mailbox(mailbox = mbnode->mailbox))
+ /* FIXME: the check is not needed in non-MT-mode */
+ if (!window || bw_is_open_mailbox(mailbox = mbnode->mailbox))
return;
index = BALSA_INDEX(balsa_index_new());
@@ -2345,16 +2347,36 @@ balsa_window_real_open_mbnode(BalsaWindow * window,
(balsa_app.layout_type == LAYOUT_WIDE_SCREEN)
? BALSA_INDEX_NARROW : BALSA_INDEX_WIDE);
+ g_object_add_weak_pointer(G_OBJECT(window), (gpointer) &window);
message = g_strdup_printf(_("Opening %s"), mailbox->name);
balsa_window_increase_activity(window, message);
- balsa_index_load_mailbox_node(index, mbnode);
- balsa_window_decrease_activity(window, message);
+
+ /* Call balsa_index_load_mailbox_node NOT holding the gdk lock. */
+ gdk_threads_leave();
+ failurep = balsa_index_load_mailbox_node(index, mbnode, &err);
+ gdk_threads_enter();
+
+ if (window) {
+ balsa_window_decrease_activity(window, message);
+ g_object_remove_weak_pointer(G_OBJECT(window), (gpointer) &window);
+ }
g_free(message);
- index->mailbox_node = mbnode;
+ if (!window || failurep) {
+ libbalsa_information(
+ LIBBALSA_INFORMATION_ERROR,
+ _("Unable to Open Mailbox!\n%s."),
+ err ? err->message : _("Unknown error"));
+ g_clear_error(&err);
+ g_object_unref(g_object_ref_sink(index));
+ return;
+ }
+ g_assert(index->mailbox_node);
g_signal_connect(G_OBJECT (index), "index-changed",
G_CALLBACK (bw_index_changed_cb), window);
+ /* if(config_short_label) label = gtk_label_new(mbnode->mailbox->name);
+ else */
label = bw_notebook_label_new(mbnode);
/* store for easy access */
@@ -2385,6 +2407,82 @@ balsa_window_real_open_mbnode(BalsaWindow * window,
libbalsa_mailbox_set_threading(mailbox,
libbalsa_mailbox_get_threading_type
(mailbox));
+ balsa_index_scroll_on_open(index);
+}
+
+#ifdef BALSA_USE_THREADS
+static pthread_mutex_t open_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct bw_open_mbnode_info {
+ BalsaWindow *window;
+ BalsaMailboxNode * mbnode;
+ gboolean set_current;
+};
+
+static void
+bw_real_open_mbnode_thread(GPtrArray *info_array)
+{
+ guint i;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ pthread_mutex_lock(&open_lock);
+
+ for (i = 0; i < info_array->len; i++) {
+ struct bw_open_mbnode_info *info =
+ g_ptr_array_index(info_array, i);
+
+ pthread_mutex_unlock(&open_lock);
+ gdk_threads_enter();
+
+ bw_real_open_mbnode(info->window, info->mbnode, info->set_current);
+
+ if (info->window)
+ g_object_remove_weak_pointer(G_OBJECT(info->window),
+ (gpointer) &info->window);
+ g_object_unref(info->mbnode);
+
+ gdk_threads_leave();
+ g_free(info);
+ pthread_mutex_lock(&open_lock);
+ }
+
+ info_array->len = 0;
+ pthread_mutex_unlock(&open_lock);
+}
+#endif
+
+static void
+balsa_window_real_open_mbnode(BalsaWindow * window,
+ BalsaMailboxNode * mbnode,
+ gboolean set_current)
+{
+#ifdef BALSA_USE_THREADS
+ struct bw_open_mbnode_info *info;
+ static GPtrArray *info_array;
+
+ info = g_new(struct bw_open_mbnode_info, 1);
+ info->window = window;
+ g_object_add_weak_pointer(G_OBJECT(window), (gpointer) &info->window);
+ info->mbnode = g_object_ref(mbnode);
+ info->set_current = set_current;
+
+ pthread_mutex_lock(&open_lock);
+
+ if (!info_array)
+ info_array = g_ptr_array_new();
+ if (!info_array->len) {
+ pthread_t open_thread;
+ pthread_create(&open_thread, NULL,
+ (void*(*)(void*))bw_real_open_mbnode_thread,
+ info_array);
+ pthread_detach(open_thread);
+ }
+
+ g_ptr_array_add(info_array, info);
+ pthread_mutex_unlock(&open_lock);
+#else
+ bw_real_open_mbnode(window, mbnode, set_current);
+#endif
}
/* balsa_window_real_close_mbnode:
@@ -3029,15 +3127,6 @@ bw_mailbox_check(LibBalsaMailbox * mailbox, BalsaWindow * window)
libbalsa_mailbox_check(mailbox);
}
-static gboolean
-bw_check_messages_thread_idle(BalsaWindow * window)
-{
- bw_set_sensitive(window, "GetNewMail", TRUE);
- g_object_unref(window);
-
- return FALSE;
-}
-
static void
bw_check_messages_thread(struct check_messages_thread_info *info)
{
@@ -3065,12 +3154,14 @@ bw_check_messages_thread(struct check_messages_thread_info *info)
checking_mail = 0;
if (info->window) {
- gdk_threads_add_idle((GSourceFunc) bw_check_messages_thread_idle,
- info->window);
+ gdk_threads_enter();
+ bw_set_sensitive(info->window, "GetNewMail", TRUE);
#if defined(HAVE_LIBNM_GLIB)
if (info->window->nm_state == NM_STATE_CONNECTED)
time(&info->window->last_check_time);
#endif /* defined(HAVE_LIBNM_GLIB) */
+ g_object_unref(info->window);
+ gdk_threads_leave();
}
pthread_mutex_unlock(&checking_mail_lock);
diff --git a/src/main.c b/src/main.c
index cf773a4..7c4676f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -486,8 +486,8 @@ periodic_expunge_cb(void)
static GTimeVal prev_time_val;
static gdouble min_fraction;
static void
-progress_set_text(LibBalsaProgress * progress, const gchar * text,
- guint total)
+balsa_progress_set_text(LibBalsaProgress * progress, const gchar * text,
+ guint total)
{
gboolean rc = FALSE;
@@ -508,53 +508,12 @@ progress_set_text(LibBalsaProgress * progress, const gchar * text,
LIBBALSA_PROGRESS_YES : LIBBALSA_PROGRESS_NO;
}
-#ifdef BALSA_USE_THREADS
-typedef struct {
- LibBalsaProgress *progress;
- const gchar *text;
- guint total;
- gdouble fraction;
-} BalsaProgressSetTextInfo;
-
-static gboolean
-progress_set_text_idle_cb(BalsaProgressSetTextInfo * info)
-{
- progress_set_text(info->progress, info->text, info->total);
-
- g_free(info);
-
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-static void
-balsa_progress_set_text(LibBalsaProgress * progress, const gchar * text,
- guint total)
-{
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- BalsaProgressSetTextInfo *info;
-
- info = g_new(BalsaProgressSetTextInfo, 1);
- info->progress = progress;
- info->text = text;
- info->total = total;
-
- gdk_threads_add_idle((GSourceFunc) progress_set_text_idle_cb,
- info);
- } else
- progress_set_text(progress, text, total);
-#else /* BALSA_USE_THREADS */
- progress_set_text(progress, text, total);
-#endif /* BALSA_USE_THREADS */
-}
-
/*
* Set the fraction in the progress bar.
*/
static void
-progress_set_fraction(LibBalsaProgress * progress, gdouble fraction)
+balsa_progress_set_fraction(LibBalsaProgress * progress, gdouble fraction)
{
GTimeVal time_val;
guint elapsed;
@@ -582,38 +541,6 @@ progress_set_fraction(LibBalsaProgress * progress, gdouble fraction)
gdk_threads_leave();
}
-#ifdef BALSA_USE_THREADS
-static gboolean
-progress_set_fraction_idle_cb(BalsaProgressSetTextInfo * info)
-{
- progress_set_fraction(info->progress, info->fraction);
-
- g_free(info);
-
- return FALSE;
-}
-#endif /* BALSA_USE_THREADS */
-
-static void
-balsa_progress_set_fraction(LibBalsaProgress * progress, gdouble fraction)
-{
-#ifdef BALSA_USE_THREADS
- if (libbalsa_am_i_subthread()) {
- BalsaProgressSetTextInfo *info;
-
- info = g_new(BalsaProgressSetTextInfo, 1);
- info->progress = progress;
- info->fraction = fraction;
-
- gdk_threads_add_idle((GSourceFunc) progress_set_fraction_idle_cb,
- info);
- } else
- progress_set_fraction(progress, fraction);
-#else /* BALSA_USE_THREADS */
- progress_set_fraction(progress, fraction);
-#endif /* BALSA_USE_THREADS */
-}
-
static void
balsa_progress_set_activity(gboolean set, const gchar * text)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]