A different angle to IDLE



This is a completely different angle to IDLE, and I'm pretty sure I will
replace the implementation with this soon.

I'm first fine tuning it, then aggressively testing it and then
committing.

But please apply it and test it a bit yourself, read the code, comment
on it, etc etc.

-- 
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 2884)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(working copy)
@@ -197,44 +197,29 @@
 static void 
 let_idle_die (CamelImapStore *store, gboolean connect_buz)
 {
-
 	idle_debug ("let_idle_die starts\n");
-
-	g_static_rec_mutex_lock (store->idle_prefix_lock);
-	g_static_rec_mutex_lock (store->idle_lock);
-
-	store->idle_kill = TRUE;
-	store->idle_cont = FALSE;
-
-	if (store->idle_prefix)
+	if (store->in_idle && store->idle_thread) 
 	{
-		gchar *resp = NULL;
-		int nwritten = 0;
-		CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+		IdleResponse *idle_resp;
+		store->idle_cont = FALSE;
+		if (store->current_idle)
+			camel_operation_cancel (store->current_idle);
+		idle_resp = g_thread_join (store->idle_thread);
+		if (store->current_idle)
+			camel_operation_uncancel (store->current_idle);
 
-		idle_debug ("Sending DONE in let_idle_die\n");
-		CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-		nwritten = camel_stream_printf (store->ostream, "DONE\r\n");
+		g_static_rec_mutex_lock (store->idle_prefix_lock);
+		g_static_rec_mutex_lock (store->idle_lock);
 		store->in_idle = FALSE;
-		if (nwritten != -1) {
-			resp = NULL;
-			while ((camel_imap_command_response_idle (store, &resp, &ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) {
-				idle_debug ("(.., ..) <- %s | in let_idle_die\n", resp); 
-				g_free (resp); resp=NULL; 
-			}
-			if (resp) {
-				idle_debug ("(.., ..) <- %s\n", resp);
-				g_free (resp);
-			}
-		}
-		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
-		g_free (store->idle_prefix); 
-		store->idle_prefix=NULL;
+		store->idle_thread = NULL;
+		if (store->idle_prefix)
+			g_free (store->idle_prefix);
+		g_static_rec_mutex_unlock (store->idle_lock);
+		g_static_rec_mutex_unlock (store->idle_prefix_lock);
+		if (idle_resp)
+			idle_response_free (idle_resp);
 	}
-
-	g_static_rec_mutex_unlock (store->idle_lock);
-	g_static_rec_mutex_unlock (store->idle_prefix_lock);
-
+	store->idle_prefix = NULL;
 	idle_debug ("let_idle_die finished\n");
 
 	return;
@@ -245,41 +230,8 @@
 {
 	if (store->current_folder && CAMEL_IS_IMAP_FOLDER (store->current_folder))
 		camel_imap_folder_stop_idle (store->current_folder);
-	else {
-		g_static_rec_mutex_lock (store->idle_prefix_lock);
-		g_static_rec_mutex_lock (store->idle_lock);
-
-		store->idle_kill = TRUE;
-		store->idle_cont = FALSE;
-
-		if (store->idle_prefix) {
-			gchar *resp = NULL;
-			int nwritten = 0;
-			CamelException ex = CAMEL_EXCEPTION_INITIALISER;
-
-			idle_debug ("Sending DONE in camel_imap_store_stop_idle\n");
-			CAMEL_SERVICE_REC_LOCK (store, connect_lock);
-			nwritten = camel_stream_printf (store->ostream, "DONE\r\n");
-			store->in_idle = FALSE;
-			if (nwritten != -1) {
-				resp = NULL;
-				while ((camel_imap_command_response_idle (store, &resp, &ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) {
-					idle_debug ("(.., ..) <- %s | in idle_deal_with_stuff (no current folder?)\n", resp); 
-					g_free (resp); resp=NULL; 
-				}
-				if (resp) {
-					idle_debug ("(.., ..) <- %s\n", resp);
-					g_free (resp);
-				}
-			}
-			CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
-			g_free (store->idle_prefix);
-			store->idle_prefix = NULL;
-		}
-
-		g_static_rec_mutex_unlock (store->idle_lock);
-		g_static_rec_mutex_unlock (store->idle_prefix_lock);
-	}
+	else
+		let_idle_die (store, FALSE);
 }
 
 
@@ -415,6 +367,9 @@
 	g_free (imap_store->sum_lock);
 	imap_store->sum_lock = NULL;
 
+	if (imap_store->current_idle)
+		camel_operation_unref (imap_store->current_idle);
+
 }
 
 static void
@@ -422,6 +377,7 @@
 {
 	CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
 
+	imap_store->current_idle = NULL;
 	imap_store->got_online = FALSE;
 	imap_store->going_online = FALSE;
 	imap_store->courier_crap = FALSE;
@@ -4078,191 +4034,3 @@
 	return nread;
 }
 
-
-
-/* FIXME: please god, when will the hurting stop? Thus function is so
-   fucking broken it's not even funny. */
-ssize_t
-camel_imap_store_readline_idle (CamelImapStore *store, char **dest, CamelException *ex)
-{
-	CamelStreamBuffer *stream;
-	char linebuf[1024] = {0};
-	GByteArray *ba;
-	ssize_t nread;
-	
-	g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1);
-	g_return_val_if_fail (dest, -1);
-	
-	*dest = NULL;
-	
-	/* Check for connectedness. Failed (or cancelled) operations will
-	 * close the connection. We can't expect a read to have any
-	 * meaning if we reconnect, so always set an exception.
-	 */
-
-	if (!camel_disco_store_check_online((CamelDiscoStore *)store, ex))
-		return -1;
-
-	camel_imap_store_restore_stream_buffer (store);
-	stream = CAMEL_STREAM_BUFFER (store->istream);
-
-	ba = g_byte_array_new ();
-	while ((nread = camel_stream_buffer_gets_idle (stream, linebuf, sizeof (linebuf))) > 0) {
-		g_byte_array_append (ba, (const guchar*) linebuf, nread);
-		if (linebuf[nread - 1] == '\n')
-			break;
-	}
-
-	if (nread <= 0) {
-		if (errno == EINTR)
-		{
-			CamelException mex = CAMEL_EXCEPTION_INITIALISER;
-			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
-			camel_imap_recon (store, &mex);
-			imap_debug ("Recon in idle: %s\n", camel_exception_get_description (&mex));
-		} else {
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-					      _("Server unexpectedly disconnected: %s"),
-					      g_strerror (errno));
-			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
-		}
-
-		g_byte_array_free (ba, TRUE);
-		return -1;
-	}
-	
-	if (camel_verbose_debug) {
-		fprintf (stderr, "received: ");
-		fwrite (ba->data, 1, ba->len, stderr);
-	}
-	
-	/* camel-imap-command.c:imap_read_untagged expects the CRLFs
-           to be stripped off and be nul-terminated *sigh* */
-	nread = ba->len - 1;
-	ba->data[nread] = '\0';
-	if (ba->data[nread - 1] == '\r') {
-		ba->data[nread - 1] = '\0';
-		nread--;
-	}
-	
-	*dest = (char *) ba->data;
-	g_byte_array_free (ba, FALSE);
-	
-	return nread;
-}
-
-ssize_t
-camel_imap_store_readline_nl (CamelImapStore *store, char **dest, CamelException *ex)
-{
-	CamelStreamBuffer *stream;
-	char linebuf[1024] = {0};
-	GByteArray *ba;
-	ssize_t nread;
-	
-	g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1);
-	g_return_val_if_fail (dest, -1);
-	
-	*dest = NULL;
-	
-	/* Check for connectedness. Failed (or cancelled) operations will
-	 * close the connection. We can't expect a read to have any
-	 * meaning if we reconnect, so always set an exception.
-	 */
-
-	if (!camel_disco_store_check_online((CamelDiscoStore *)store, ex))
-		return -1;
-
-	camel_imap_store_restore_stream_buffer (store);
-
-	if (!store->istream)
-		return -1;
-
-	stream = CAMEL_STREAM_BUFFER (store->istream);
-
-	ba = g_byte_array_new ();
-	while ((nread = camel_stream_buffer_gets (stream, linebuf, sizeof (linebuf))) > 0) {
-		g_byte_array_append (ba, (const guchar*) linebuf, nread);
-		if (linebuf[nread - 1] == '\n')
-			break;
-	}
-
-	if (nread <= 0) {
-		if (errno == EINTR)
-		{
-			CamelException mex = CAMEL_EXCEPTION_INITIALISER;
-			camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, _("Operation cancelled"));
-			camel_imap_recon (store, &mex);
-			imap_debug ("Recon in nl: %s\n", camel_exception_get_description (&mex));
-		} else {
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-					      _("Server unexpectedly disconnected: %s"),
-					      g_strerror (errno));
-			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
-		}
-
-		g_byte_array_free (ba, TRUE);
-		return -1;
-	}
-	
-	if (camel_verbose_debug) {
-		fprintf (stderr, "received: ");
-		fwrite (ba->data, 1, ba->len, stderr);
-	}
-	
-	/* camel-imap-command.c:imap_read_untagged expects the CRLFs
-           to be stripped off and be nul-terminated *sigh* */
-	nread = ba->len - 1;
-	ba->data[nread] = '\0';
-	if (ba->data[nread - 1] == '\r') {
-		ba->data[nread - 1] = '\0';
-		nread--;
-	}
-	
-	*dest = (char *) ba->data;
-	g_byte_array_free (ba, FALSE);
-	
-	return nread;
-}
-
-ssize_t
-camel_imap_store_readline_nb (CamelImapStore *store, char **dest, CamelException *ex)
-{
-	CamelStreamBuffer *stream;
-	char linebuf[1024] = {0};
-	GByteArray *ba;
-	ssize_t nread;
-	
-	g_return_val_if_fail (CAMEL_IS_IMAP_STORE (store), -1);
-	g_return_val_if_fail (dest, -1);
-
-	*dest = NULL;
-
-	if (store->istream == NULL || ((CamelObject *)store->istream)->ref_count <= 0)
-		return -1;
-
-	stream = CAMEL_STREAM_BUFFER (store->istream);
-	ba = g_byte_array_new ();
-	while ((nread = camel_tcp_stream_buffer_gets_nb (stream, linebuf, sizeof (linebuf))) > 0) 
-	{
-		g_byte_array_append (ba, (const guchar*) linebuf, nread);
-		if (linebuf[nread - 1] == '\n')
-			break;
-	}
-
-	if (nread <= 0) {
-		g_byte_array_free (ba, TRUE);
-		return -1;
-	}
-
-	nread = ba->len - 1;
-	ba->data[nread] = '\0';
-	if (ba->data[nread - 1] == '\r') {
-		ba->data[nread - 1] = '\0';
-		nread--;
-	}
-	
-	*dest = (char *) ba->data;
-	g_byte_array_free (ba, FALSE);
-	
-	return nread;
-}
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(working copy)
@@ -52,6 +52,18 @@
 
 G_BEGIN_DECLS
 
+typedef struct {
+	guint32 exists;
+	guint32 recent;
+	GArray *expunged;
+	GList *vanished;
+	GPtrArray *fetch;
+	gboolean exists_happened;
+	CamelFolder *folder;
+} IdleResponse;
+
+void idle_response_free (IdleResponse *idle_resp);
+
 typedef struct _CamelImapMsg CamelImapMsg;
 
 struct _CamelImapMsg {
@@ -151,7 +163,8 @@
 	char tag_prefix;
 	guint32 command;
 	CamelFolder *current_folder, *last_folder, *old_folder;
-	
+	CamelOperation *current_idle;
+
 	/* Information about the server */
 	CamelImapServerLevel server_level;
 	guint32 capabilities, parameters;
@@ -185,10 +198,7 @@
 
 gboolean camel_imap_store_connected (CamelImapStore *store, CamelException *ex);
 
-ssize_t camel_imap_store_readline_nl (CamelImapStore *store, char **dest, CamelException *ex);
-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);
-ssize_t camel_imap_store_readline_idle (CamelImapStore *store, char **dest, CamelException *ex);
 
 gboolean camel_imap_store_restore_stream_buffer (CamelImapStore *store);
 
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(revision 2884)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -3456,15 +3456,6 @@
 	guint32 flags;
 } FetchIdleResponse;
 
-typedef struct {
-	guint32 exists;
-	guint32 recent;
-	GArray *expunged;
-	GList *vanished;
-	GPtrArray *fetch;
-	gboolean exists_happened;
-	CamelFolder *folder;
-} IdleResponse;
 
 static void 
 process_idle_response (IdleResponse *idle_resp)
@@ -3600,7 +3591,7 @@
 	return idle_resp;
 }
 
-static void
+void
 idle_response_free (IdleResponse *idle_resp)
 {
 	idle_debug ("idle_response_free\n");
@@ -3624,41 +3615,30 @@
 
 
 static void
-idle_real_start (CamelImapStore *store)
+idle_start (CamelImapStore *store)
 {
 	char *resp;
 	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
 	gboolean l = CAMEL_SERVICE_REC_TRYLOCK (store, connect_lock);
-	if (store->ostream && store->istream && CAMEL_IS_STREAM (store->ostream))
-	{
-		int nwritten = 0;
-		if (store->idle_prefix)
-			g_free (store->idle_prefix);
-		store->idle_prefix = g_strdup_printf ("%c%.5u", 
-			store->tag_prefix, store->command++);
-		nwritten = camel_stream_printf (store->ostream, "%s IDLE\r\n",
+	int nwritten = 0;
+
+	if (store->idle_prefix)
+		g_free (store->idle_prefix);
+
+	store->idle_prefix = g_strdup_printf ("%c%.5u", store->tag_prefix, 
+			store->command++);
+
+	nwritten = camel_stream_printf (store->ostream, "%s IDLE\r\n",
 			store->idle_prefix);
-		idle_debug ("(%d, %d) -> %s IDLE\n", strlen (store->idle_prefix)+5, 
-			nwritten, store->idle_prefix);
-	} else {
-		idle_debug ("idle_real_start connection lost\n");
-		goto errh;
-	}
 
-	/* The IDLE command is sent from the client to the server when the
-	 *  client is ready to accept unsolicited mailbox update messages.  The
-	 *  server requests a response to the IDLE command using the continuation
-	 * ("+") response.  The IDLE command remains active until the client
-	 * responds to the continuation, and as long as an IDLE command is
-	 * active, the server is now free to send untagged EXISTS, EXPUNGE, and
-	 *  other messages at any time. */
+	idle_debug ("(%d, %d) -> %s IDLE\n", strlen (store->idle_prefix)+5, 
+		nwritten, store->idle_prefix);
 
-	/* So according to the RFC, we will wait for the server for its + 
-	 * continuation. If the server doesn't do this, it's an incorrect 
-	 * IDLE implementation at the server. Right? */
+	/* According to the RFC, we will wait for the server for its + 
+	 * continuation. */
 
 	resp = NULL;
-	while (camel_imap_store_readline_nl (store, &resp, &ex) > 0)
+	while (camel_imap_store_readline (store, &resp, &ex) > 0)
 	{
 		gboolean tbreak = FALSE;
 		if (!strncmp (resp, "+ ", 2))
@@ -3667,16 +3647,18 @@
 			tbreak = TRUE;
 		if (camel_strstrcase (resp, "BAD") != NULL)
 			tbreak = TRUE;
-		idle_debug ("(.., ..) <- %s | in idle_real_start\n", resp);
-		g_free (resp); resp=NULL;
+		idle_debug ("(.., ..) <- %s\n", resp);
+		g_free (resp); 
+		resp=NULL;
 		if (tbreak)
 			break;
 	}
 	if (resp)
 		g_free (resp);
-errh:
+
 	if (l)
 		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
 	return;
 }
 
@@ -3697,6 +3679,52 @@
 	return;
 }
 
+static void
+idle_done (CamelImapStore *store, CamelFolder *folder, IdleResponse *idle_resp)
+{
+	char *resp;
+	CamelException ex = CAMEL_EXCEPTION_INITIALISER;
+	gboolean l = CAMEL_SERVICE_REC_TRYLOCK (store, connect_lock);
+	int nwritten = 0;
+
+	nwritten = camel_stream_printf (store->ostream, "DONE\r\n",
+		store->idle_prefix);
+	idle_debug ("(%d, %d) -> DONE\n", nwritten);
+
+	resp = NULL;
+	while (camel_imap_store_readline (store, &resp, &ex) > 0)
+	{
+		gboolean tbreak = FALSE;
+
+		if (resp && strlen (resp) > 1 && resp[0] == '*') {
+			if (!idle_resp)
+				idle_resp = idle_response_new (folder);
+			consume_idle_line (store, folder, resp, idle_resp);
+		}
+
+		if (camel_strstrcase (resp, "OK") != NULL)
+			tbreak = TRUE;
+		if (camel_strstrcase (resp, "NO") != NULL)
+			tbreak = TRUE;
+		if (camel_strstrcase (resp, "BAD") != NULL)
+			tbreak = TRUE;
+
+		idle_debug ("(.., ..) <- %s\n", resp);
+		g_free (resp); 
+		resp=NULL;
+
+		if (tbreak)
+			break;
+	}
+	if (resp)
+		g_free (resp);
+
+	if (l)
+		CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
+
+	return;
+}
+
 typedef struct {
 	CamelFolder *folder;
 	GCond *condition;
@@ -3715,6 +3743,12 @@
 	int cnt = 0;
 	int nwritten=0;
 	gpointer retval = NULL;
+	gchar line_buffer [1024];
+	CamelTcpStream *tcp_stream;
+	IdleResponse *idle_resp = NULL;
+	gboolean stopped = FALSE;
+	int lines = 0;
+	int stop_fd;
 
 	idle_debug ("idle_thread starts\n");
 
@@ -3776,201 +3810,70 @@
 		idle_debug ("idle_thread starting but immediately stopping\n");
 	}
 
+	idle_start (store);
+
+	if (!info->had_cond && info->condition) {
+		g_mutex_lock (info->mutex);
+		g_cond_broadcast (info->condition);
+		info->had_cond = TRUE;
+		had_cond = TRUE;
+		g_mutex_unlock (info->mutex);
+	}
+
 	/* While nothing has stopped us yet ... 
 	 * TNY TODO: it would be nicer to use select() here, rather than usleep() */
 
-	while (my_cont && !store->idle_kill) 
-	{
-		CamelException ex = CAMEL_EXCEPTION_INITIALISER;
-		char *resp = NULL;
-		IdleResponse *idle_resp = NULL;
-		gboolean senddone = FALSE;
+	tcp_stream = (CamelTcpStream *) store->ostream;
+	stop_fd = camel_operation_cancel_fd (store->current_idle);
 
-		/* A) The first time we will start the IDLE by sending IDLE to
-		 * the server and reading away the + continuation (check out the
-		 * idle_real_start function). We don't call this in the other
-		 * loop cycles of this while. */
+	memset (line_buffer, 0, sizeof (*line_buffer));
 
-		if (store->idle_cont && first) {
-			gboolean l = g_static_rec_mutex_trylock (store->idle_lock);
-			if (!store->idle_kill)
-				idle_real_start (store);
-			if (l)
-				g_static_rec_mutex_unlock (store->idle_lock);
-			first = FALSE;
-		}
+	while (store->idle_cont) 
+	{
+		char *lasts = NULL;
+		int bytes = camel_tcp_stream_wait (tcp_stream, stop_fd, store->idle_sleep, line_buffer, 1023);
 
-		/* And we also send the broadcast to the caller of this thread:
-		 * We're started, and we're fine. It can continue. We don't call
-		 * this in the other loop cycles of this while. */
-
-		if (tfirst) {
-			if (info->condition) {
-				g_mutex_lock (info->mutex);
-				g_cond_broadcast (info->condition);
-				info->had_cond = TRUE; had_cond = TRUE;
-				g_mutex_unlock (info->mutex);
-			}
-			tfirst = FALSE;
-		}
-
-		if (g_static_rec_mutex_trylock (store->idle_lock)) 
+		if (bytes > 0) 
 		{
-			/* B) This happens during the IDLE's body (after IDLE is
-			 * started and before DONE is sent). We read away the
-			 * lines in a non-blocking way. As soon as we have a
-			 * full line, that starts with '*', we consume it. */
+			char *resp;
+			line_buffer[bytes+1] = '\0';
 
-			if (!store->idle_kill) {
-				while (camel_imap_store_readline_nb (store, &resp, &ex) > 0)
-				{
-					if (resp && strlen (resp) > 1 && resp[0] == '*') {
-						if (!idle_resp)
-							idle_resp = idle_response_new (folder);
-						consume_idle_line (store, folder, resp, idle_resp);
-					}
-
-					if (resp)
-						g_free (resp);
-					resp = NULL;
+			for (resp = strtok_r (line_buffer, "\n", &lasts); resp; resp = strtok_r (NULL, "\n", &lasts))
+			{
+				if (resp && strlen (resp) > 1 && resp[0] == '*') {
+					if (!idle_resp)
+						idle_resp = idle_response_new (folder);
+					consume_idle_line (store, folder, resp, idle_resp);
+					lines++;
 				}
 			}
-			g_static_rec_mutex_unlock (store->idle_lock);
+
+			printf ("IDLE: read %d bytes %s\n", bytes, line_buffer);
 		}
 
-		if (resp)
-			g_free (resp);
+		if (!store->idle_cont || (idle_resp && idle_resp->exists_happened)) {
+			idle_done (store, folder, idle_resp);
+			stopped = TRUE;
+			if (!store->idle_cont)
+				retval = idle_resp;
+		} 
 
-		if (store->idle_cont) 
-		{
-			if (idle_resp && !idle_resp->exists_happened) {
-				/* We can process it already: nothing is at this moment
-				 * joining us, nothing is at this moment locking the
-				 * folder_changed handler of TnyCamelFolder */
+		if (store->idle_cont) {
+			if (idle_resp) {
 				process_idle_response (idle_resp);
 				idle_response_free (idle_resp);
 				idle_resp = NULL;
-			} else if (idle_resp && idle_resp->exists_happened) {
-
-				/* We can't deal with new EXISTS responses 
-				 * without first stopping IDLE (we'll need to
-				 * fetch the new headers) */
-
-				senddone = TRUE;
-				retval = idle_resp;
+				printf ("Processed %d lines\n", lines);
+				lines = 0;
 			}
-		} else {
-			/* If store->idle_cont was FALSE, we're going to handle
-			 * idle_resp differently (look below). */
-			senddone = TRUE;
-			retval = idle_resp; 
+			if (stopped)
+				idle_start (store);
 		}
 
-		/* C) So either we timed out (store->idle_sleep as been reached), 
-		 * which means that we 'are' going to restart this entire while,
-		 * including resending the IDLE-start, after we're done with 
-		 * this if-block of course.
-		 *
-		 * Or another thread called us to stop IDLE, and then we're 
-		 * going to exit this while, of course. If it was an idle_kill,
-		 * we're not even going to try doing that in a nice way. In that
-		 * case we'll just exit ASAP (it's let_idle_die in CamelImapStore
-		 * trying to disconnect from the IMAP server). */
-
-		if ((cnt > store->idle_sleep) || senddone) 
-		{
-			if (store->idle_prefix) 
-			{
-				CamelImapResponseType type;
-				gboolean l = g_static_rec_mutex_trylock (store->idle_lock);
-
-				if (!store->idle_kill) 
-				{
-					/* We read-away everything that we still
-					 * have. To find where idle_resp is handled,
-					 * read below at the g_thread_join for
-					 * this thread (we are returning it). */
-
-					resp = NULL;
-					while (camel_imap_store_readline_nb (store, &resp, &ex) > 0)
-					{
-						if (resp && strlen (resp) > 1 && resp[0] == '*') {
-							if (!idle_resp) {
-								idle_resp = idle_response_new (folder);
-								/* We will free this after the join */
-								if (!store->idle_cont)
-									retval = idle_resp; 
-							}
-							consume_idle_line (store, folder, resp, idle_resp);
-						}
-
-						if (resp)
-							g_free (resp);
-						resp = NULL;
-					}
-					if (resp)
-						g_free (resp);
-					resp = NULL;
-
-					/* We send the DONE to the server */
-
-					nwritten = camel_stream_printf (store->ostream, "DONE\r\n");
-					idle_debug ("(%d, 8) -> DONE\n", nwritten);
-
-					/* We read away everything the server sends 
-					 * until the we see the untagged OK response */
-
-					while ((type = camel_imap_command_response_idle (store, &resp, &ex)) == CAMEL_IMAP_RESPONSE_UNTAGGED) 
-					{
-						if (resp && strlen (resp) > 1 && resp[0] == '*') {
-							if (!idle_resp) {
-								idle_resp = idle_response_new (folder);
-								/* We will free this after the join */
-								if (!store->idle_cont)
-									retval = idle_resp; 
-							}
-							consume_idle_line (store, folder, resp, idle_resp);
-						}
-
-						if (resp)
-							g_free (resp);
-						resp = NULL;
-					}
-				}
-
-				if (l)
-					g_static_rec_mutex_unlock (store->idle_lock);
-
-				if (resp)
-					g_free (resp);
-				resp = NULL;
-
-				/* If we are continuing the loop, handle idle_resp
-				 * now (this can invoke fetching new headers). */
-
-				if (store->idle_cont && idle_resp) {
-					process_idle_response (idle_resp);
-					idle_response_free (idle_resp);
-					idle_resp = NULL;
-				}
-			}
-
-			if (store->idle_cont)
-				first = TRUE; 
-			else
-				my_cont = FALSE;
-
-			cnt = 0;
-		}
-
-		/* TNY TODO: try to use the select() of the non-blocking read 
-		 * for this usleep() and cnt stuff. */
-
-		if (my_cont)
-			usleep (500000);
-		cnt++;
+		memset (line_buffer, 0, sizeof (*line_buffer));
 	}
 
+
 	/* We have an extra bool for this, because it's possible that info
 	 * is already freed (of the broadcast happened above, the calling
 	 * thread will have freed it already) */
@@ -4009,8 +3912,14 @@
 	{
 		if (store->in_idle && store->idle_thread) {
 			IdleResponse *idle_resp = NULL;
+
 			store->idle_cont = FALSE;
+			if (store->current_idle)
+				camel_operation_cancel (store->current_idle);
 			idle_resp = g_thread_join (store->idle_thread);
+			if (store->current_idle)
+				camel_operation_uncancel (store->current_idle);
+
 			g_static_rec_mutex_lock (store->idle_prefix_lock);
 			g_static_rec_mutex_lock (store->idle_lock);
 			store->in_idle = FALSE;
@@ -4065,7 +3974,6 @@
 
 			if (!store->in_idle && store->idle_thread) {
 				IdleResponse *idle_resp = NULL;
-
 				store->idle_cont = FALSE;
 				idle_resp = g_thread_join (store->idle_thread);
 				store->idle_thread = NULL;
@@ -4093,6 +4001,10 @@
 				info->folder = folder;
 				camel_object_ref (info->folder);
 
+				if (!store->current_idle)
+					store->current_idle = camel_operation_new (NULL, NULL);
+
+
 				store->idle_thread = g_thread_create (idle_thread, 
 					info, TRUE, NULL);
 				g_mutex_lock (info->mutex);
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(revision 2883)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-command.c	(working copy)
@@ -355,19 +355,6 @@
 		fprintf (stderr, "sending : %c%.5u %s\r\n", store->tag_prefix, store->command, mask);
 	}
 
-	/* Read away whatever we got */
-	while (camel_imap_store_readline_nb (store, &resp, &myex) > 0)
-	{
-		imap_debug ("unsolitcited: ");
-		imap_debug (resp);
-		imap_debug ("\n");
-
-		g_free (resp);
-		resp=NULL;
-	}
-	if (resp)
-		g_free (resp);
-
 	full_cmd = g_strdup_printf ("%c%.5u %s\r\n", store->tag_prefix, 
 		store->command++, cmd);
 	len = strlen (full_cmd);
@@ -531,72 +518,6 @@
 }
 
 
-CamelImapResponseType
-camel_imap_command_response_idle (CamelImapStore *store, char **response,
-			     CamelException *ex)
-{
-	CamelImapResponseType type;
-	char *respbuf;
-
-	if (camel_imap_store_readline_nl (store, &respbuf, ex) < 0)
-		return CAMEL_IMAP_RESPONSE_ERROR;
-
-	imap_debug ("(.., ..) <- %s (IDLE response)\n", respbuf);
-
-	switch (*respbuf) {
-	case '*':
-		if (!g_ascii_strncasecmp (respbuf, "* BYE", 5)) {
-			/* Connection was lost, no more data to fetch */
-			camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL);
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
-					      _("Server unexpectedly disconnected: %s"),
-					      _("Unknown error")); /* g_strerror (104));  FIXME after 1.0 is released */
-			store->connected = FALSE;
-			g_free (respbuf);
-			respbuf = NULL;
-			type = CAMEL_IMAP_RESPONSE_ERROR;
-			break;
-		}
-		
-		/* Read the rest of the response. */
-		type = CAMEL_IMAP_RESPONSE_UNTAGGED;
-		respbuf = imap_read_untagged (store, respbuf, ex);
-		if (!respbuf)
-			type = CAMEL_IMAP_RESPONSE_ERROR;
-		else if (!g_ascii_strncasecmp (respbuf, "* OK [ALERT]", 12)
-			 || !g_ascii_strncasecmp (respbuf, "* NO [ALERT]", 12)
-			 || !g_ascii_strncasecmp (respbuf, "* BAD [ALERT]", 13)) {
-			char *msg;
-
-			/* for imap ALERT codes, account user host */
-			/* we might get a ']' from a BAD response since we +12, but who cares? */
-			msg = g_strdup_printf(_("Alert from IMAP server %s %s:\n%s"),
-					      ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+12);
-			camel_session_alert_user_generic(((CamelService *)store)->session, 
-				CAMEL_SESSION_ALERT_WARNING, msg, FALSE, ((CamelService *)store));
-			g_free(msg);
-		} else if (!g_ascii_strncasecmp (respbuf, "* BAD Invalid tag",17))
-			type = CAMEL_IMAP_RESPONSE_ERROR;
-		break;
-	case '+':
-		type = CAMEL_IMAP_RESPONSE_CONTINUATION;
-		break;
-	default:
-		if (camel_strstrcase (respbuf, "OK") != NULL || 
-			camel_strstrcase (respbuf, "NO") != NULL ||
-			camel_strstrcase (respbuf, "BAD") != NULL) {
-
-			type = CAMEL_IMAP_RESPONSE_TAGGED;
-
-		} else 
-			type = CAMEL_IMAP_RESPONSE_UNTAGGED;
-		break;
-	}
-	*response = respbuf;
-	
-	return type;
-}
-
 CamelImapResponse *
 imap_read_response (CamelImapStore *store, CamelException *ex)
 {
Index: libtinymail-camel/camel-lite/camel/camel-tcp-stream-openssl.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-tcp-stream-openssl.c	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-tcp-stream-openssl.c	(working copy)
@@ -61,7 +61,7 @@
 /* Returns the class for a CamelTcpStreamSSL */
 #define CTSR_CLASS(so) CAMEL_TCP_STREAM_SSL_CLASS (CAMEL_OBJECT_GET_CLASS (so))
 
-static ssize_t stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
+static ssize_t stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t n);
 static ssize_t stream_read (CamelStream *stream, char *buffer, size_t n);
 static ssize_t stream_write (CamelStream *stream, const char *buffer, size_t n);
 static int stream_flush  (CamelStream *stream);
@@ -84,6 +84,9 @@
 	gboolean ssl_mode;
 	guint32 flags;
 	CamelService *service;
+
+	gchar *wait_buffer;
+	size_t wait_buffer_size;
 };
 
 
@@ -105,7 +108,7 @@
 	camel_stream_class->flush = stream_flush;
 	camel_stream_class->close = stream_close;
 	
-	camel_tcp_stream_class->read_nb = stream_read_nb;
+	camel_tcp_stream_class->wait = stream_wait;
 	camel_tcp_stream_class->connect = stream_connect;
 	camel_tcp_stream_class->getsockopt = stream_getsockopt;
 	camel_tcp_stream_class->setsockopt = stream_setsockopt;
@@ -124,6 +127,8 @@
 	
 	stream->priv = g_new0 (struct _CamelTcpStreamSSLPrivate, 1);
 	stream->priv->sockfd = -1;
+	stream->priv->wait_buffer = g_malloc (1024);
+	stream->priv->wait_buffer_size = -1;
 }
 
 static void
@@ -143,9 +148,10 @@
 	
 	if (stream->priv->sockfd != -1)
 		close (stream->priv->sockfd);
-	
+
 	g_free (stream->priv->expected_host);
-	
+	g_free (stream->priv->wait_buffer);
+
 	g_free (stream->priv);
 }
 
@@ -288,53 +294,42 @@
 
 
 static ssize_t
-stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len)
 {
 	CamelTcpStreamSSL *openssl = CAMEL_TCP_STREAM_SSL (stream);
 	SSL *ssl = openssl->priv->ssl;
 	ssize_t nread;
-
 	int error, flags, fdmax;
-	struct timeval timeout;
+	struct timeval tv;
 	fd_set rdset;
 	int res;
 
 	flags = fcntl (openssl->priv->sockfd, F_GETFL);
 	fcntl (openssl->priv->sockfd, F_SETFL, flags | O_NONBLOCK);
-	
-	fdmax = openssl->priv->sockfd + 1;
-	
-	do {
-		FD_ZERO (&rdset);
-		FD_SET (openssl->priv->sockfd, &rdset);
+
+	fdmax = MAX (openssl->priv->sockfd, stop_fd) + 1;
+	FD_ZERO (&rdset);
+	FD_SET (openssl->priv->sockfd, &rdset);
+	FD_SET (stop_fd, &rdset);
+
+	nread = -1;
+	tv.tv_sec = timeout;
+	tv.tv_usec = 0;
+
+	res = select (fdmax, &rdset, 0, 0, &tv);
+
+	if (res > 0 && !FD_ISSET (stop_fd, &rdset)) {
+		if (ssl)
+			nread = SSL_read (ssl, buffer, max_len);
+		else
+			nread = read (openssl->priv->sockfd, buffer, max_len);
+	} else
 		nread = -1;
-		timeout.tv_sec = NONBLOCKING_READ_TIMEOUT;
-		timeout.tv_usec = 0;
-		res = select (fdmax, &rdset, 0, 0, &timeout);
-		
-		if (res == -1)
-			;
-		else if (res == 0)
-			errno = ETIMEDOUT;
-		else {
 
-		  do {
-			if (ssl) {
-				nread = SSL_read (ssl, buffer, n);
-				if (nread < 0)
-					errno = ssl_errno (ssl, nread);
-			} else {
-				nread = read (openssl->priv->sockfd, buffer, n);
-			}
-		  } while (0 && (nread < 0 && errno == EINTR));
-		}
-	} while (0 && (nread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)));
-	
 	error = errno;
 	fcntl (openssl->priv->sockfd, F_SETFL, flags);
 	errno = error;
 
-
 	return nread;
 }
 
@@ -346,7 +341,7 @@
 	SSL *ssl = openssl->priv->ssl;
 	ssize_t nread;
 	int cancel_fd;
-	
+
 	if (camel_operation_cancel_check (NULL)) {
 		errno = EINTR;
 		return -1;
Index: libtinymail-camel/camel-lite/camel/camel-tcp-stream.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-tcp-stream.c	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-tcp-stream.c	(working copy)
@@ -40,7 +40,7 @@
 static int tcp_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
 static struct sockaddr *tcp_get_local_address (CamelTcpStream *stream, socklen_t *len);
 static struct sockaddr *tcp_get_remote_address (CamelTcpStream *stream, socklen_t *len);
-static ssize_t tcp_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
+static ssize_t tcp_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len);
 
 static void
 camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class)
@@ -50,12 +50,12 @@
 	parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (CAMEL_STREAM_TYPE));
 	
 	/* tcp stream methods */
-	camel_tcp_stream_class->read_nb            = tcp_read_nb;
 	camel_tcp_stream_class->connect            = tcp_connect;
 	camel_tcp_stream_class->getsockopt         = tcp_getsockopt;
 	camel_tcp_stream_class->setsockopt         = tcp_setsockopt;
 	camel_tcp_stream_class->get_local_address  = tcp_get_local_address;
 	camel_tcp_stream_class->get_remote_address = tcp_get_remote_address;
+	camel_tcp_stream_class->wait               = tcp_wait;
 }
 
 static void
@@ -84,9 +84,9 @@
 }
 
 static ssize_t
-tcp_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+tcp_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len)
 {
-	w(g_warning ("CamelTcpStream::read_nb called on default implementation"));
+	w(g_warning ("CamelTcpStream::wait called on default implementation"));
 	return -1;
 }
 
@@ -191,10 +191,10 @@
 	return CTS_CLASS (stream)->get_local_address (stream, len);
 }
 
-int 
-camel_tcp_stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+ssize_t 
+camel_tcp_stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len)
 {
-	return CTS_CLASS (stream)->read_nb (stream, buffer, n);
+	return CTS_CLASS (stream)->wait (stream, stop_fd, timeout, buffer, max_len);
 }
 
 
Index: libtinymail-camel/camel-lite/camel/camel-tcp-stream.h
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-tcp-stream.h	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-tcp-stream.h	(working copy)
@@ -106,7 +106,9 @@
 	
 	struct sockaddr * (*get_local_address)  (CamelTcpStream *stream, socklen_t *len);
 	struct sockaddr * (*get_remote_address) (CamelTcpStream *stream, socklen_t *len);
-	ssize_t (*read_nb)   (CamelTcpStream *stream, char *buffer, size_t n);
+
+	ssize_t (*wait) (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len);
+
 } CamelTcpStreamClass;
 
 /* Standard Camel function */
@@ -116,11 +118,11 @@
 int         camel_tcp_stream_connect    (CamelTcpStream *stream, struct addrinfo *host);
 int         camel_tcp_stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
 int         camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
+ssize_t     camel_tcp_stream_wait       (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len);
 
 struct sockaddr *camel_tcp_stream_get_local_address  (CamelTcpStream *stream, socklen_t *len);
 struct sockaddr *camel_tcp_stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
 
-int         camel_tcp_stream_read_nb    (CamelTcpStream *stream, char *buffer, size_t n);
 
 G_END_DECLS
 
Index: libtinymail-camel/camel-lite/camel/camel-file-utils.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-file-utils.c	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-file-utils.c	(working copy)
@@ -798,89 +798,8 @@
 }
 
 
-ssize_t
-camel_read_socket_nb (int fd, char *buf, size_t n)
-{
-#ifndef G_OS_WIN32
-	return camel_read_nb (fd, buf, n);
-#else
-	ssize_t nread;
-	int cancel_fd;
-	
-	if (camel_operation_cancel_check (NULL)) {
-		errno = EINTR;
-		return -1;
-	}
-	cancel_fd = camel_operation_cancel_fd (NULL);
 
-	if (cancel_fd == -1) {
 
-		int fdmax;
-		fd_set rdset;
-		u_long yes = 1;
-
-		ioctlsocket (fd, FIONBIO, &yes);
-		fdmax = fd + 1;
-		do {
-			struct timeval tv;
-			int res;
-
-			FD_ZERO (&rdset);
-			FD_SET (fd, &rdset);
-			tv.tv_sec = NONBLOCKING_READ_TIMEOUT;
-			tv.tv_usec = 0;
-			nread = -1;
-
-			res = select(fdmax, &rdset, 0, 0, &tv);
-			if (res == -1)
-				;
-			else if (res == 0)
-				errno = ETIMEDOUT;
-			} else {				
-				nread = recv (fd, buf, n, 0);
-			}
-		} while (0&&(nread == -1 && WSAGetLastError () == WSAEWOULDBLOCK));
-
-	} else {
-		int fdmax;
-		fd_set rdset;
-		u_long yes = 1;
-
-		ioctlsocket (fd, FIONBIO, &yes);
-		fdmax = MAX (fd, cancel_fd) + 1;
-		do {
-			struct timeval tv;
-			int res;
-
-			FD_ZERO (&rdset);
-			FD_SET (fd, &rdset);
-			FD_SET (cancel_fd, &rdset);
-			tv.tv_sec = NONBLOCKING_READ_TIMEOUT;
-			tv.tv_usec = 0;
-			nread = -1;
-
-			res = select(fdmax, &rdset, 0, 0, &tv);
-			if (res == -1)
-				;
-			else if (res == 0)
-				errno = ETIMEDOUT;
-			else if (FD_ISSET (cancel_fd, &rdset)) {
-				errno = EINTR;
-				goto failed;
-			} else {				
-				nread = recv (fd, buf, n, 0);
-			}
-		} while (0&&(nread == -1 && WSAGetLastError () == WSAEWOULDBLOCK));
-	failed:
-		;
-	}
-	
-	return nread;
-#endif
-}
-
-
-
 /**
  * camel_write_socket:
  * @fd: file descriptor
Index: libtinymail-camel/camel-lite/camel/camel-tcp-stream-raw.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-tcp-stream-raw.c	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-tcp-stream-raw.c	(working copy)
@@ -32,7 +32,12 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <sys/types.h>
 
+#include <glib.h>
+
 #include "camel-file-utils.h"
 #include "camel-operation.h"
 #include "camel-tcp-stream-raw.h"
@@ -64,7 +69,7 @@
 static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
 static struct sockaddr *stream_get_local_address (CamelTcpStream *stream, socklen_t *len);
 static struct sockaddr *stream_get_remote_address (CamelTcpStream *stream, socklen_t *len);
-static ssize_t stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n);
+static ssize_t stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t n);
 
 
 static void
@@ -83,7 +88,7 @@
 	camel_stream_class->flush = stream_flush;
 	camel_stream_class->close = stream_close;
 
-	camel_tcp_stream_class->read_nb = stream_read_nb;
+	camel_tcp_stream_class->wait = stream_wait;
 	camel_tcp_stream_class->connect = stream_connect;
 	camel_tcp_stream_class->getsockopt = stream_getsockopt;
 	camel_tcp_stream_class->setsockopt  = stream_setsockopt;
@@ -95,7 +100,6 @@
 camel_tcp_stream_raw_init (gpointer object, gpointer klass)
 {
 	CamelTcpStreamRaw *stream = CAMEL_TCP_STREAM_RAW (object);
-	
 	stream->sockfd = -1;
 }
 
@@ -103,7 +107,6 @@
 camel_tcp_stream_raw_finalize (CamelObject *object)
 {
 	CamelTcpStreamRaw *stream = CAMEL_TCP_STREAM_RAW (object);
-	
 	if (stream->sockfd != -1)
 		SOCKET_CLOSE (stream->sockfd);
 }
@@ -252,16 +255,40 @@
 stream_read (CamelStream *stream, char *buffer, size_t n)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
-	
+
 	return camel_read_socket (raw->sockfd, buffer, n);
 }
 
 static ssize_t
-stream_read_nb (CamelTcpStream *stream, char *buffer, size_t n)
+stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, size_t max_len)
 {
 	CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
-	
-	return camel_read_socket_nb (raw->sockfd, buffer, n);
+	int fd = raw->sockfd;
+	ssize_t nread;
+	int fdmax;
+	fd_set rdset;
+	u_long yes = 1;
+	struct timeval tv;
+	int res;
+
+	//ioctlsocket (fd, FIONBIO, &yes);
+	fdmax = MAX (fd, stop_fd) + 1;
+
+	FD_ZERO (&rdset);
+	FD_SET (fd, &rdset);
+	FD_SET (stop_fd, &rdset);
+
+	tv.tv_sec = timeout;
+	tv.tv_usec = 0;
+	nread = -1;
+
+	res = select (fdmax, &rdset, 0, 0, &tv);
+	if (res > 0 && !FD_ISSET (stop_fd, &rdset))
+		nread = recv (fd, buffer, max_len, 0);
+	else
+		nread = -1;
+
+	return nread;
 }
 
 static ssize_t
Index: libtinymail-camel/camel-lite/camel/camel-stream-buffer.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-stream-buffer.c	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-stream-buffer.c	(working copy)
@@ -429,49 +429,7 @@
 }
 
 
-int
-camel_tcp_stream_buffer_gets_nb (CamelStreamBuffer *sbf, char *buf, unsigned int max)
-{
-	register char *outptr, *inptr, *inend, c, *outend;
-	int bytes_read;
 
-	outptr = buf;
-	inptr = (char*)sbf->ptr;
-	inend = (char*)sbf->end;
-	outend = buf+max-1;	/* room for NUL */
-
-	do {
-		while (inptr<inend && outptr<outend) {
-			c = *inptr++;
-			*outptr++ = c;
-			if (c == '\n') {
-				*outptr = 0;
-				sbf->ptr = (unsigned char*) inptr;
-				return outptr-buf;
-			}
-		}
-		if (outptr == outend)
-			break;
-
-		bytes_read = camel_tcp_stream_read_nb ((CamelTcpStream *)sbf->stream, (char*)sbf->buf, sbf->size);
-		if (bytes_read == -1) {
-			if (buf == outptr)
-				return -1;
-			else
-				bytes_read = 0;
-		}
-		sbf->ptr = sbf->buf;
-		sbf->end = sbf->buf + bytes_read;
-		inptr = (char*)sbf->ptr;
-		inend = (char*)sbf->end;
-	} while (bytes_read>0);
-
-	sbf->ptr = (unsigned char*)inptr;
-	*outptr = 0;
-
-	return (int)(outptr - buf);
-}
-
 /**
  * camel_stream_buffer_read_line: read a complete line from the stream
  * @sbf: a #CamelStreamBuffer object
Index: libtinymail-camel/camel-lite/camel/camel-stream-buffer.h
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-stream-buffer.h	(revision 2882)
+++ libtinymail-camel/camel-lite/camel/camel-stream-buffer.h	(working copy)
@@ -94,7 +94,6 @@
 int camel_stream_buffer_gets (CamelStreamBuffer *sbf, char *buf, unsigned int max);
 
 char *camel_stream_buffer_read_line (CamelStreamBuffer *sbf);
-int camel_tcp_stream_buffer_gets_nb (CamelStreamBuffer *sbf, char *buf, unsigned int max);
 
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]