From: Ken Hornstein Date: Mon, 18 Mar 2013 19:29:35 +0000 (-0400) Subject: Add code for (and convert world to) the new world lock order. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/6b4bc4a25eaac2eddd1bef51e3f00c21f98ed32d?ds=inline;hp=-c Add code for (and convert world to) the new world lock order. Still need to add some code to make inc and pick behave better (not hold locks for as long). --- 6b4bc4a25eaac2eddd1bef51e3f00c21f98ed32d diff --git a/h/mh.h b/h/mh.h index daf47c02..c5246f29 100644 --- a/h/mh.h +++ b/h/mh.h @@ -205,6 +205,18 @@ struct msgs { * in a particular sequence. */ seqset_t *msgstats; /* msg status */ + + /* + * A FILE handle containing an open filehandle for the sequence file + * for this folder. If non-NULL, use it when the sequence file is + * written. + */ + FILE *seqhandle; + + /* + * The name of the public sequence file; required by lkfclose() + */ + char *seqname; }; /* diff --git a/h/prototypes.h b/h/prototypes.h index 14b12528..484bef28 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -66,7 +66,19 @@ int folder_addmsg (struct msgs **, char *, int, int, int, int, char *); int folder_delmsgs (struct msgs *, int, int); void folder_free (struct msgs *); int folder_pack (struct msgs **, int); -struct msgs *folder_read (char *); + +/* + * Read a MH folder structure and return an allocated "struct msgs" + * corresponding to the contents of the folder. + * + * Arguments include: + * + * name - Name of folder + * lockflag - If true, write-lock (and keep open) metadata files. + * See comments for seq_read() for more information. + */ +struct msgs *folder_read (char *name, int lockflag); + struct msgs *folder_realloc (struct msgs *, int, int); int gans (char *, struct swit *); char **getans (char *, struct swit *); @@ -152,7 +164,21 @@ char *seq_list (struct msgs *, char *); int seq_nameok (char *); void seq_print (struct msgs *, char *); void seq_printall (struct msgs *); -void seq_read (struct msgs *); + +/* + * Read the sequence files for the folder referenced in the given + * struct msgs and populate the sequence entries in the struct msgs. + * + * Arguments: + * + * mp - Folder structure to add sequence entries to + * lockflag - If true, obtain a write lock on the sequence file. + * Additionally, the sequence file will remain open + * and a pointer to the filehandle will be stored in + * folder structure, where it will later be used by + * seq_save(). + */ +void seq_read (struct msgs * mp, int lockflag); void seq_save (struct msgs *); void seq_setcur (struct msgs *, int); void seq_setprev (struct msgs *); diff --git a/sbr/folder_free.c b/sbr/folder_free.c index ebb58ab4..7f87ccd4 100644 --- a/sbr/folder_free.c +++ b/sbr/folder_free.c @@ -25,6 +25,14 @@ folder_free (struct msgs *mp) for (i = 0; mp->msgattrs[i]; i++) free (mp->msgattrs[i]); + /* Close/free the sequence file if it is open */ + + if (mp->seqhandle) + lkfclosedata (mp->seqhandle, mp->seqname); + + if (mp->seqname) + free (mp->seqname); + free (mp->msgstats); /* free message status area */ free (mp); /* free main folder structure */ } diff --git a/sbr/folder_read.c b/sbr/folder_read.c index 29204484..02271bc6 100644 --- a/sbr/folder_read.c +++ b/sbr/folder_read.c @@ -23,7 +23,7 @@ */ struct msgs * -folder_read (char *name) +folder_read (char *name, int lockflag) { int msgnum, prefix_len, len, *mi; struct msgs *mp; @@ -54,6 +54,8 @@ folder_read (char *name) mp->hghsel = 0; mp->numsel = 0; mp->nummsg = 0; + mp->seqhandle = NULL; + mp->seqname = NULL; if (access (name, W_OK) == -1) set_readonly (mp); @@ -151,7 +153,7 @@ folder_read (char *name) /* * Read and initialize the sequence information. */ - seq_read (mp); + seq_read (mp, lockflag); return mp; } diff --git a/sbr/m_draft.c b/sbr/m_draft.c index e4791869..a8c973d2 100644 --- a/sbr/m_draft.c +++ b/sbr/m_draft.c @@ -38,7 +38,7 @@ m_draft (char *folder, char *msg, int use, int *isdf) if (chdir (buffer) == -1) adios (buffer, "unable to change directory to"); - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* diff --git a/sbr/seq_read.c b/sbr/seq_read.c index 2bea5367..eea27512 100644 --- a/sbr/seq_read.c +++ b/sbr/seq_read.c @@ -15,7 +15,7 @@ * static prototypes */ static int seq_init (struct msgs *, char *, char *); -static void seq_public (struct msgs *); +static void seq_public (struct msgs *, int); static void seq_private (struct msgs *); @@ -26,7 +26,7 @@ static void seq_private (struct msgs *); */ void -seq_read (struct msgs *mp) +seq_read (struct msgs *mp, int lockflag) { /* * Initialize the list of sequence names. Go ahead and @@ -41,7 +41,7 @@ seq_read (struct msgs *mp) return; /* Initialize the public sequences */ - seq_public (mp); + seq_public (mp, lockflag); /* Initialize the private sequences */ seq_private (mp); @@ -53,7 +53,7 @@ seq_read (struct msgs *mp) */ static void -seq_public (struct msgs *mp) +seq_public (struct msgs *mp, int lockflag) { int state; char *cp, seqfile[PATH_MAX]; @@ -73,7 +73,7 @@ seq_public (struct msgs *mp) /* get filename of sequence file */ snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq); - if ((fp = lkfopendata (seqfile, "r")) == NULL) + if ((fp = lkfopendata (seqfile, lockflag ? "r+" : "r")) == NULL) return; /* Use m_getfld to scan sequence file */ @@ -96,7 +96,8 @@ seq_public (struct msgs *mp) } continue; - case BODY: + case BODY: + lkfclosedata (fp, seqfile); adios (NULL, "no blank lines are permitted in %s", seqfile); /* fall */ @@ -104,13 +105,19 @@ seq_public (struct msgs *mp) break; default: + lkfclosedata (fp, seqfile); adios (NULL, "%s is poorly formatted", seqfile); } break; /* break from for loop */ } m_getfld_state_destroy (&gstate); - lkfclosedata (fp, seqfile); + if (lockflag) { + mp->seqhandle = fp; + mp->seqname = getcpy(seqfile); + } else { + lkfclosedata (fp, seqfile); + } } diff --git a/sbr/seq_save.c b/sbr/seq_save.c index 837b4bab..3c53e4bc 100644 --- a/sbr/seq_save.c +++ b/sbr/seq_save.c @@ -30,8 +30,11 @@ seq_save (struct msgs *mp) sigset_t set, oset; /* check if sequence information has changed */ - if (!(mp->msgflags & SEQMOD)) + if (!(mp->msgflags & SEQMOD)) { + if (mp->seqhandle) + lkfclosedata (mp->seqhandle, mp->seqname); return; + } mp->msgflags &= ~SEQMOD; fp = NULL; @@ -74,7 +77,15 @@ priv: * If that fails (probably because folder is * readonly), then make sequence private. */ - if ((fp = lkfopendata (seqfile, "w")) == NULL + + if (mp->seqhandle) { + fp = mp->seqhandle; + mp->seqhandle = NULL; + free(mp->seqname); + mp->seqname = NULL; + rewind(fp); + ftruncate(fileno(fp), 0); + } else if ((fp = lkfopendata (seqfile, "w")) == NULL && (unlink (seqfile) == -1 || (fp = lkfopendata (seqfile, "w")) == NULL)) { admonish (attr, "unable to write"); diff --git a/uip/anno.c b/uip/anno.c index cf52021c..d18713ae 100644 --- a/uip/anno.c +++ b/uip/anno.c @@ -240,7 +240,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/burst.c b/uip/burst.c index e4792335..34ef10b0 100644 --- a/uip/burst.c +++ b/uip/burst.c @@ -158,7 +158,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/comp.c b/uip/comp.c index 416a8854..be7968d1 100644 --- a/uip/comp.c +++ b/uip/comp.c @@ -256,7 +256,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ @@ -267,6 +267,7 @@ main (int argc, char **argv) if (!m_convert (mp, msg)) done (1); seq_setprev (mp); /* set the previous-sequence */ + seq_save (mp); if (mp->numsel > 1) adios (NULL, "only one message at a time!"); diff --git a/uip/dist.c b/uip/dist.c index 3d247181..d3ceaec2 100644 --- a/uip/dist.c +++ b/uip/dist.c @@ -281,7 +281,7 @@ try_it_again: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/flist.c b/uip/flist.c index 1444acaf..d0945fce 100644 --- a/uip/flist.c +++ b/uip/flist.c @@ -468,7 +468,7 @@ AddFolder(char *name, int force) struct msgs *mp; /* Read folder and create message structure */ - if (!(mp = folder_read (name))) { + if (!(mp = folder_read (name, 0))) { /* Oops, error occurred. Record it and continue. */ AllocFolders(&folders, &nFoldersAlloced, nFolders + 1); f = &folders[nFolders++]; diff --git a/uip/fmttest.c b/uip/fmttest.c index dafdbdb8..8b81924b 100644 --- a/uip/fmttest.c +++ b/uip/fmttest.c @@ -507,7 +507,7 @@ process_messages(struct format *fmt, struct msgs_array *comps, if (chdir(maildir) < 0) adios(maildir, "unable to change directory to"); - if (!(mp = folder_read(folder))) + if (!(mp = folder_read(folder, 1))) adios(NULL, "unable to read folder %s", folder); if (mp->nummsg == 0) diff --git a/uip/folder.c b/uip/folder.c index e4defc70..29ef616a 100644 --- a/uip/folder.c +++ b/uip/folder.c @@ -403,7 +403,7 @@ get_folder_info_body (char *fold, char *msg, boolean *crawl_children) /* * create message structure and get folder info */ - if (!(mp = folder_read (fold))) { + if (!(mp = folder_read (fold, 1))) { admonish (NULL, "unable to read folder %s", fold); return 0; } diff --git a/uip/forw.c b/uip/forw.c index 18a4f03b..45fb740f 100644 --- a/uip/forw.c +++ b/uip/forw.c @@ -363,7 +363,7 @@ try_it_again: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/inc.c b/uip/inc.c index 6f7f5946..2b4c7ce9 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -515,7 +515,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); go_to_it: diff --git a/uip/mark.c b/uip/mark.c index f99832a2..cc5a7133 100644 --- a/uip/mark.c +++ b/uip/mark.c @@ -159,7 +159,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* print some general debugging info */ diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index 8bac6d37..459a2559 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -753,7 +753,7 @@ use_forw: if (!folder) folder = add (getfolder (1), NULL); - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); for (ap = arguments; *ap; ap++) { cp = *ap; diff --git a/uip/mhlist.c b/uip/mhlist.c index 6ab50e39..38060739 100644 --- a/uip/mhlist.c +++ b/uip/mhlist.c @@ -278,7 +278,7 @@ do_cache: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/mhn.c b/uip/mhn.c index a5a7b05e..ced10f2e 100644 --- a/uip/mhn.c +++ b/uip/mhn.c @@ -512,7 +512,7 @@ do_cache: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/mhpath.c b/uip/mhpath.c index ef16bce2..3a0a628b 100644 --- a/uip/mhpath.c +++ b/uip/mhpath.c @@ -91,7 +91,7 @@ main(int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* diff --git a/uip/mhshow.c b/uip/mhshow.c index f5666b07..76a0d022 100644 --- a/uip/mhshow.c +++ b/uip/mhshow.c @@ -336,7 +336,7 @@ do_cache: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/mhstore.c b/uip/mhstore.c index 1865f14c..cd84aeef 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -304,7 +304,7 @@ do_cache: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index b978dbfb..6badafeb 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -872,7 +872,7 @@ output_content_folder (char *folder, char *filename) struct msgs *mp; /* Read the folder. */ - if ((mp = folder_read (folder))) { + if ((mp = folder_read (folder, 0))) { /* Link file into folder */ msgnum = folder_addmsg (&mp, filename, 0, 0, 0, 0, (char *)0); } else { diff --git a/uip/mhtest.c b/uip/mhtest.c index cf7f8642..aa6d8e43 100644 --- a/uip/mhtest.c +++ b/uip/mhtest.c @@ -270,7 +270,7 @@ do_cache: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/msh.c b/uip/msh.c index 2a562f00..c1f0fc3a 100644 --- a/uip/msh.c +++ b/uip/msh.c @@ -604,7 +604,7 @@ fsetup (char *folder) padios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) padios (NULL, "unable to read folder %s", folder); /* check for empty folder */ @@ -831,7 +831,7 @@ check_folder (int scansw) low = mp->hghmsg + 1; folder_free (mp); /* free folder/message structure */ - if (!(mp = folder_read (fmsh))) + if (!(mp = folder_read (fmsh, 0))) padios (NULL, "unable to re-read folder %s", fmsh); hgh = mp->hghmsg; diff --git a/uip/packf.c b/uip/packf.c index 53e696af..d82ef782 100644 --- a/uip/packf.c +++ b/uip/packf.c @@ -138,7 +138,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to "); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/pick.c b/uip/pick.c index 5549ea64..281a1ac7 100644 --- a/uip/pick.c +++ b/uip/pick.c @@ -193,7 +193,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/rcvstore.c b/uip/rcvstore.c index 3afe12e3..9a89230e 100644 --- a/uip/rcvstore.c +++ b/uip/rcvstore.c @@ -193,7 +193,7 @@ main (int argc, char **argv) /* * read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* diff --git a/uip/refile.c b/uip/refile.c index 54b6e5f8..8dd04fb9 100644 --- a/uip/refile.c +++ b/uip/refile.c @@ -195,7 +195,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read source folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ @@ -282,7 +282,7 @@ opnfolds (struct st_fold *folders, int nfolders) if (chdir (nmaildir) == NOTOK) adios (nmaildir, "unable to change directory to"); - if (!(mp = folder_read (fp->f_name))) + if (!(mp = folder_read (fp->f_name, 1))) adios (NULL, "unable to read folder %s", fp->f_name); mp->curmsg = 0; diff --git a/uip/repl.c b/uip/repl.c index e8d64907..840b7620 100644 --- a/uip/repl.c +++ b/uip/repl.c @@ -386,7 +386,7 @@ try_it_again: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/rmm.c b/uip/rmm.c index d96622ed..02a55910 100644 --- a/uip/rmm.c +++ b/uip/rmm.c @@ -94,7 +94,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/scan.c b/uip/scan.c index 459fcb07..2996a2b5 100644 --- a/uip/scan.c +++ b/uip/scan.c @@ -201,7 +201,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/send.c b/uip/send.c index 510047a0..8a659222 100644 --- a/uip/send.c +++ b/uip/send.c @@ -350,7 +350,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (dfolder))) + if (!(mp = folder_read (dfolder, 1))) adios (NULL, "unable to read folder %s", dfolder); /* check for empty folder */ diff --git a/uip/sendsbr.c b/uip/sendsbr.c index e3a8195f..2a5ad829 100644 --- a/uip/sendsbr.c +++ b/uip/sendsbr.c @@ -1064,7 +1064,7 @@ annoaux (int fd) admonish (maildir, "unable to change directory to"); return; } - if (!(mp = folder_read (folder))) { + if (!(mp = folder_read (folder, 0))) { if (debugsw) admonish (NULL, "unable to read folder %s", folder); return; diff --git a/uip/show.c b/uip/show.c index dc426130..b73e56a8 100644 --- a/uip/show.c +++ b/uip/show.c @@ -221,7 +221,7 @@ usage: adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ diff --git a/uip/sortm.c b/uip/sortm.c index 6e7a7491..ea6b805e 100644 --- a/uip/sortm.c +++ b/uip/sortm.c @@ -199,7 +199,7 @@ main (int argc, char **argv) adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */