From 0203055520206028eecee5d261887cdc91500e15 Mon Sep 17 00:00:00 2001
From: Akira TAGOH <akira@tagoh.org>
Date: Wed, 2 Oct 2013 16:34:34 +0900
Subject: [PATCH] Workaround the race condition issue on updating cache
---
fc-cache/fc-cache.c | 62 ++++++++++++++++++++++++++++---------------------
fontconfig/fontconfig.h | 3 +++
src/fcstr.c | 6 +++++
3 files changed, 45 insertions(+), 26 deletions(-)
diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c
index aeb0af2..af7ba6d 100644
--- a/fc-cache/fc-cache.c
+++ b/fc-cache/fc-cache.c
@@ -118,7 +118,7 @@ usage (char *program, int error)
static FcStrSet *processed_dirs;
static int
-scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, int *changed)
+scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, FcBool recursive, int *changed)
{
int ret = 0;
const FcChar8 *dir;
@@ -141,7 +141,7 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
fflush (stdout);
}
- if (FcStrSetMember (processed_dirs, dir))
+ if (recursive && FcStrSetMember (processed_dirs, dir))
{
if (verbose)
printf ("skipping, looped directory detected\n");
@@ -213,32 +213,37 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
ret++;
}
}
-
- subdirs = FcStrSetCreate ();
- if (!subdirs)
+
+ if (recursive)
{
- fprintf (stderr, "%s: Can't create subdir set\n", dir);
- ret++;
- FcDirCacheUnload (cache);
- continue;
- }
- for (i = 0; i < FcCacheNumSubdir (cache); i++)
- FcStrSetAdd (subdirs, FcCacheSubdir (cache, i));
+ subdirs = FcStrSetCreate ();
+ if (!subdirs)
+ {
+ fprintf (stderr, "%s: Can't create subdir set\n", dir);
+ ret++;
+ FcDirCacheUnload (cache);
+ continue;
+ }
+ for (i = 0; i < FcCacheNumSubdir (cache); i++)
+ FcStrSetAdd (subdirs, FcCacheSubdir (cache, i));
- FcDirCacheUnload (cache);
+ FcDirCacheUnload (cache);
- sublist = FcStrListCreate (subdirs);
- FcStrSetDestroy (subdirs);
- if (!sublist)
- {
- fprintf (stderr, "%s: Can't create subdir list\n", dir);
- ret++;
- continue;
+ sublist = FcStrListCreate (subdirs);
+ FcStrSetDestroy (subdirs);
+ if (!sublist)
+ {
+ fprintf (stderr, "%s: Can't create subdir list\n", dir);
+ ret++;
+ continue;
+ }
+ FcStrSetAdd (processed_dirs, dir);
+ ret += scanDirs (sublist, config, force, really_force, verbose, recursive, changed);
+ FcStrListDone (sublist);
}
- FcStrSetAdd (processed_dirs, dir);
- ret += scanDirs (sublist, config, force, really_force, verbose, changed);
+ else
+ FcDirCacheUnload (cache);
}
- FcStrListDone (list);
return ret;
}
@@ -366,7 +371,11 @@ main (int argc, char **argv)
}
changed = 0;
- ret = scanDirs (list, config, force, really_force, verbose, &changed);
+ ret = scanDirs (list, config, force, really_force, verbose, FcTrue, &changed);
+ /* Update the directory cache again to avoid the race condition as much as possible */
+ FcStrListFirst (list);
+ ret += scanDirs (list, config, FcTrue, really_force, verbose, FcFalse, &changed);
+ FcStrListDone (list);
/*
* Try to create CACHEDIR.TAG anyway.
@@ -379,6 +388,8 @@ main (int argc, char **argv)
cleanCacheDirectories (config, verbose);
+ FcConfigDestroy (config);
+ FcFini ();
/*
* Now we need to sleep a second (or two, to be extra sure), to make
* sure that timestamps for changes after this run of fc-cache are later
@@ -386,8 +397,7 @@ main (int argc, char **argv)
* sleep(3) can't be interrupted by a signal here -- this isn't in the
* library, and there aren't any signals flying around here.
*/
- FcConfigDestroy (config);
- FcFini ();
+ /* the resolution of mtime on FAT is 2 seconds */
if (changed)
sleep (1);
if (verbose)
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 58912f5..e588579 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -974,6 +974,9 @@ FcStrSetDestroy (FcStrSet *set);
FcPublic FcStrList *
FcStrListCreate (FcStrSet *set);
+FcPublic void
+FcStrListFirst (FcStrList *list);
+
FcPublic FcChar8 *
FcStrListNext (FcStrList *list);
diff --git a/src/fcstr.c b/src/fcstr.c
index 3a32031..5707172 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -1374,6 +1374,12 @@ FcStrListCreate (FcStrSet *set)
return list;
}
+void
+FcStrListFirst (FcStrList *list)
+{
+ list->n = 0;
+}
+
FcChar8 *
FcStrListNext (FcStrList *list)
{
--
1.8.3.1
From 9a4310176bb11e1e826d238eb0761b7895b48883 Mon Sep 17 00:00:00 2001
From: Akira TAGOH <akira@tagoh.org>
Date: Wed, 9 Oct 2013 12:19:35 +0900
Subject: [PATCH] Add missing doc for FcStrListFirst and fix a typo
---
doc/fcstrset.fncs | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/doc/fcstrset.fncs b/doc/fcstrset.fncs
index 737347b..b96489a 100644
--- a/doc/fcstrset.fncs
+++ b/doc/fcstrset.fncs
@@ -98,12 +98,20 @@ Destroys <parameter>set</parameter>.
Creates an iterator to list the strings in <parameter>set</parameter>.
@@
+@RET@ void
+@FUNC@ FcStrListFirst
+@TYPE1@ FcStrList * @ARG1@ list
+@PURPOSE@ get first string in iteration
+@DESC@
+Returns the first string in <parameter>list</parameter>.
+@@
+
@RET@ FcChar8 *
@FUNC@ FcStrListNext
@TYPE1@ FcStrList * @ARG1@ list
@PURPOSE@ get next string in iteration
@DESC@
-Returns the next string in <parameter>set</parameter>.
+Returns the next string in <parameter>list</parameter>.
@@
@RET@ void
--
1.8.3.1