+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):
--- /dev/null
+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.
+
{
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')
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)
{
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);
{
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 *
}
+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 */
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) */
struct _CamelIMAPPEngine {
CamelObject parent_object;
+ /* incoming requests */
+ EMsgPort *port;
+
CamelIMAPPStream *stream;
camel_imapp_engine_state_t state;
#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"
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);
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);
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
}
*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 *
}
*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);
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);
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");
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;
}
g_free(group);
header->next = savedhdrs;
- CAMEL_NNTP_STORE_UNLOCK(nntp_store, command_lock);
+ CAMEL_SERVICE_UNLOCK(nntp_store, connect_lock);
return;
}
#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))
#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"
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) {
store->current_folder = NULL;
fail:
- CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
+ CAMEL_SERVICE_UNLOCK(store, connect_lock);
return retval;
}
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");
}
if (!service_class->disconnect (service, clean, ex)) {
- CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
+ CAMEL_SERVICE_UNLOCK(store, connect_lock);
return FALSE;
}
g_free(store->current_folder);
store->current_folder = NULL;
- CAMEL_NNTP_STORE_UNLOCK(store, command_lock);
+ CAMEL_SERVICE_UNLOCK(store, connect_lock);
return TRUE;
}
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;
}
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);
unsigned int len;
unsigned char *line;
int ret = -1;
+ CamelFolderInfo *fi = NULL;
+
+ CAMEL_SERVICE_LOCK(nntp_store, connect_lock);
if (top == NULL)
top = "";
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;
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);
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 *
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;
}
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) {
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
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);
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 */
xover = xn;
}
- e_mutex_destroy(p->command_lock);
-
g_free(p);
}
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
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);
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,
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;
}
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;
}