0455f7a71d
Apply a patch to make it MT-safe more.
229 lines
7.2 KiB
Diff
229 lines
7.2 KiB
Diff
From c9862b6ea7c3234b29f6500c7d07359847e55ed7 Mon Sep 17 00:00:00 2001
|
|
From: Akira TAGOH <akira@tagoh.org>
|
|
Date: Mon, 28 Oct 2019 17:11:38 +0900
|
|
Subject: [PATCH 1/9] Read latest cache in paths
|
|
|
|
Right now fontconfig uses a cache found first in a path and
|
|
cachedirs are the order of the system-wide path and then the user path.
|
|
this is due to avoid writing caches into the user path when running as root.
|
|
|
|
However, changing caches by certain config only, e.g. using <match target="scan">
|
|
may not take effect by this behavior, because it may be stored into the user path.
|
|
|
|
Thus, needing to find the latest cache out from paths.
|
|
|
|
Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/issues/182
|
|
---
|
|
src/fccache.c | 36 +++++++++++++++++++++-----
|
|
test/run-test.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
2 files changed, 96 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/fccache.c b/src/fccache.c
|
|
index 0976201..4acde22 100644
|
|
--- a/src/fccache.c
|
|
+++ b/src/fccache.c
|
|
@@ -338,7 +338,7 @@ FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat)
|
|
static FcBool
|
|
FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat,
|
|
- struct stat *dir_stat, void *closure),
|
|
+ struct stat *dir_stat, struct timeval *cache_mtime, void *closure),
|
|
void *closure, FcChar8 **cache_file_ret)
|
|
{
|
|
int fd = -1;
|
|
@@ -348,6 +348,7 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
struct stat file_stat, dir_stat;
|
|
FcBool ret = FcFalse;
|
|
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
|
+ struct timeval latest_mtime = (struct timeval){ 0 };
|
|
|
|
if (sysroot)
|
|
d = FcStrBuildFilename (sysroot, dir, NULL);
|
|
@@ -383,15 +384,18 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
#endif
|
|
fd = FcDirCacheOpenFile (cache_hashed, &file_stat);
|
|
if (fd >= 0) {
|
|
- ret = (*callback) (config, fd, &file_stat, &dir_stat, closure);
|
|
+ ret = (*callback) (config, fd, &file_stat, &dir_stat, &latest_mtime, closure);
|
|
close (fd);
|
|
if (ret)
|
|
{
|
|
if (cache_file_ret)
|
|
+ {
|
|
+ if (*cache_file_ret)
|
|
+ FcStrFree (*cache_file_ret);
|
|
*cache_file_ret = cache_hashed;
|
|
+ }
|
|
else
|
|
FcStrFree (cache_hashed);
|
|
- break;
|
|
}
|
|
}
|
|
#ifndef _WIN32
|
|
@@ -414,7 +418,8 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
}
|
|
}
|
|
#endif
|
|
- FcStrFree (cache_hashed);
|
|
+ else
|
|
+ FcStrFree (cache_hashed);
|
|
}
|
|
FcStrListDone (list);
|
|
|
|
@@ -998,12 +1003,31 @@ FcDirCacheUnload (FcCache *cache)
|
|
}
|
|
|
|
static FcBool
|
|
-FcDirCacheMapHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure)
|
|
+FcDirCacheMapHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, struct timeval *latest_cache_mtime, void *closure)
|
|
{
|
|
FcCache *cache = FcDirCacheMapFd (config, fd, fd_stat, dir_stat);
|
|
+ struct timeval cache_mtime;
|
|
|
|
if (!cache)
|
|
return FcFalse;
|
|
+ cache_mtime.tv_sec = fd_stat->st_mtime;
|
|
+#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
|
+ cache_mtime.tv_usec = fd_stat->st_mtim.tv_nsec / 1000;
|
|
+#else
|
|
+ cache_mtime.tv_usec = 0;
|
|
+#endif
|
|
+ if (timercmp (latest_cache_mtime, &cache_mtime, <))
|
|
+ {
|
|
+ if (*((FcCache **) closure))
|
|
+ FcDirCacheUnload (*((FcCache **) closure));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ FcDirCacheUnload (cache);
|
|
+ return FcFalse;
|
|
+ }
|
|
+ latest_cache_mtime->tv_sec = cache_mtime.tv_sec;
|
|
+ latest_cache_mtime->tv_usec = cache_mtime.tv_usec;
|
|
*((FcCache **) closure) = cache;
|
|
return FcTrue;
|
|
}
|
|
@@ -1093,7 +1117,7 @@ FcDirChecksumNano (struct stat *statb)
|
|
* the magic number and the size field
|
|
*/
|
|
static FcBool
|
|
-FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED)
|
|
+FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, struct timeval *latest_cache_mtime, void *closure FC_UNUSED)
|
|
{
|
|
FcBool ret = FcTrue;
|
|
FcCache c;
|
|
diff --git a/test/run-test.sh b/test/run-test.sh
|
|
index 4e5968b..8ad09e3 100644
|
|
--- a/test/run-test.sh
|
|
+++ b/test/run-test.sh
|
|
@@ -340,6 +340,72 @@ fi
|
|
|
|
rm -rf $MyPWD/sysroot
|
|
|
|
+dotest "read newer caches when multiple places are allowed to store"
|
|
+prep
|
|
+cp $FONT1 $FONT2 $FONTDIR
|
|
+if [ -n ${SOURCE_DATE_EPOCH:-} ] && [ ${#SOURCE_DATE_EPOCH} -gt 0 ]; then
|
|
+ touch -m -t "`date -d \"@${SOURCE_DATE_EPOCH}\" +%y%m%d%H%M.%S`" $FONTDIR
|
|
+fi
|
|
+MYCACHEBASEDIR=`mktemp -d /tmp/fontconfig.XXXXXXXX`
|
|
+MYCACHEDIR=$MYCACHEBASEDIR/cache.dir
|
|
+MYOWNCACHEDIR=$MYCACHEBASEDIR/owncache.dir
|
|
+MYCONFIG=`mktemp /tmp/fontconfig.XXXXXXXX`
|
|
+
|
|
+mkdir -p $MYCACHEDIR
|
|
+mkdir -p $MYOWNCACHEDIR
|
|
+
|
|
+sed "s!@FONTDIR@!$FONTDIR!
|
|
+s!@REMAPDIR@!!
|
|
+s!@CACHEDIR@!$MYCACHEDIR!" < $TESTDIR/fonts.conf.in > my-fonts.conf
|
|
+
|
|
+FONTCONFIG_FILE=$MyPWD/my-fonts.conf $FCCACHE $FONTDIR
|
|
+
|
|
+sleep 1
|
|
+cat<<EOF>$MYCONFIG
|
|
+<fontconfig>
|
|
+ <match target="scan">
|
|
+ <test name="file"><string>$FONTDIR/4x6.pcf</string></test>
|
|
+ <edit name="pixelsize"><int>8</int></edit>
|
|
+ </match>
|
|
+</fontconfig>
|
|
+EOF
|
|
+sed "s!@FONTDIR@!$FONTDIR!
|
|
+s!@REMAPDIR@!<include ignore_missing=\"yes\">$MYCONFIG</include>!
|
|
+s!@CACHEDIR@!$MYOWNCACHEDIR!" < $TESTDIR/fonts.conf.in > my-fonts.conf
|
|
+
|
|
+if [ -n ${SOURCE_DATE_EPOCH:-} ]; then
|
|
+ old_epoch=${SOURCE_DATE_EPOCH}
|
|
+ SOURCE_DATE_EPOCH=`expr $SOURCE_DATE_EPOCH + 1`
|
|
+fi
|
|
+FONTCONFIG_FILE=$MyPWD/my-fonts.conf $FCCACHE -f $FONTDIR
|
|
+if [ -n ${SOURCE_DATE_EPOCH:-} ]; then
|
|
+ SOURCE_DATE_EPOCH=${old_epoch}
|
|
+fi
|
|
+
|
|
+sed "s!@FONTDIR@!$FONTDIR!
|
|
+s!@REMAPDIR@!<include ignore_missing=\"yes\">$MYCONFIG</include>!
|
|
+s!@CACHEDIR@!$MYCACHEDIR</cachedir><cachedir>$MYOWNCACHEDIR!" < $TESTDIR/fonts.conf.in > my-fonts.conf
|
|
+
|
|
+FONTCONFIG_FILE=$MyPWD/my-fonts.conf $FCLIST - family pixelsize | sort > my-out
|
|
+echo "=" >> my-out
|
|
+FONTCONFIG_FILE=$MyPWD/my-fonts.conf $FCLIST - family pixelsize | sort >> my-out
|
|
+echo "=" >> my-out
|
|
+FONTCONFIG_FILE=$MyPWD/my-fonts.conf $FCLIST - family pixelsize | sort >> my-out
|
|
+tr -d '\015' <my-out >my-out.tmp; mv my-out.tmp my-out
|
|
+sed -e 's/pixelsize=6/pixelsize=8/g' $BUILDTESTDIR/$EXPECTED > my-out.expected
|
|
+
|
|
+if cmp my-out my-out.expected > /dev/null ; then : ; else
|
|
+ echo "*** Test failed: $TEST"
|
|
+ echo "*** output is in 'my-out', expected output in 'my-out.expected'"
|
|
+ echo "Actual Result"
|
|
+ cat my-out
|
|
+ echo "Expected Result"
|
|
+ cat my-out.expected
|
|
+ exit 1
|
|
+fi
|
|
+
|
|
+rm -rf $MYCACHEBASEDIR $MYCONFIG my-fonts.conf my-out my-out.expected
|
|
+
|
|
fi # if [ "x$EXEEXT" = "x" ]
|
|
|
|
rm -rf $FONTDIR $CACHEFILE $CACHEDIR $BASEDIR $FONTCONFIG_FILE out
|
|
--
|
|
2.24.1
|
|
|
|
From a45fc8a33256d9d3ea0ea7947f33c8e5e3cc7238 Mon Sep 17 00:00:00 2001
|
|
From: Akira TAGOH <akira@tagoh.org>
|
|
Date: Thu, 31 Oct 2019 16:15:25 +0900
|
|
Subject: [PATCH 2/9] Fix a memory leak caused by the previous commit
|
|
|
|
---
|
|
src/fccache.c | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/src/fccache.c b/src/fccache.c
|
|
index 4acde22..c565560 100644
|
|
--- a/src/fccache.c
|
|
+++ b/src/fccache.c
|
|
@@ -397,6 +397,8 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
else
|
|
FcStrFree (cache_hashed);
|
|
}
|
|
+ else
|
|
+ FcStrFree (cache_hashed);
|
|
}
|
|
#ifndef _WIN32
|
|
else if (!retried)
|
|
@@ -416,6 +418,8 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
|
|
break;
|
|
goto retry;
|
|
}
|
|
+ else
|
|
+ FcStrFree (cache_hashed);
|
|
}
|
|
#endif
|
|
else
|
|
--
|
|
2.24.1
|
|
|