Experimental patch that makes Camel make a new connection each time a message is fetched
- From: Philip Van Hoof <spam pvanhoof be>
- To: tinymail-devel-list <tinymail-devel-list gnome org>
- Subject: Experimental patch that makes Camel make a new connection each time a message is fetched
- Date: Tue, 24 Apr 2007 22:31:10 +0200
I really, really, really really, ...
really hope people will test this patch A LOT.
It's quite gross what happens, but actually: it just works.
I'm basically creating a new CamelImapStore instance, that will connect
on its own behalf, and I use that new store instance for getting the
message. Then I simply disconnect that connection, and I unreference the
worker instance.
Things that might go wrong: the password must be set in the ->url of the
instance. I will also tweak this a little bit to have the API of Camel
cope with all this in a nice way.
I had to make some private API of CamelImapStore public, like its
constructor for example.
I don't recommend doing this trick for other functionalities of Camel.
Nothing in Camel (except the getting of messages, after I reviewed it
line by line) is calculated on this way of working.
Please don't let this be a way for you to tell me: hey, just create a
new connection like what you did for the camel_folder_get_message
functionality: no ... this is an exception.
--
Philip Van Hoof, software developer
home: me at pvanhoof dot be
gnome: pvanhoof at gnome dot org
http://www.pvanhoof.be/blog
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c (revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c (working copy)
@@ -374,6 +374,16 @@
}
}
+
+void
+camel_imap_store_construct (CamelService *service, CamelSession *session,
+ CamelProvider *provider, CamelURL *url,
+ CamelException *ex)
+{
+ construct (service, session, provider, url, ex);
+}
+
+
static int
imap_setv (CamelObject *object, CamelException *ex, CamelArgV *args)
{
@@ -1060,7 +1070,8 @@
{ NULL, "imap", IMAP_PORT, MODE_CLEAR },
};
-gboolean
+
+static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
const char *ssl_mode;
@@ -1114,6 +1125,12 @@
return ret;
}
+gboolean
+camel_imap_service_connect (CamelService *service, CamelException *ex)
+{
+ return connect_to_server_wrapper (service, ex);
+}
+
extern CamelServiceAuthType camel_imap_password_authtype;
static GList *
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h (revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h (working copy)
@@ -159,13 +159,17 @@
ssize_t camel_imap_store_readline_nb (CamelImapStore *store, char **dest, CamelException *ex);
ssize_t camel_imap_store_readline (CamelImapStore *store, char **dest, CamelException *ex);
-gboolean connect_to_server_wrapper (CamelService *service, CamelException *ex);
+gboolean camel_imap_service_connect (CamelService *service, CamelException *ex);
gboolean camel_imap_store_restore_stream_buffer (CamelImapStore *store);
void camel_imap_store_stop_idle (CamelImapStore *store);
void camel_imap_store_start_idle (CamelImapStore *store);
+void
+camel_imap_store_construct (CamelService *service, CamelSession *session,
+ CamelProvider *provider, CamelURL *url,
+ CamelException *ex);
#ifdef __cplusplus
}
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (working copy)
@@ -3830,32 +3830,19 @@
CamelFolderReceiveType type, gint param, CamelException *ex)
{
CamelFolder *folder = CAMEL_FOLDER (imap_folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+ CamelImapStore *store = NULL;
CamelStream *stream = NULL;
gboolean connected = FALSE, idle_rt = FALSE;
- CamelException tex = CAMEL_EXCEPTION_INITIALISER, myex = CAMEL_EXCEPTION_INITIALISER;
- ssize_t nread = 0;
+ CamelException tex = CAMEL_EXCEPTION_INITIALISER,
+ myex = CAMEL_EXCEPTION_INITIALISER,
+ cex = CAMEL_EXCEPTION_INITIALISER;
+ ssize_t nread = 0; gboolean amcon = FALSE;
gchar *a_resp = NULL;
- /* EXPUNGE responses have to modify the cache, which means
- * they have to grab the cache_lock while holding the
- * connect_lock.
-
- * Because getting the service lock may cause MUCH unecessary
- * delay when we already have the data locally, we do the
- * locking separately. This could cause a race
- * getting the same data from the cache, but that is only
- * an inefficiency, and bad luck. */
-
CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
- connected = camel_disco_store_check_online((CamelDiscoStore *)store, &tex);
+ connected = camel_disco_store_check_online(CAMEL_DISCO_STORE (folder->parent_store), &tex);
- if (!store->istream || ((CamelObject *)store->istream)->ref_count <= 0)
- connected = FALSE;
- if (!store->ostream || ((CamelObject *)store->ostream)->ref_count <= 0)
- connected = FALSE;
-
if (connected && ((type & CAMEL_FOLDER_RECEIVE_FULL) && camel_imap_message_cache_is_partial (imap_folder->cache, uid)))
camel_imap_message_cache_remove (imap_folder->cache, uid);
else if (connected && ((type & CAMEL_FOLDER_RECEIVE_PARTIAL || type & CAMEL_FOLDER_RECEIVE_SIZE_LIMITED)
@@ -3863,20 +3850,20 @@
camel_imap_message_cache_remove (imap_folder->cache, uid);
else
{
- stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
-
- if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0")))
- {
- camel_exception_clear (ex);
- stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
- }
+ stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text, ex);
+ if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0")))
+ {
+ camel_exception_clear (ex);
+ stream = camel_imap_message_cache_get (imap_folder->cache, uid, "", ex);
+ }
}
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-
+
if (stream || cache_only)
return stream;
- if (!camel_disco_store_check_online ((CamelDiscoStore*)store, ex)) {
+ if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (folder->parent_store), ex))
+ {
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("This message is not currently available"));
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
@@ -3884,10 +3871,35 @@
}
camel_exception_clear (ex);
- CAMEL_SERVICE_REC_LOCK(store, connect_lock);
- camel_exception_clear(ex);
+ store = CAMEL_IMAP_STORE (camel_object_new (CAMEL_IMAP_STORE_TYPE));
+ camel_imap_store_construct (CAMEL_SERVICE (store),
+ camel_service_get_session (CAMEL_SERVICE (folder->parent_store)),
+ camel_service_get_provider (CAMEL_SERVICE (folder->parent_store)),
+ CAMEL_SERVICE (folder->parent_store)->url, ex);
+
+ if (camel_exception_is_set (ex))
+ {
+ g_critical ("ERR\n");
+ }
+
+ /* amcon = camel_imap_service_connect (CAMEL_SERVICE (store), ex); */
+ amcon = camel_service_connect (CAMEL_SERVICE (store), ex);
+
+ if (!amcon || camel_exception_is_set (ex) || !camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
+ {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("This message is not currently available"));
+ CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
+ return NULL;
+ }
+ camel_exception_clear (ex);
+
+printf ("You have a second connection !\n");
+
+ CAMEL_SERVICE_REC_LOCK(store, connect_lock);
+
CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
if (type & CAMEL_FOLDER_RECEIVE_FULL)
@@ -4251,8 +4263,11 @@
CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
- CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
+ CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
+ camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+ camel_object_unref (CAMEL_OBJECT (store));
+
return stream;
errorhander:
@@ -4271,8 +4286,13 @@
if (stream && ((CamelObject *)stream)->ref_count > 0)
camel_object_unref (CAMEL_OBJECT (stream));
+ if (store)
+ {
+
CAMEL_SERVICE_REC_UNLOCK(store, connect_lock);
-
+ camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
+ camel_object_unref (CAMEL_OBJECT (store));
+ }
return NULL;
}
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c (revision 1837)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c (working copy)
@@ -271,6 +271,8 @@
store->command++, cmd);
len = strlen (full_cmd);
+printf ("-> %s\n", full_cmd);
+
nwritten = camel_stream_write (store->ostream, full_cmd, len);
/* g_mutex_unlock (store->stream_lock); */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]