** See #56479.
2004-06-16 Not Zed <NotZed@Ximian.com> ** See #56479. * em-utils.c (em_utils_in_addressbook): use the main thread to setup the addressbook list. (em_utils_in_addressbook): only check against the "completion" sources, not all of them. 2004-06-15 Not Zed <NotZed@Ximian.com> * em-folder-browser.c (emfb_mail_stop): call mail_cancel_all to implement the stop button. * em-utils.c (emu_addr_sources_refresh): don't unref the group list, otherwise the sources become broken now (?). (em_utils_in_addressbook): add some locking. add cancellation. this is almost certainly going to cause issues. * mail-mt.c (mail_cancel_hook_add, mail_cancel_hook_remove) (mail_cancel_all): new functions to implement a global mailer stop button. svn path=/trunk/; revision=26363
This commit is contained in:
@ -1,3 +1,26 @@
|
||||
2004-06-16 Not Zed <NotZed@Ximian.com>
|
||||
|
||||
** See #56479.
|
||||
|
||||
* em-utils.c (em_utils_in_addressbook): use the main thread to
|
||||
setup the addressbook list.
|
||||
(em_utils_in_addressbook): only check against the "completion"
|
||||
sources, not all of them.
|
||||
|
||||
2004-06-15 Not Zed <NotZed@Ximian.com>
|
||||
|
||||
* em-folder-browser.c (emfb_mail_stop): call mail_cancel_all to
|
||||
implement the stop button.
|
||||
|
||||
* em-utils.c (emu_addr_sources_refresh): don't unref the group
|
||||
list, otherwise the sources become broken now (?).
|
||||
(em_utils_in_addressbook): add some locking. add cancellation.
|
||||
this is almost certainly going to cause issues.
|
||||
|
||||
* mail-mt.c (mail_cancel_hook_add, mail_cancel_hook_remove)
|
||||
(mail_cancel_all): new functions to implement a global mailer stop
|
||||
button.
|
||||
|
||||
2004-06-15 Jeffrey Stedfast <fejj@ximian.com>
|
||||
|
||||
* mail-ops.c (save_part_save): This code no longer needs to do
|
||||
|
||||
@ -632,7 +632,7 @@ emfb_mail_compose(BonoboUIComponent *uid, void *data, const char *path)
|
||||
static void
|
||||
emfb_mail_stop(BonoboUIComponent *uid, void *data, const char *path)
|
||||
{
|
||||
camel_operation_cancel(NULL);
|
||||
mail_cancel_all();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
130
mail/em-utils.c
130
mail/em-utils.c
@ -1663,42 +1663,41 @@ struct _addr_node {
|
||||
|
||||
#define EMU_ADDR_CACHE_TIME (60*30) /* in seconds */
|
||||
|
||||
static GSList *emu_addr_sources;
|
||||
static pthread_mutex_t emu_addr_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static ESourceList *emu_addr_list;
|
||||
static GHashTable *emu_addr_cache;
|
||||
|
||||
static void
|
||||
emu_addr_sources_refresh(void)
|
||||
/* runs sync, in main thread */
|
||||
static void *
|
||||
emu_addr_setup(void *dummy)
|
||||
{
|
||||
GError *err = NULL;
|
||||
ESourceList *list;
|
||||
GSList *g, *s, *groups, *sources;
|
||||
|
||||
g_slist_foreach(emu_addr_sources, (GFunc)g_object_unref, NULL);
|
||||
g_slist_free(emu_addr_sources);
|
||||
emu_addr_sources = NULL;
|
||||
emu_addr_cache = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
if (!e_book_get_addressbooks(&list, &err)) {
|
||||
if (!e_book_get_addressbooks(&emu_addr_list, &err))
|
||||
g_error_free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
groups = e_source_list_peek_groups(list);
|
||||
for (g=groups;g;g=g_slist_next(g)) {
|
||||
sources = e_source_group_peek_sources((ESourceGroup *)g->data);
|
||||
for (s=sources;s;s=g_slist_next(s)) {
|
||||
emu_addr_sources = g_slist_prepend(emu_addr_sources, g_object_ref(s->data));
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_object_unref(list);
|
||||
static void
|
||||
emu_addr_cancel_book(void *data)
|
||||
{
|
||||
EBook *book = data;
|
||||
GError *err = NULL;
|
||||
|
||||
/* we dunna care if this fails, its just the best we can try */
|
||||
e_book_cancel(book, &err);
|
||||
g_clear_error(&err);
|
||||
}
|
||||
|
||||
gboolean
|
||||
em_utils_in_addressbook(CamelInternetAddress *iaddr)
|
||||
{
|
||||
GError *err = NULL;
|
||||
GSList *s;
|
||||
int found = FALSE;
|
||||
GSList *s, *g, *addr_sources = NULL;
|
||||
int stop = FALSE, found = FALSE;
|
||||
EBookQuery *query;
|
||||
const char *addr;
|
||||
struct _addr_node *node;
|
||||
@ -1708,69 +1707,106 @@ em_utils_in_addressbook(CamelInternetAddress *iaddr)
|
||||
if (!camel_internet_address_get(iaddr, 0, NULL, &addr))
|
||||
return FALSE;
|
||||
|
||||
pthread_mutex_lock(&emu_addr_lock);
|
||||
|
||||
if (emu_addr_cache == NULL) {
|
||||
emu_addr_cache = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
emu_addr_sources_refresh();
|
||||
mail_call_main(MAIL_CALL_p_p, emu_addr_setup, NULL);
|
||||
}
|
||||
|
||||
if (emu_addr_list == NULL) {
|
||||
pthread_mutex_unlock(&emu_addr_lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
now = time(0);
|
||||
|
||||
printf("Checking '%s' is in addressbook", addr);
|
||||
d(printf("Checking '%s' is in addressbook", addr));
|
||||
|
||||
node = g_hash_table_lookup(emu_addr_cache, addr);
|
||||
if (node) {
|
||||
printf(" -> cached, found %s\n", node->found?"yes":"no");
|
||||
if (node->stamp + EMU_ADDR_CACHE_TIME > now)
|
||||
return node->found;
|
||||
printf(" but expired!\n");
|
||||
d(printf(" -> cached, found %s\n", node->found?"yes":"no"));
|
||||
if (node->stamp + EMU_ADDR_CACHE_TIME > now) {
|
||||
found = node->found;
|
||||
pthread_mutex_unlock(&emu_addr_lock);
|
||||
return found;
|
||||
}
|
||||
d(printf(" but expired!\n"));
|
||||
} else {
|
||||
printf(" -> not found in cache\n");
|
||||
d(printf(" -> not found in cache\n"));
|
||||
node = g_malloc0(sizeof(*node));
|
||||
node->addr = g_strdup(addr);
|
||||
g_hash_table_insert(emu_addr_cache, node->addr, node);
|
||||
}
|
||||
|
||||
query = e_book_query_field_test(E_CONTACT_EMAIL, E_BOOK_QUERY_IS, addr);
|
||||
|
||||
for (s = emu_addr_sources;!found && s;s=g_slist_next(s)) {
|
||||
/* FIXME: this aint threadsafe by any measure, but what can you do eh??? */
|
||||
|
||||
for (g = e_source_list_peek_groups(emu_addr_list);g;g=g_slist_next(g)) {
|
||||
for (s = e_source_group_peek_sources((ESourceGroup *)g->data);s;s=g_slist_next(s)) {
|
||||
ESource *src = s->data;
|
||||
const char *completion = e_source_get_property (src, "completion");
|
||||
|
||||
if (completion && !g_ascii_strcasecmp (completion, "true")) {
|
||||
addr_sources = g_slist_prepend(addr_sources, src);
|
||||
g_object_ref(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (s = addr_sources;!stop && !found && s;s=g_slist_next(s)) {
|
||||
ESource *source = s->data;
|
||||
GList *contacts;
|
||||
EBook *book;
|
||||
void *hook;
|
||||
|
||||
printf(" checking '%s'\n", e_source_get_uri(source));
|
||||
d(printf(" checking '%s'\n", e_source_get_uri(source)));
|
||||
|
||||
/* could this take a while? no way to cancel it? */
|
||||
book = e_book_new(source, &err);
|
||||
|
||||
if (!book
|
||||
|| !e_book_open(book, TRUE, &err)) {
|
||||
printf("couldn't load source?\n");
|
||||
if (book == NULL) {
|
||||
g_warning("Unable to create addressbook: %s", err->message);
|
||||
g_clear_error(&err);
|
||||
g_object_unref(book);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e_book_get_contacts(book, query, &contacts, &err)) {
|
||||
printf("Can't get contacts?\n");
|
||||
g_clear_error(&err);
|
||||
hook = mail_cancel_hook_add(emu_addr_cancel_book, book);
|
||||
|
||||
/* ignore errors, but cancellation errors we don't try to go further either */
|
||||
if (!e_book_open(book, TRUE, &err)
|
||||
|| !e_book_get_contacts(book, query, &contacts, &err)) {
|
||||
stop = err->domain == E_BOOK_ERROR && err->code == E_BOOK_ERROR_CANCELLED;
|
||||
mail_cancel_hook_remove(hook);
|
||||
g_object_unref(book);
|
||||
g_warning("Can't get contacts: %s", err->message);
|
||||
g_clear_error(&err);
|
||||
continue;
|
||||
}
|
||||
|
||||
found = contacts != NULL;
|
||||
mail_cancel_hook_remove(hook);
|
||||
|
||||
printf(" %s\n", found?"found":"not found");
|
||||
if (contacts != NULL) {
|
||||
found = TRUE;
|
||||
g_list_foreach(contacts, (GFunc)g_object_unref, NULL);
|
||||
g_list_free(contacts);
|
||||
}
|
||||
|
||||
g_list_foreach(contacts, (GFunc)g_object_unref, NULL);
|
||||
g_list_free(contacts);
|
||||
d(printf(" %s\n", stop?"found":"not found"));
|
||||
|
||||
g_object_unref(book);
|
||||
}
|
||||
|
||||
g_slist_free(addr_sources);
|
||||
|
||||
if (!stop) {
|
||||
node->found = found;
|
||||
node->stamp = now;
|
||||
}
|
||||
|
||||
e_book_query_unref(query);
|
||||
|
||||
node->found = found;
|
||||
node->stamp = now;
|
||||
|
||||
g_hash_table_insert(emu_addr_cache, node->addr, node);
|
||||
pthread_mutex_unlock(&emu_addr_lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
@ -1779,7 +1815,7 @@ em_utils_in_addressbook(CamelInternetAddress *iaddr)
|
||||
* em_utils_snoop_type:
|
||||
* @part:
|
||||
*
|
||||
* Rries to snoop the mime type of a part.
|
||||
* Tries to snoop the mime type of a part.
|
||||
*
|
||||
* Return value: NULL if unknown (more likely application/octet-stream).
|
||||
**/
|
||||
|
||||
@ -352,6 +352,60 @@ void mail_msg_wait_all(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************************** */
|
||||
struct _cancel_hook_data {
|
||||
struct _cancel_hook_data *next;
|
||||
struct _cancel_hook_data *prev;
|
||||
|
||||
GDestroyNotify func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static EDList cancel_hook_list = E_DLIST_INITIALISER(cancel_hook_list);
|
||||
|
||||
void *mail_cancel_hook_add(GDestroyNotify func, void *data)
|
||||
{
|
||||
struct _cancel_hook_data *d;
|
||||
|
||||
d = g_malloc0(sizeof(*d));
|
||||
d->func = func;
|
||||
d->data = data;
|
||||
|
||||
MAIL_MT_LOCK(mail_msg_lock);
|
||||
e_dlist_addtail(&cancel_hook_list, (EDListNode *)d);
|
||||
MAIL_MT_UNLOCK(mail_msg_lock);
|
||||
|
||||
return (void *)d;
|
||||
}
|
||||
|
||||
void mail_cancel_hook_remove(void *handle)
|
||||
{
|
||||
struct _cancel_hook_data *d = handle;
|
||||
|
||||
MAIL_MT_LOCK(mail_msg_lock);
|
||||
e_dlist_remove((EDListNode *)d);
|
||||
MAIL_MT_UNLOCK(mail_msg_lock);
|
||||
g_free(d);
|
||||
}
|
||||
|
||||
void mail_cancel_all(void)
|
||||
{
|
||||
struct _cancel_hook_data *d, *n;
|
||||
|
||||
camel_operation_cancel(NULL);
|
||||
|
||||
/* I can ssee a deadlock coming on ... */
|
||||
MAIL_MT_LOCK(mail_msg_lock);
|
||||
d = (struct _cancel_hook_data *)cancel_hook_list.head;
|
||||
n = d->next;
|
||||
while (n) {
|
||||
d->func(d->data);
|
||||
d = n;
|
||||
n = n->next;
|
||||
}
|
||||
MAIL_MT_UNLOCK(mail_msg_lock);
|
||||
}
|
||||
|
||||
EMsgPort *mail_gui_port;
|
||||
static GIOChannel *mail_gui_channel;
|
||||
static guint mail_gui_watch;
|
||||
|
||||
@ -60,6 +60,11 @@ void mail_msg_wait(unsigned int msgid);
|
||||
void mail_msg_wait_all(void);
|
||||
int mail_msg_active(unsigned int msgid);
|
||||
|
||||
/* To implement the stop button */
|
||||
void *mail_cancel_hook_add(GDestroyNotify func, void *data);
|
||||
void mail_cancel_hook_remove(void *handle);
|
||||
void mail_cancel_all(void);
|
||||
|
||||
/* request a string/password */
|
||||
char *mail_get_password (CamelService *service, const char *prompt,
|
||||
gboolean secret, gboolean *cache);
|
||||
|
||||
Reference in New Issue
Block a user