Subject: mm_flags()

From: Mike Macgirvin <[email-masked]>
Date: Thu, 12 Jan 1995 16:34:00 -0800 (PST)

I'm trying to figure out how best to manage flag updates with the
3.6-BETA (IMAP2bis) c-client.
	
	I've got mm_flags() set up to put items into a list whenever called. At
check time, or when I know there are going to be changes, I run through the
list and call mail_fetchflags() for everything in the list, then empty it out.
I can't update flags within mm_flags() because the stream is locked.
	Anyway, the act of calling mail_fetchflags() on a message (to get the
changed flags) results in yet another call to mm_flags() by the c-client. I'm
pulling my hair out trying to prevent recursion. An added hassle is that when
the flag changes are of my own doing, I get notified right away, and again at
mail_ping() time. This is an unfortunate duplication of effort I can probably
live with.
	But to prevent recursion, I put a lock into mm_flags which ignores
changes while I'm running through the change list to get the new values. Then I
release the lock. Problem is, there's no way I can distinguish if the
mm_flags() call was the result of my mail_fetchflags() or another process
making changes, which would presumably get reported when the server processes
my fetch request. If I just look for duplicated message numbers, and only add
an item that isn't already in my list, there's the possibility of a race
condition (in fact, a 100% probability thereof). How do other folks manage this
mess?

mike

---

From: Mark Crispin <[email-masked]>
Date: Fri, 13 Jan 1995 11:15:06 +0900 (JST)

The answer to your question is: "don't do it that way".  The code is
working the way it is intended to work; the problem is that you don't seem
to understand what that intention is.  Let's see if this helps: 

mail_fetchflags() is used only to load the client cache.  Once the cache 
is loaded, you don't need to load it again.  In other words, it should be 
considered to be a one-time call -- if it is ever called.  

When mm_flags() is called, it is notifying the client that its cache has
been updated so it should take a look.  So, when you called
mail_fetchflags() after mm_flags(), you discarded the cached data that has
already been set up for you and replaced it with identical data!

All you need to do in response to mm_flags() is get the elt from
mail_elt(), then look at the flag bits there.  I think that it's alright
to call this from mm_flags() since you won't do any stream operations 
that will provoke the lock.

If you're worried about the cache not being set up, you can call 
mail_fetchstructure() as a safety-belt.  mail_fetchstructure() is smart 
enough not to fetch if the cache is already loaded.  However, you can not 
call mail_fetchstructure() from mm_flags().  That's alright, though, 
since you won't get to mm_flags() unless the elt is loaded with flags.  
Just don't assume in mm_flags() that you have the envelope unless that 
has already been fetched.