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:
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user