From 0203055520206028eecee5d261887cdc91500e15 Mon Sep 17 00:00:00 2001 From: Akira TAGOH 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 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 set. Creates an iterator to list the strings in set. @@ +@RET@ void +@FUNC@ FcStrListFirst +@TYPE1@ FcStrList * @ARG1@ list +@PURPOSE@ get first string in iteration +@DESC@ +Returns the first string in list. +@@ + @RET@ FcChar8 * @FUNC@ FcStrListNext @TYPE1@ FcStrList * @ARG1@ list @PURPOSE@ get next string in iteration @DESC@ -Returns the next string in set. +Returns the next string in list. @@ @RET@ void -- 1.8.3.1