summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2008-12-10 07:16:51 -0700
committerEric Blake <ebb9@byu.net>2008-12-15 08:07:10 -0700
commit64df649442038cace6b063fa5bd36c7007193dcc (patch)
treed0f0abda4d456859fee3c480fc73dab079db49e9
parentc28c0d455f7e28ee1bac21ab398dbe3d010b502a (diff)
downloadm4-64df649442038cace6b063fa5bd36c7007193dcc.tar.gz
Double size of temp file cache.
* m4/output.c (tmp_file, tmp_file_owner): Split... (tmp_file1, tmp_file2, tmp_file1_owner, tmp_file2_owner): ...into two variables. (tmp_file2_recent): New variable. (m4_tmpopen, m4_tmpclose, m4_tmpremove, m4_tmprename) (m4_output_exit): Adjust callers. Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r--ChangeLog8
-rw-r--r--m4/output.c88
2 files changed, 75 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 04aefd61..a73ba6e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2008-12-15 Eric Blake <ebb9@byu.net>
+ Double size of temp file cache.
+ * m4/output.c (tmp_file, tmp_file_owner): Split...
+ (tmp_file1, tmp_file2, tmp_file1_owner, tmp_file2_owner): ...into
+ two variables.
+ (tmp_file2_recent): New variable.
+ (m4_tmpopen, m4_tmpclose, m4_tmpremove, m4_tmprename)
+ (m4_output_exit): Adjust callers.
+
Use fewer seeks on cached files.
* m4/output.c (m4_tmpfile): Use write, not append mode.
(m4_tmpopen): Add parameter to decide when to skip seeks.
diff --git a/m4/output.c b/m4/output.c
index 61ddfbb3..baea127f 100644
--- a/m4/output.c
+++ b/m4/output.c
@@ -112,11 +112,16 @@ static size_t output_unused;
/* Temporary directory holding all spilled diversion files. */
static m4_temp_dir *output_temp_dir;
-/* Cache of most recently used spilled diversion file. */
-static FILE *tmp_file;
+/* Cache of most recently used spilled diversion files. */
+static FILE *tmp_file1;
+static FILE *tmp_file2;
-/* Diversion that owns tmp_file, or 0. */
-static int tmp_file_owner;
+/* Diversions that own tmp_file, or 0. */
+static int tmp_file1_owner;
+static int tmp_file2_owner;
+
+/* True if tmp_file2 is more recently used. */
+static bool tmp_file2_recent;
/* Internal routines. */
@@ -242,12 +247,21 @@ m4_tmpopen (m4 *context, int divnum, bool reread)
const char *name;
FILE *file;
- if (tmp_file_owner == divnum)
+ if (tmp_file1_owner == divnum)
+ {
+ if (reread && fseeko (tmp_file1, 0, SEEK_SET) != 0)
+ m4_error (context, EXIT_FAILURE, errno, NULL,
+ _("cannot seek within diversion"));
+ tmp_file2_recent = false;
+ return tmp_file1;
+ }
+ else if (tmp_file2_owner == divnum)
{
- if (reread && fseeko (tmp_file, 0, SEEK_SET) != 0)
+ if (reread && fseeko (tmp_file2, 0, SEEK_SET) != 0)
m4_error (context, EXIT_FAILURE, errno, NULL,
_("cannot seek to beginning of diversion"));
- return tmp_file;
+ tmp_file2_recent = true;
+ return tmp_file2;
}
name = m4_tmpname (divnum);
/* We need update mode, to avoid truncation. */
@@ -274,12 +288,22 @@ static int
m4_tmpclose (FILE *file, int divnum)
{
int result = 0;
- if (divnum != tmp_file_owner)
+ if (divnum != tmp_file1_owner && divnum != tmp_file2_owner)
{
- if (tmp_file_owner)
- result = close_stream_temp (tmp_file);
- tmp_file = file;
- tmp_file_owner = divnum;
+ if (tmp_file2_recent)
+ {
+ if (tmp_file1_owner)
+ result = close_stream_temp (tmp_file1);
+ tmp_file1 = file;
+ tmp_file1_owner = divnum;
+ }
+ else
+ {
+ if (tmp_file2_owner)
+ result = close_stream_temp (tmp_file2);
+ tmp_file2 = file;
+ tmp_file2_owner = divnum;
+ }
}
return result;
}
@@ -288,12 +312,19 @@ m4_tmpclose (FILE *file, int divnum)
static int
m4_tmpremove (int divnum)
{
- if (divnum == tmp_file_owner)
+ if (divnum == tmp_file1_owner)
+ {
+ int result = close_stream_temp (tmp_file1);
+ if (result)
+ return result;
+ tmp_file1_owner = 0;
+ }
+ else if (divnum == tmp_file2_owner)
{
- int result = close_stream_temp (tmp_file);
+ int result = close_stream_temp (tmp_file2);
if (result)
return result;
- tmp_file_owner = 0;
+ tmp_file2_owner = 0;
}
return cleanup_temp_file (output_temp_dir, m4_tmpname (divnum));
}
@@ -308,17 +339,30 @@ m4_tmprename (m4 *context, int oldnum, int newnum)
char *oldname = xstrdup (m4_tmpname (oldnum));
const char *newname = m4_tmpname (newnum);
register_temp_file (output_temp_dir, newname);
- if (oldnum == tmp_file_owner)
+ if (oldnum == tmp_file1_owner)
+ {
+ /* Be careful of mingw, which can't rename an open file. */
+ if (RENAME_OPEN_FILE_WORKS)
+ tmp_file1_owner = newnum;
+ else
+ {
+ if (close_stream_temp (tmp_file1))
+ m4_error (context, EXIT_FAILURE, errno, NULL,
+ _("cannot close temporary file for diversion"));
+ tmp_file1_owner = 0;
+ }
+ }
+ else if (oldnum == tmp_file2_owner)
{
/* Be careful of mingw, which can't rename an open file. */
if (RENAME_OPEN_FILE_WORKS)
- tmp_file_owner = newnum;
+ tmp_file2_owner = newnum;
else
{
- if (close_stream_temp (tmp_file))
+ if (close_stream_temp (tmp_file2))
m4_error (context, EXIT_FAILURE, errno, NULL,
_("cannot close temporary file for diversion"));
- tmp_file_owner = 0;
+ tmp_file2_owner = 0;
}
}
/* Either it is safe to rename an open file, or no one should have
@@ -355,8 +399,10 @@ m4_output_exit (void)
as an atexit handler, and it must not traverse stale memory. */
gl_oset_t table = diversion_table;
assert (gl_oset_size (diversion_table) == 0);
- if (tmp_file_owner)
- m4_tmpremove (tmp_file_owner);
+ if (tmp_file1_owner)
+ m4_tmpremove (tmp_file1_owner);
+ if (tmp_file2_owner)
+ m4_tmpremove (tmp_file2_owner);
diversion_table = NULL;
gl_oset_free (table);
obstack_free (&diversion_storage, NULL);