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
This commit is contained in:
6
2001-10-16 17:34:59 +00:00
committed by Michael Zucci
parent 1ca6ce72ac
commit 41802db263
5 changed files with 116 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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 {