Re: [Evolution-hackers] Let the porting begin

2007-11-20 Thread Philip Van Hoof
On Thu, 2007-10-25 at 22:25 -0400, Jeffrey Stedfast wrote:
> On Fri, 2007-10-26 at 03:25 +0200, Philip Van Hoof wrote:
> > On Wed, 2007-10-24 at 11:58 -0400, Jeffrey Stedfast wrote:
> > > I took a look at the IDLE implementation last night and felt it went
> > > about it the wrong way.
> > 
> > Yes, you are right. I think the right fix is to create a new API called
> > camel_tcp_stream_wait that works like this:
> > 
> > 
> > int bytes = camel_tcp_stream_wait (tcp_stream, stop_fd,
> >  store->idle_sleep, line_buffer, 1023);
> [snip]
> 
> I was thinking more along the lines of making the idle_loop use
> PRPoll()/poll() itself - it already has to figure out what type of fd to
> create for the cancel_idle_fd anyway.

I have it more or less working, with one more problem remaining (and I
already tried fixing it, check the "line_buffer" stuff in this patch)
being that the read returns me a block of bytes, not lines.

Yet I need to feed the rest of the current IDLE handling code exact
lines (untagged lines that start with '*').

So my plan is to use strrchr(buffer, '\n') and with the result calculate
where the last full line was. Then add that to what we stored last time.
And store the remainder in a buffer for the next loop.

Then with the two pieces together, strtok_r on \n and get the full lines
ouf of that.

I already started this, but I'm going to sleep now :)

Attached ... (it's again on Tinymail's trunk, not on Camel upstream)

> > Afaics It's not true that you don't need to change any API:
> > 
> > The camel_stream_read() will block until all n bytes are read.
> 
> no it doesn't. it returns as soon as any number of bytes are read or an
> error occurs.
> 
> >  This is
> > something you don't know during IDLE (how many bytes you can expect to
> > receive), and on top of that you want to continue immediately after
> > select returns, not keep retrying until you have n bytes (to simulate a
> > blocking read).
> 
> sure, but that's why you poll yourself. once the socket has data, /then/
> you call camel_stream_read() on it.
> 
> >  You also want a dedicated stop fildescriptor, not the
> > standard cancel_fd as then any cancel will interfere with this (while
> > you want strict control over this to let other threads start and stop
> > IDLE).
> 
> right, but if you add a CamelStream API, then you have to add 1 for unix
> fds and 1 for PRFileDesc
> 
> plus it keeps the code simpler (keeps all read() logic in the
> camel_stream_read() implementations rather than duplicating it).
> 
> 
> This actually brings me to another thought I've had for a few years now
> but haven't bothered pushing for it... but it might be best if all of
> the sockets used PRFileDesc rather than unix fd for raw sockets and
> PRFileDesc for SSL sockets. If this is done, I think it'd be possible to
> get rid of CamelTcpStreamRaw and move the implementation into
> CamelTcpStream and make CamelTcpStreamSSL a simple subclass of
> CamelTcpStream, replacing the CamelTcpStream's PRFileDesc with an
> SSL-wrapped fd as appropriate and calling parent_class->read/write/etc
> instead of implementing them all itself /again/.
> 
> 
> Jeff
> 
> 
-- 
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,46 +197,31 @@
 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)
+	idle_debug ("let_idle_die starts\n");
+	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");
 		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)

Re: [Evolution-hackers] Let the porting begin

2007-11-20 Thread Philip Van Hoof
On Wed, 2007-10-24 at 11:58 -0400, Jeffrey Stedfast wrote:
> I took a look at the IDLE implementation last night and felt it went
> about it the wrong way.

Yes, you are right. I think the right fix is to create a new API called
camel_tcp_stream_wait that works like this:


int bytes = camel_tcp_stream_wait (tcp_stream, stop_fd,
 store->idle_sleep, line_buffer, 1023);

I need the amount of read-read bytes, to know where the buffer stops, so
I return it. I need a stop_fd to get the select() to early-stop. I need
a timeout for in case of connection problems. I need the buffer to put
the newly read data in and I need a size to tell it how large my buffer
max is.


.. idle_thread () ..
{

  start_idle (store);
  line_buffer = malloc (1024)
  memset (line_buffer, 0, sizeof (*line_buffer));
  ...

  while (store->idle_cont)  {
char *lasts = NULL;
int bytes = camel_tcp_stream_wait (tcp_stream, stop_fd, 
store->idle_sleep, line_buffer, 1023);

if (bytes > 0) {
char *resp;
line_buffer[bytes+1] = '\0';

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++;
}
}
printf ("IDLE: read %d bytes %s\n", bytes, line_buffer);
}

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) {
process_idle_response (idle_resp);
idle_response_free (idle_resp);
idle_resp = NULL;
printf ("Processed %d lines\n", lines);
lines = 0;
}
if (stopped)
idle_start (store);
}
memset (line_buffer, 0, sizeof (*line_buffer));
  }
}

That "wait" is implemented like this:


static ssize_t
stream_wait (CamelTcpStream *stream, int stop_fd, int timeout, char *buffer, 
size_t max_len)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
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;
}


Afaics It's not true that you don't need to change any API:

The camel_stream_read() will block until all n bytes are read. This is
something you don't know during IDLE (how many bytes you can expect to
receive), and on top of that you want to continue immediately after
select returns, not keep retrying until you have n bytes (to simulate a
blocking read). You also want a dedicated stop fildescriptor, not the
standard cancel_fd as then any cancel will interfere with this (while
you want strict control over this to let other threads start and stop
IDLE).

Well ... let me put it this way: I tried it from a few angles, I didn't
succeed with the normal camel_stream_read :-(

I have reworked the IDLE implementation. You can apply this patch to
Tinymail's upstream (trunk). You most likely can't apply it to upstream
Camel. (http://svn.tinymail.org/svn/tinymail/trunk)

There's still one problem: sometimes camel_imap_folder_stop_idle is not
returning late enough (the socket is still in IDLE state when it
returns).

Other than that, it usually works.

I'm trying to fix this last problem right now, and after that there will
most likely be a few days of testing before I put this in Tinymail's
repository.


> You should simply poll() on the socket descriptors (and a pipe fd used
> for telling the IDLE thread's I/O loop to finish and send DONE).

Yep


> Jeff
> 
> On Mon, 2007-10-08 at 00:41 +0200, Philip Van Hoof wrote:
> > On Sun, 2007-10-07 at 14:15 +0200, Philip Van Hoof wrote:
> > > Hi there,
> > 
> > > Using this changeset you can follow the changes to camel-lite:
> > > 
> > >   http://tinymail.org/trac/tinymail/changeset/2823
> > > 
> > 
> > This changeset are a bunch of compilation warnings for Matthew's Base64
> > patch to Camel: http://t

Re: [Evolution-hackers] Let the porting begin

2007-10-25 Thread Jeffrey Stedfast

On Fri, 2007-10-26 at 03:25 +0200, Philip Van Hoof wrote:
> On Wed, 2007-10-24 at 11:58 -0400, Jeffrey Stedfast wrote:
> > I took a look at the IDLE implementation last night and felt it went
> > about it the wrong way.
> 
> Yes, you are right. I think the right fix is to create a new API called
> camel_tcp_stream_wait that works like this:
> 
> 
> int bytes = camel_tcp_stream_wait (tcp_stream, stop_fd,
>store->idle_sleep, line_buffer, 1023);
[snip]

I was thinking more along the lines of making the idle_loop use
PRPoll()/poll() itself - it already has to figure out what type of fd to
create for the cancel_idle_fd anyway.

> 
> Afaics It's not true that you don't need to change any API:
> 
> The camel_stream_read() will block until all n bytes are read.

no it doesn't. it returns as soon as any number of bytes are read or an
error occurs.

>  This is
> something you don't know during IDLE (how many bytes you can expect to
> receive), and on top of that you want to continue immediately after
> select returns, not keep retrying until you have n bytes (to simulate a
> blocking read).

sure, but that's why you poll yourself. once the socket has data, /then/
you call camel_stream_read() on it.

>  You also want a dedicated stop fildescriptor, not the
> standard cancel_fd as then any cancel will interfere with this (while
> you want strict control over this to let other threads start and stop
> IDLE).

right, but if you add a CamelStream API, then you have to add 1 for unix
fds and 1 for PRFileDesc

plus it keeps the code simpler (keeps all read() logic in the
camel_stream_read() implementations rather than duplicating it).


This actually brings me to another thought I've had for a few years now
but haven't bothered pushing for it... but it might be best if all of
the sockets used PRFileDesc rather than unix fd for raw sockets and
PRFileDesc for SSL sockets. If this is done, I think it'd be possible to
get rid of CamelTcpStreamRaw and move the implementation into
CamelTcpStream and make CamelTcpStreamSSL a simple subclass of
CamelTcpStream, replacing the CamelTcpStream's PRFileDesc with an
SSL-wrapped fd as appropriate and calling parent_class->read/write/etc
instead of implementing them all itself /again/.


Jeff


___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] Let the porting begin

2007-10-24 Thread Philip Van Hoof
On Wed, 2007-10-24 at 11:58 -0400, Jeffrey Stedfast wrote:
> I took a look at the IDLE implementation last night and felt it went
> about it the wrong way.

Note that the IDLE implementation got changed (reimplemented) this
morning.

Although the same problems that you mention here still apply.

I also added some comments. The poll() idea is indeed something that at
some point I should refactor the loop to.

> Firstly, the added camel_stream_[read,write]_nb() and
> camel_stream_read_idle() functionality is totally unnecessary and just
> makes the camel stream API gross (not to mention duplicating a lot of
> code as there's no real difference from the normal read/write
> implementations other than the timeout).
> 
> You should simply poll() on the socket descriptors (and a pipe fd used
> for telling the IDLE thread's I/O loop to finish and send DONE).
> 
> Jeff
> 
> On Mon, 2007-10-08 at 00:41 +0200, Philip Van Hoof wrote:
> > On Sun, 2007-10-07 at 14:15 +0200, Philip Van Hoof wrote:
> > > Hi there,
> > 
> > > Using this changeset you can follow the changes to camel-lite:
> > > 
> > >   http://tinymail.org/trac/tinymail/changeset/2823
> > > 
> > 
> > This changeset are a bunch of compilation warnings for Matthew's Base64
> > patch to Camel: http://tinymail.org/trac/tinymail/changeset/2827
> > 
> > 
> > ps. Adding Matthew in CC.
> > 
> 
-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog




___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] Let the porting begin

2007-10-24 Thread Jeffrey Stedfast
I took a look at the IDLE implementation last night and felt it went
about it the wrong way.

Firstly, the added camel_stream_[read,write]_nb() and
camel_stream_read_idle() functionality is totally unnecessary and just
makes the camel stream API gross (not to mention duplicating a lot of
code as there's no real difference from the normal read/write
implementations other than the timeout).

You should simply poll() on the socket descriptors (and a pipe fd used
for telling the IDLE thread's I/O loop to finish and send DONE).

Jeff

On Mon, 2007-10-08 at 00:41 +0200, Philip Van Hoof wrote:
> On Sun, 2007-10-07 at 14:15 +0200, Philip Van Hoof wrote:
> > Hi there,
> 
> > Using this changeset you can follow the changes to camel-lite:
> > 
> > http://tinymail.org/trac/tinymail/changeset/2823
> > 
> 
> This changeset are a bunch of compilation warnings for Matthew's Base64
> patch to Camel: http://tinymail.org/trac/tinymail/changeset/2827
> 
> 
> ps. Adding Matthew in CC.
> 

___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] Let the porting begin

2007-10-07 Thread Philip Van Hoof
On Sun, 2007-10-07 at 14:15 +0200, Philip Van Hoof wrote:
> Hi there,

> Using this changeset you can follow the changes to camel-lite:
> 
>   http://tinymail.org/trac/tinymail/changeset/2823
> 

This changeset are a bunch of compilation warnings for Matthew's Base64
patch to Camel: http://tinymail.org/trac/tinymail/changeset/2827


ps. Adding Matthew in CC.

-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog




___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


Re: [Evolution-hackers] Let the porting begin

2007-10-07 Thread Philip Van Hoof
On Sun, 2007-10-07 at 14:15 +0200, Philip Van Hoof wrote:
> Hi there,

> Using this changeset you can follow the changes to camel-lite:
> 
>   http://tinymail.org/trac/tinymail/changeset/2823

More such commits to Tinymail's camel-lite happened today. Nearly all of
those are merging work in action. After today, using KDiff3 or any other
tool that can recursively compare two directories should be painless and
straight forward on ./libtinymail-camel/camel-lite/camel
vs. ./evolution-data-server/camel


-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog




___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers


[Evolution-hackers] Let the porting begin

2007-10-07 Thread Philip Van Hoof
Hi there,

I got notified that some Evolution hackers are interested in bringing
the features of camel-lite to camel. This is of course excellent news!

To ease this process, I pushed all the recent changes that happened to
camel, to camel-lite. These changes include the copyright's address
changes, the changes Matthew Barnes did on the BASE64 decoding, most of
the compiler-warning changes (although a lot of them had already been
put in camel-lite, of course), Kjartan Maraas's 0 vs. NULL changes,
Milan Crha's changes (set-label, compiler warnings, etc).

Using this changeset you can follow the changes to camel-lite:

http://tinymail.org/trac/tinymail/changeset/2823


Note about compiler warnings: camel-lite contains fixes for -pedantic
warnings. When making differences, you might find compiler-warning fixes
that you wouldn't expect with -Wall. Camel-lite right now has two or
three things that are problematic and not yet fixed for -pedantic:

 - Enumerations that exceed the size of an int, which are not allowed in
   ANSI C (or C99, I don't remember exactly).

 - Casting function pointers to (void*) which also isn't allowed (but I
   have no idea how else I can store them in a GHashTable, which is what
   Camel is doing at some locations)


Some of the changes to camel-lite might not be welcomed to camel. Among
them I expect the changes to camel-object not to be interested (some of
these changes cut one or two bytes from the CamelObject's size and put
some more and also less locking-on-signal-emissions in place). Others
are more clear like features that are just not interesting. And yet
others are just not done in a clean way.

On future plans for camel-lite: I'm interested in implementing QRSYNC
next to the CONDSTORE support. Although only one IMAP server already
supports this (Isode's Mbox).


-- 
Philip Van Hoof, software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://www.pvanhoof.be/blog




___
Evolution-hackers mailing list
Evolution-hackers@gnome.org
http://mail.gnome.org/mailman/listinfo/evolution-hackers