** See bug #66509.
authorNot Zed <NotZed@Ximian.com>
Wed, 29 Sep 2004 02:02:03 +0000 (02:02 +0000)
committerMichael Zucci <zucchi@src.gnome.org>
Wed, 29 Sep 2004 02:02:03 +0000 (02:02 +0000)
2004-09-28  Not Zed  <NotZed@Ximian.com>

        ** See bug #66509.

        * providers/nntp/camel-nntp-store.c (camel_nntp_command): if we
        get an error selecting the folder, disconnect/include it in the
        re-try loop.
        (camel_nntp_command): don't set the exception based on errno,
        exception processing is already done.  don't clear it if we're on
        the 3rd retry.

2004-09-27  Not Zed  <NotZed@Ximian.com>

        * providers/nntp/camel-nntp-store.c (nntp_get_folder_info): don't
        do any locking here.
        (nntp_store_get_folder_info_all): move the locking here.
        (nntp_store_get_subscribed_folder_info): and some here too.

        * providers/nntp/camel-nntp-store.c:
        * providers/nntp/camel-nntp-folder.c: Remove nntp command_lock and
        just use the service connect lock for serialisation.

camel/ChangeLog
camel/providers/imapp/ChangeLog [new file with mode: 0644]
camel/providers/imapp/camel-imapp-engine.c
camel/providers/imapp/camel-imapp-engine.h
camel/providers/nntp/camel-nntp-folder.c
camel/providers/nntp/camel-nntp-private.h
camel/providers/nntp/camel-nntp-store.c

index 558337d..a5618f0 100644 (file)
@@ -1,3 +1,25 @@
+2004-09-28  Not Zed  <NotZed@Ximian.com>
+
+       ** See bug #66509.
+
+       * providers/nntp/camel-nntp-store.c (camel_nntp_command): if we
+       get an error selecting the folder, disconnect/include it in the
+       re-try loop.
+       (camel_nntp_command): don't set the exception based on errno,
+       exception processing is already done.  don't clear it if we're on
+       the 3rd retry.
+
+2004-09-27  Not Zed  <NotZed@Ximian.com>
+       
+       * providers/nntp/camel-nntp-store.c (nntp_get_folder_info): don't
+       do any locking here.
+       (nntp_store_get_folder_info_all): move the locking here.
+       (nntp_store_get_subscribed_folder_info): and some here too.
+
+       * providers/nntp/camel-nntp-store.c:
+       * providers/nntp/camel-nntp-folder.c: Remove nntp command_lock and
+       just use the service connect lock for serialisation.
+
 2004-09-14  Jeffrey Stedfast  <fejj@novell.com>
 
        * providers/nntp/camel-nntp-store.c (camel_nntp_try_authenticate):
diff --git a/camel/providers/imapp/ChangeLog b/camel/providers/imapp/ChangeLog
new file mode 100644 (file)
index 0000000..766c24b
--- /dev/null
@@ -0,0 +1,13 @@
+2004-09-28  Not Zed  <NotZed@Ximian.com>
+
+       * camel-imapp-engine.c (camel_imapp_engine_command_free): assume
+       the command isn't in a list now.
+       (cie_worker): worker thread code.
+
+       * camel-imapp-engine.h: make the imappcommand a
+       message.
+
+2004-09-28  Not Zed  <NotZed@Ximian.com>
+
+       * added new changelog.
+
index 798fb31..e288432 100644 (file)
@@ -42,9 +42,10 @@ object_init(CamelIMAPPEngine *ie, CamelIMAPPEngineClass *ieclass)
 {
        ie->handlers = g_hash_table_new(g_str_hash, g_str_equal);
        e_dlist_init(&ie->active);
-       e_dlist_init(&ie->queue);
        e_dlist_init(&ie->done);
 
+       ie->port = e_msgport_new();
+
        ie->tagprefix = ieclass->tagprefix;
        ieclass->tagprefix++;
        if (ieclass->tagprefix > 'Z')
@@ -650,7 +651,7 @@ camel_imapp_engine_command_complete(CamelIMAPPEngine *imap, struct _CamelIMAPPCo
        ic->complete_data = data;
 }
 
-/* FIXME: make imap command's refcounted */
+/* FIXME: make imap command's refcounted? */
 void
 camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
 {
@@ -659,60 +660,18 @@ camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
        if (ic == NULL)
                return;
 
-       /* validity check - we cant' free items still in any queue ... */
-       /* maybe we should just have another queue to keep them? */
-       {
-               CamelIMAPPCommand *iw;
-               int found = 0;
-
-               iw = (CamelIMAPPCommand *)imap->active.head;
-               while (iw->next) {
-                       if (iw == ic) {
-                               found = 1;
-                               g_warning("command '%s' still in active queue", iw->name);
-                               break;
-                       }
-                       iw = iw->next;
-               }
-               iw = (CamelIMAPPCommand *)imap->queue.head;
-               while (iw->next) {
-                       if (iw == ic) {
-                               found = 1;
-                               g_warning("command '%s' still in waiting queue", iw->name);
-                               break;
-                       }
-                       iw = iw->next;
-               }
-               iw = (CamelIMAPPCommand *)imap->done.head;
-               while (iw->next) {
-                       if (iw == ic) {
-                               found = 1;
-                               break;
-                       }
-                       iw = iw->next;
-               }
-               if (!found) {
-                       g_warning("command '%s' not found anywhere", ic->name);
-                       abort();
-               }
-       }
-
-       e_dlist_remove((EDListNode *)ic);
+       /* Note the command must not be in any queue? */
 
        if (ic->mem)
                camel_object_unref((CamelObject *)ic->mem);
        imap_free_status(ic->status);
        g_free(ic->select);
 
-       cp = (CamelIMAPPCommandPart *)ic->parts.head;
-       cn = cp->next;
-       while (cn) {
+       while ( (cp = ((CamelIMAPPCommandPart *)e_dlist_remhead(&ic->parts))) ) {
                g_free(cp->data);
                if (cp->ob)
                        camel_object_unref(cp->ob);
                g_free(cp);
-               cp = cn;
-               cn = cn->next;
        }
 
        g_free(ic);
@@ -724,51 +683,12 @@ camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic)
 {
        CamelIMAPPCommandPart *cp;
 
+       g_assert(ic->msg.reply_port);
+
        if (ic->mem)
                imap_engine_command_complete(imap, ic);
 
-       /* FIXME: remove select stuff */
-
-       /* see if we need to pre-queue a select command to select the right folder first */
-       if (ic->select && (imap->last_select == NULL || strcmp(ic->select, imap->last_select) != 0)) {
-               CamelIMAPPCommand *select;
-               
-               /* of course ... we can't do anything like store/search if we have to select
-                  first, because it'll mess up all the sequence numbers ... hrm ... bugger */
-
-               select = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", ic->select);
-               g_free(imap->last_select);
-               imap->last_select = g_strdup(ic->select);
-               camel_imapp_engine_command_queue(imap, select);
-               /* how does it get freed? handle inside engine? */
-       }
-       
-       /* first, check if command can be sent yet ... queue if not */
-       if (imap->literal != NULL) {
-               printf("%p: queueing while literal active\n", ic);
-               e_dlist_addtail(&imap->queue, (EDListNode *)ic);
-               return;
-       }
-
-       cp = (CamelIMAPPCommandPart *)ic->parts.head;
-       g_assert(cp);
-       ic->current = cp;
-
-       /* how to handle exceptions here? */
-
-       printf("queueing command \"%c%05u %s\"\n", imap->tagprefix, ic->tag, cp->data);
-       camel_stream_printf((CamelStream *)imap->stream, "%c%05u %s\r\n", imap->tagprefix, ic->tag, cp->data);
-
-       if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) {
-               printf("%p: active literal\n", ic);
-               g_assert(cp->next);
-               imap->literal = ic;
-               e_dlist_addtail(&imap->active, (EDListNode *)ic);
-       } else {
-               printf("%p: active non-literal\n", ic);
-               g_assert(cp->next && cp->next->next == NULL);
-               e_dlist_addtail(&imap->active, (EDListNode *)ic);
-       }
+       e_msgport_put(imap->port, (EMsg *)ic);
 }
 
 CamelIMAPPCommand *
@@ -1077,6 +997,54 @@ imap_engine_command_addv(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const ch
 }
 
 
+static void *
+cie_worker(void *data)
+{
+       /* FIXME: remove select stuff */
+
+       /* see if we need to pre-queue a select command to select the right folder first */
+       if (ic->select && (imap->last_select == NULL || strcmp(ic->select, imap->last_select) != 0)) {
+               CamelIMAPPCommand *select;
+               
+               /* of course ... we can't do anything like store/search if we have to select
+                  first, because it'll mess up all the sequence numbers ... hrm ... bugger */
+
+               select = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", ic->select);
+               g_free(imap->last_select);
+               imap->last_select = g_strdup(ic->select);
+               camel_imapp_engine_command_queue(imap, select);
+               /* how does it get freed? handle inside engine? */
+       }
+       
+       /* first, check if command can be sent yet ... queue if not */
+       if (imap->literal != NULL) {
+               printf("%p: queueing while literal active\n", ic);
+               e_dlist_addtail(&imap->queue, (EDListNode *)ic);
+               return;
+       }
+
+       cp = (CamelIMAPPCommandPart *)ic->parts.head;
+       g_assert(cp);
+       ic->current = cp;
+
+       /* how to handle exceptions here? */
+
+       printf("queueing command \"%c%05u %s\"\n", imap->tagprefix, ic->tag, cp->data);
+       camel_stream_printf((CamelStream *)imap->stream, "%c%05u %s\r\n", imap->tagprefix, ic->tag, cp->data);
+
+       if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) {
+               printf("%p: active literal\n", ic);
+               g_assert(cp->next);
+               imap->literal = ic;
+               e_dlist_addtail(&imap->active, (EDListNode *)ic);
+       } else {
+               printf("%p: active non-literal\n", ic);
+               g_assert(cp->next && cp->next->next == NULL);
+               e_dlist_addtail(&imap->active, (EDListNode *)ic);
+       }
+}
+
+
 /* here temporarily while its experimental */
 
 
index 5f74d06..4064d99 100644 (file)
@@ -46,10 +46,8 @@ struct _CamelIMAPPCommandPart {
 typedef int (*CamelIMAPPEngineFunc)(struct _CamelIMAPPEngine *engine, guint32 id, void *data);
 typedef void (*CamelIMAPPCommandFunc)(struct _CamelIMAPPEngine *engine, struct _CamelIMAPPCommand *, void *data);
 
-/* FIXME: make this refcounted */
 struct _CamelIMAPPCommand {
-       struct _CamelIMAPPCommand *next;
-       struct _CamelIMAPPCommand *prev;
+       EMsg msg;
 
        const char *name;       /* command name/type (e.g. FETCH) */
 
@@ -99,6 +97,9 @@ typedef enum _camel_imapp_engine_state_t {
 struct _CamelIMAPPEngine {
        CamelObject parent_object;
 
+       /* incoming requests */
+       EMsgPort *port;
+
        CamelIMAPPStream *stream;
 
        camel_imapp_engine_state_t state;
index 40abfcf..7f06555 100644 (file)
@@ -50,6 +50,7 @@
 #include "camel/camel-mime-part.h"
 #include "camel/camel-stream-buffer.h"
 #include "camel/camel-i18n.h"
+#include "camel/camel-private.h"
 
 #include "camel-nntp-summary.h"
 #include "camel-nntp-store.h"
@@ -84,7 +85,7 @@ nntp_folder_refresh_info_online (CamelFolder *folder, CamelException *ex)
        nntp_store = (CamelNNTPStore *) folder->parent_store;
        nntp_folder = (CamelNNTPFolder *) folder;
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
 
        camel_nntp_command(nntp_store, ex, nntp_folder, &line, NULL);
 
@@ -93,7 +94,7 @@ nntp_folder_refresh_info_online (CamelFolder *folder, CamelException *ex)
                nntp_folder->changes = camel_folder_change_info_new();
        }
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
        
        if (changes) {
                camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes);
@@ -104,17 +105,17 @@ nntp_folder_refresh_info_online (CamelFolder *folder, CamelException *ex)
 static void
 nntp_folder_sync_online (CamelFolder *folder, CamelException *ex)
 {
-       CAMEL_NNTP_STORE_LOCK(folder->parent_store, command_lock);
+       CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
        camel_folder_summary_save (folder->summary);
-       CAMEL_NNTP_STORE_UNLOCK(folder->parent_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
 }
 
 static void
 nntp_folder_sync_offline (CamelFolder *folder, CamelException *ex)
 {
-       CAMEL_NNTP_STORE_LOCK(folder->parent_store, command_lock);
+       CAMEL_SERVICE_LOCK(folder->parent_store, connect_lock);
        camel_folder_summary_save (folder->summary);
-       CAMEL_NNTP_STORE_UNLOCK(folder->parent_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(folder->parent_store, connect_lock);
 }
 
 static gboolean
@@ -178,13 +179,13 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder, const char *uid, Came
        }
        *msgid++ = 0;
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        stream = nntp_folder_download_message ((CamelNNTPFolder *) disco_folder, article, msgid, ex);
        if (stream)
                camel_object_unref (stream);
 
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
 }
 
 static CamelMimeMessage *
@@ -210,7 +211,7 @@ nntp_folder_get_message (CamelFolder *folder, const char *uid, CamelException *e
        }
        *msgid++ = 0;
 
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        /* Lookup in cache, NEWS is global messageid's so use a global cache path */
        stream = camel_data_cache_get (nntp_store->cache, "cache", msgid, NULL);
@@ -245,7 +246,7 @@ fail:
                changes = NULL;
        }
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
        
        if (changes) {
                camel_object_trigger_event ((CamelObject *) folder, "folder_changed", changes);
@@ -318,7 +319,7 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
        struct _camel_header_raw *header, *savedhdrs, *n, *tail;
        char *group, *line;
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        /* send 'POST' command */
        ret = camel_nntp_command (nntp_store, ex, NULL, &line, "post");
@@ -329,7 +330,7 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
                else if (ret != -1)
                        camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
                                              _("Posting failed: %s"), line);
-               CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+               CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
                return;
        }
        
@@ -379,7 +380,7 @@ nntp_folder_append_message_online (CamelFolder *folder, CamelMimeMessage *mime_m
        g_free(group);
        header->next = savedhdrs;
 
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
        
        return;
 }
index f2cca4e..253d4e2 100644 (file)
@@ -38,7 +38,7 @@ extern "C" {
 #include "e-util/e-msgport.h"
 
 struct _CamelNNTPStorePrivate {
-       EMutex *command_lock;   /* for locking the command stream for a complete operation */
+       int dummy;
 };
 
 #define CAMEL_NNTP_STORE_LOCK(f, l) (e_mutex_lock(((CamelNNTPStore *)f)->priv->l))
index 67aff99..718f958 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <camel/camel-disco-store.h>
 #include <camel/camel-disco-diary.h>
+#include "camel/camel-private.h"
 
 #include "camel-nntp-summary.h"
 #include "camel-nntp-store.h"
@@ -168,7 +169,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
        int ret;
        char *path;
        
-       CAMEL_NNTP_STORE_LOCK(store, command_lock);
+       CAMEL_SERVICE_LOCK(store, connect_lock);
 
        /* setup store-wide cache */
        if (store->cache == NULL) {
@@ -266,7 +267,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
        store->current_folder = NULL;
        
  fail:
-       CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
+       CAMEL_SERVICE_UNLOCK(store, connect_lock);
        return retval;
 }
 
@@ -356,7 +357,7 @@ nntp_disconnect_online (CamelService *service, gboolean clean, CamelException *e
        CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
        char *line;
        
-       CAMEL_NNTP_STORE_LOCK(store, command_lock);
+       CAMEL_SERVICE_LOCK(store, connect_lock);
        
        if (clean) {
                camel_nntp_raw_command (store, ex, &line, "quit");
@@ -364,7 +365,7 @@ nntp_disconnect_online (CamelService *service, gboolean clean, CamelException *e
        }
        
        if (!service_class->disconnect (service, clean, ex)) {
-               CAMEL_NNTP_STORE_UNLOCK(store, command_lock);   
+               CAMEL_SERVICE_UNLOCK(store, connect_lock);      
                return FALSE;
        }
        
@@ -373,7 +374,7 @@ nntp_disconnect_online (CamelService *service, gboolean clean, CamelException *e
        g_free(store->current_folder);
        store->current_folder = NULL;
 
-       CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
+       CAMEL_SERVICE_UNLOCK(store, connect_lock);
        
        return TRUE;
 }
@@ -418,11 +419,11 @@ nntp_get_folder(CamelStore *store, const char *folder_name, guint32 flags, Camel
        CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
        CamelFolder *folder;
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        folder = camel_nntp_folder_new(store, folder_name, ex);
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
        
        return folder;
 }
@@ -602,7 +603,9 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *store, const char *top, g
 
                                folder = (CamelNNTPFolder *)camel_store_get_folder((CamelStore *)store, si->path, 0, ex);
                                if (folder) {
+                                       CAMEL_SERVICE_LOCK(store, connect_lock);
                                        camel_nntp_command(store, ex, folder, &line, NULL);
+                                       CAMEL_SERVICE_UNLOCK(store, connect_lock);
                                        camel_object_unref(folder);
                                }
                                camel_exception_clear(ex);
@@ -732,6 +735,9 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const char *top, guin
        unsigned int len;
        unsigned char *line;
        int ret = -1;
+       CamelFolderInfo *fi = NULL;
+
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        if (top == NULL)
                top = "";
@@ -746,11 +752,11 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const char *top, guin
                        date[13] = '\0';
                        
                        if (!nntp_get_date (nntp_store, ex))
-                               return NULL;
+                               goto error;
                        
                        ret = camel_nntp_command (nntp_store, ex, NULL, (char **) &line, "newgroups %s", date);
                        if (ret == -1)
-                               return NULL;
+                               goto error;
                        else if (ret != 231) {
                                /* newgroups not supported :S so reload the complete list */
                                summary->last_newslist[0] = 0;
@@ -771,7 +777,7 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const char *top, guin
                        
                        ret = camel_nntp_command (nntp_store, ex, NULL, (char **)&line, "list");
                        if (ret == -1)
-                               return NULL;
+                               goto error;
                        else if (ret != 215) {
                                camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_INVALID,
                                                      _("Error retrieving newsgroups:\n\n%s"), line);
@@ -799,9 +805,11 @@ nntp_store_get_folder_info_all(CamelNNTPStore *nntp_store, const char *top, guin
                camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
        }
        
-       return nntp_store_get_cached_folder_info (nntp_store, top, flags, ex);
+       fi = nntp_store_get_cached_folder_info (nntp_store, top, flags, ex);
  error:
-       return NULL;
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
+
+       return fi;
 }
 
 static CamelFolderInfo *
@@ -817,14 +825,11 @@ nntp_get_folder_info (CamelStore *store, const char *top, guint32 flags, gboolea
                online,
                top?top:""));
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
-       
        if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
                first = nntp_store_get_subscribed_folder_info (nntp_store, top, flags, ex);
        else
                first = nntp_store_get_folder_info_all (nntp_store, top, flags, online, ex);
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
        return first;
 }
 
@@ -864,7 +869,7 @@ nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
        CamelStoreInfo *si;
        CamelFolderInfo *fi;
        
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        si = camel_store_summary_path(CAMEL_STORE_SUMMARY(nntp_store->summary), folder_name);
        if (!si) {
@@ -878,14 +883,14 @@ nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
                        fi->flags |= CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_NOCHILDREN;
                        camel_store_summary_touch ((CamelStoreSummary *) nntp_store->summary);
                        camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
-                       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+                       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
                        camel_object_trigger_event ((CamelObject *) nntp_store, "folder_subscribed", fi);
                        camel_folder_info_free (fi);
                        return;
                }
        }
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
 }
 
 static void
@@ -895,7 +900,7 @@ nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
        CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE(store);
        CamelFolderInfo *fi;
        CamelStoreInfo *fitem;
-       CAMEL_NNTP_STORE_LOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
        
        fitem = camel_store_summary_path(CAMEL_STORE_SUMMARY(nntp_store->summary), folder_name);
        
@@ -909,14 +914,14 @@ nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
                        fi = nntp_folder_info_from_store_info (nntp_store, nntp_store->do_short_folder_notation, fitem);
                        camel_store_summary_touch ((CamelStoreSummary *) nntp_store->summary);
                        camel_store_summary_save ((CamelStoreSummary *) nntp_store->summary);
-                       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+                       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
                        camel_object_trigger_event ((CamelObject *) nntp_store, "folder_unsubscribed", fi);
                        camel_folder_info_free (fi);
                        return;
                }
        }
        
-       CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+       CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
 }
 
 /* stubs for various folder operations we're not implementing */
@@ -978,8 +983,6 @@ nntp_store_finalize (CamelObject *object)
                xover = xn;
        }
        
-       e_mutex_destroy(p->command_lock);
-       
        g_free(p);
 }
 
@@ -1082,7 +1085,6 @@ nntp_store_init (gpointer object, gpointer klass)
        nntp_store->mem = (CamelStreamMem *)camel_stream_mem_new();
        
        p = nntp_store->priv = g_malloc0(sizeof(*p));
-       p->command_lock = e_mutex_new(E_MUTEX_REC);
 }
 
 CamelType
@@ -1163,7 +1165,7 @@ camel_nntp_raw_commandv (CamelNNTPStore *store, CamelException *ex, char **line,
        int d;
        unsigned int u, u2;
        
-       e_mutex_assert_locked(store->priv->command_lock);
+       e_mutex_assert_locked(((CamelService *)store)->priv->connect_lock);
        g_assert(store->stream->mode != CAMEL_NNTP_STREAM_DATA);
 
        camel_nntp_stream_set_mode(store->stream, CAMEL_NNTP_STREAM_LINE);
@@ -1258,7 +1260,7 @@ camel_nntp_command (CamelNNTPStore *store, CamelException *ex, CamelNNTPFolder *
        int ret, retry;
        unsigned int u;
        
-       e_mutex_assert_locked(store->priv->command_lock);
+       e_mutex_assert_locked(((CamelService *)store)->priv->connect_lock);
 
        if (((CamelDiscoStore *)store)->status == CAMEL_DISCO_STORE_OFFLINE) {
                camel_exception_setv(ex, CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED,
@@ -1289,8 +1291,10 @@ camel_nntp_command (CamelNNTPStore *store, CamelException *ex, CamelNNTPFolder *
                                g_free(store->current_folder);
                                store->current_folder = g_strdup(((CamelFolder *)folder)->full_name);
                                camel_nntp_folder_selected(folder, *line, ex);
-                               if (camel_exception_is_set(ex))
-                                       return -1;
+                               if (camel_exception_is_set(ex)) {
+                                       ret = -1;
+                                       goto error;
+                               }
                        } else {
                                goto error;
                        }
@@ -1320,19 +1324,12 @@ camel_nntp_command (CamelNNTPStore *store, CamelException *ex, CamelNNTPFolder *
                        continue;
                case -1:        /* i/o error */
                        camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
-                       if (camel_exception_get_id(ex) == CAMEL_EXCEPTION_USER_CANCEL)
+                       if (camel_exception_get_id(ex) == CAMEL_EXCEPTION_USER_CANCEL || retry >= 3)
                                return -1;
                        camel_exception_clear(ex);
                        break;
                }
        } while (ret == -1 && retry < 3);
 
-       if (ret == -1) {
-               if (errno == EINTR)
-                       camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("Cancelled."));
-               else
-                       camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("NNTP Command failed: %s"), g_strerror(errno));
-       }
-       
        return ret;
 }