aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author6 <NotZed@Ximian.com>2001-10-17 01:34:59 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-10-17 01:34:59 +0800
commit41802db26312f2d70ff5624e331e45277ce8a8ec (patch)
tree1ba4c61fa37c6e10942af3b24d9e24cbc85f33f6
parent1ca6ce72ac9952f1429873b3c129cdd643ee4462 (diff)
downloadgsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar.gz
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar.bz2
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar.lz
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar.xz
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.tar.zst
gsoc2013-evolution-41802db26312f2d70ff5624e331e45277ce8a8ec.zip
New function to return the id of the currently executing proxied event.
2001-10-16 <NotZed@Ximian.com> * mail-mt.c (mail_proxy_event_id): New function to return the id of the currently executing proxied event. * folder-browser.h: Added private field. * folder-browser.c (folder_changed): Keep track of tasks outstanding in the tasks list, locked access. (FOLDER_BROWSER_LOCK, UNLOCK): Macros to lock the folder browser for poking about in diff threads. (folder_browser_finalise): Wait for any outstanding takss to finish before cleaning ourself up. (folder_browser_destroy): Move the seen_id handling to finalise, also add a loading_id handling code. (main_folder_changed): Remove our running task when done. svn path=/trunk/; revision=13695
-rw-r--r--mail/ChangeLog17
-rw-r--r--mail/folder-browser.c87
-rw-r--r--mail/folder-browser.h4
-rw-r--r--mail/mail-mt.c14
-rw-r--r--mail/mail-mt.h2
5 files changed, 116 insertions, 8 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 0700991a68..b2422fe53b 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,20 @@
+2001-10-16 <NotZed@Ximian.com>
+
+ * mail-mt.c (mail_proxy_event_id): New function to return the id
+ of the currently executing proxied event.
+
+ * folder-browser.h: Added private field.
+
+ * folder-browser.c (folder_changed): Keep track of tasks
+ outstanding in the tasks list, locked access.
+ (FOLDER_BROWSER_LOCK, UNLOCK): Macros to lock the folder browser
+ for poking about in diff threads.
+ (folder_browser_finalise): Wait for any outstanding takss to
+ finish before cleaning ourself up.
+ (folder_browser_destroy): Move the seen_id handling to finalise,
+ also add a loading_id handling code.
+ (main_folder_changed): Remove our running task when done.
+
2001-10-15 Larry Ewing <lewing@ximian.com>
* mail-display.c (mail_error_write): don't write strings longer
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index d68ccacae9..bd0c4bbb2f 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -58,6 +58,18 @@
#define d(x)
+
+typedef struct _FolderBrowserPrivate {
+ GMutex *lock;
+
+ /* If we have outstanding tasks running */
+ GSList *tasks;
+ GSList *tasks_done;
+} FolderBrowserPrivate;
+
+#define FOLDER_BROWSER_LOCK(fb) g_mutex_lock(((FolderBrowser *)(fb))->priv->lock);
+#define FOLDER_BROWSER_UNLOCK(fb) g_mutex_unlock(((FolderBrowser *)(fb))->priv->lock);
+
#define PARENT_TYPE (gtk_table_get_type ())
static void folder_changed(CamelObject *o, void *event_data, void *data);
@@ -112,10 +124,38 @@ folder_browser_finalise (GtkObject *object)
{
FolderBrowser *folder_browser;
CORBA_Environment ev;
+ FolderBrowserPrivate *p;
folder_browser = FOLDER_BROWSER(object);
+ p = folder_browser->priv;
+
+ /* This @#$#@ is to make sure we dont have any outstanding implicit
+ refs on us from outstanding async tasks */
+ FOLDER_BROWSER_LOCK(folder_browser);
+ while (p->tasks) {
+ int id;
+
+ id = (int)p->tasks->data;
+ FOLDER_BROWSER_UNLOCK(folder_browser);
+ mail_msg_wait(id);
+ FOLDER_BROWSER_LOCK(folder_browser);
+ }
+ /* the tasks_done list is just to avoid races, we can simply free it now */
+ g_slist_free(p->tasks_done);
+ p->tasks_done = NULL;
+ FOLDER_BROWSER_UNLOCK(folder_browser);
CORBA_exception_init (&ev);
+
+ if (folder_browser->seen_id != 0) {
+ gtk_timeout_remove (folder_browser->seen_id);
+ folder_browser->seen_id = 0;
+ }
+
+ if (folder_browser->loading_id != 0) {
+ gtk_timeout_remove(folder_browser->loading_id);
+ folder_browser->loading_id = 0;
+ }
if (folder_browser->search_full)
gtk_object_unref (GTK_OBJECT (folder_browser->search_full));
@@ -167,6 +207,9 @@ folder_browser_finalise (GtkObject *object)
if (folder_browser->clipboard_selection)
g_byte_array_free (folder_browser->clipboard_selection, TRUE);
+ g_mutex_free(p->lock);
+ g_free(p);
+
folder_browser_parent_class->finalize(object);
}
@@ -176,12 +219,7 @@ folder_browser_destroy (GtkObject *object)
FolderBrowser *folder_browser;
folder_browser = FOLDER_BROWSER (object);
-
- if (folder_browser->seen_id) {
- gtk_timeout_remove (folder_browser->seen_id);
- folder_browser->seen_id = 0;
- }
-
+
if (folder_browser->message_list) {
gtk_widget_destroy (GTK_WIDGET (folder_browser->message_list));
folder_browser->message_list = NULL;
@@ -783,13 +821,43 @@ update_status_bar(FolderBrowser *fb)
static void main_folder_changed(CamelObject *o, void *event_data, void *data)
{
FolderBrowser *fb = data;
+ FolderBrowserPrivate *p = fb->priv;
+ int id;
+ /* so some corba unref doesnt blow us away while we're busy */
+ gtk_object_ref((GtkObject *)fb);
update_status_bar(fb);
+
+ id = mail_proxy_event_id();
+ if (id != -1) {
+ FOLDER_BROWSER_LOCK(fb);
+ if (g_slist_find(p->tasks, (void *)id))
+ p->tasks = g_slist_remove(p->tasks, (void *)id);
+ else
+ p->tasks_done = g_slist_prepend(p->tasks_done, (void *)id);
+ FOLDER_BROWSER_UNLOCK(fb);
+ }
+ gtk_object_unref((GtkObject *)fb);
}
static void folder_changed(CamelObject *o, void *event_data, void *data)
{
- mail_msg_wait(mail_proxy_event(main_folder_changed, o, event_data, data));
+ int id;
+ FolderBrowser *fb = data;
+ FolderBrowserPrivate *p = fb->priv;
+
+ /* this snot is so we can implicitly and asynchronosly ref
+ the folder browser, since we can't actually ref it because
+ gtk_object_ref isn't threadsafe ... #@$@ */
+ id = mail_proxy_event(main_folder_changed, o, event_data, data);
+ if (id != -1) {
+ FOLDER_BROWSER_LOCK(fb);
+ if (g_slist_find(p->tasks_done, (void *)id))
+ p->tasks_done = g_slist_remove(p->tasks_done, (void *)id);
+ else
+ p->tasks = g_slist_prepend(p->tasks, (void *)id);
+ FOLDER_BROWSER_UNLOCK(fb);
+ }
}
static void
@@ -1897,6 +1965,11 @@ on_message_selected (MessageList *ml, const char *uid, FolderBrowser *fb)
static void
folder_browser_init (GtkObject *object)
{
+ FolderBrowser *fb = (FolderBrowser *)object;
+ FolderBrowserPrivate *p;
+
+ p = fb->priv = g_malloc0(sizeof(*fb->priv));
+ p->lock = g_mutex_new();
}
static void
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index 85a6d6bbaf..fcedd9e352 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -35,6 +35,8 @@ typedef enum _FolderBrowserSelectionState {
struct _FolderBrowser {
GtkTable parent;
+
+ struct _FolderBrowserPrivate *priv;
BonoboPropertyBag *properties;
@@ -56,7 +58,7 @@ struct _FolderBrowser {
char *new_uid; /* place to save the next uid during idle timeout */
char *loaded_uid; /* what we have loaded */
guint loading_id, seen_id;
-
+
/* a folder we are expunging, dont use other than to compare the pointer value */
CamelFolder *expunging;
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index e9803a80e3..0892688853 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -770,12 +770,16 @@ struct _proxy_msg {
void *data;
};
+static int mail_proxy_event_current = -1;
+
static void
do_proxy_event(struct _mail_msg *mm)
{
struct _proxy_msg *m = (struct _proxy_msg *)mm;
+ mail_proxy_event_current = mm->seq;
m->func(m->o, m->event_data, m->data);
+ mail_proxy_event_current = -1;
}
struct _mail_msg_op proxy_event_op = {
@@ -785,6 +789,12 @@ struct _mail_msg_op proxy_event_op = {
NULL,
};
+/* returns the current id of the executing proxy event */
+int mail_proxy_event_id(void)
+{
+ return mail_proxy_event_current;
+}
+
int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data)
{
struct _proxy_msg *m;
@@ -792,7 +802,11 @@ int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_
int ismain = pthread_self() == mail_gui_thread;
if (ismain) {
+ /* save the current id incase we're proxying an event in a proxied event */
+ id = mail_proxy_event_current;
+ mail_proxy_event_current = -1;
func(o, event_data, data);
+ mail_proxy_event_current = id;
/* id of -1 is 'always finished' */
return -1;
} else {
diff --git a/mail/mail-mt.h b/mail/mail-mt.h
index feeddd10cc..057de1ddb0 100644
--- a/mail/mail-mt.h
+++ b/mail/mail-mt.h
@@ -70,6 +70,8 @@ gboolean mail_user_message (const char *type, const char *prompt, gboolean allow
/* forward a camel event (or other call) to the gui thread */
int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data);
+/* in main (only), get the current event id */
+int mail_proxy_event_id(void);
/* Call a function in the gui thread, wait for it to return, type is the marshaller to use */
typedef enum {