Lock the cache file until scanning and writing finished. (#1236034)

This commit is contained in:
Akira TAGOH 2015-08-13 11:30:59 +09:00
parent 17d3f99b1a
commit 2f41965718
2 changed files with 152 additions and 1 deletions

145
fontconfig-lock-cache.patch Normal file
View File

@ -0,0 +1,145 @@
diff --git a/src/fccache.c b/src/fccache.c
index fc3ed41..5a8720b 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -1142,6 +1142,70 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
return ret;
}
+int
+FcDirCacheLock (const FcChar8 *dir,
+ FcConfig *config)
+{
+ FcChar8 *cache_hashed = NULL;
+ FcChar8 cache_base[CACHEBASE_LEN];
+ FcStrList *list;
+ FcChar8 *cache_dir;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ int fd = -1;
+
+ FcDirCacheBasename (dir, cache_base);
+ list = FcStrListCreate (config->cacheDirs);
+ if (!list)
+ return -1;
+
+ while ((cache_dir = FcStrListNext (list)))
+ {
+ if (sysroot)
+ cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL);
+ else
+ cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
+ if (!cache_hashed)
+ break;
+ fd = FcOpen ((const char *)cache_hashed, O_RDWR);
+ /* No caches in that directory. simply retry with another one */
+ if (fd != -1)
+ {
+ struct flock fl;
+
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = getpid ();
+ if (fcntl (fd, F_SETLKW, &fl) == -1)
+ goto bail;
+ break;
+ }
+ }
+ return fd;
+bail:
+ if (fd != -1)
+ close (fd);
+ return -1;
+}
+
+void
+FcDirCacheUnlock (int fd)
+{
+ struct flock fl;
+
+ if (fd != -1)
+ {
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = getpid ();
+ fcntl (fd, F_SETLK, &fl);
+ close (fd);
+ }
+}
+
/*
* Hokey little macro trick to permit the definitions of C functions
* with the same name as CPP macros
diff --git a/src/fcdir.c b/src/fcdir.c
index 2e7f0dc..f4807dd 100644
--- a/src/fcdir.c
+++ b/src/fcdir.c
@@ -332,6 +332,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
struct stat dir_stat;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d;
+ int fd = -1;
if (sysroot)
d = FcStrBuildFilename (sysroot, dir, NULL);
@@ -352,6 +353,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
if (!dirs)
goto bail1;
+ fd = FcDirCacheLock (dir, config);
/*
* Scan the dir
*/
@@ -371,6 +373,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
FcDirCacheWrite (cache, config);
bail2:
+ FcDirCacheUnlock (fd);
FcStrSetDestroy (dirs);
bail1:
FcFontSetDestroy (set);
@@ -389,6 +392,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
FcStrSet *dirs;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d = NULL;
+ int fd = -1;
cache = FcDirCacheLoad (dir, config, NULL);
if (!cache)
@@ -404,6 +408,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
if (!dirs)
goto bail;
+ fd = FcDirCacheLock (dir, config);
/*
* Scan the dir
*/
@@ -422,6 +427,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
FcDirCacheWrite (new, config);
bail1:
+ FcDirCacheUnlock (fd);
FcStrSetDestroy (dirs);
bail:
if (d)
diff --git a/src/fcint.h b/src/fcint.h
index 15e22fd..76becec 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -590,6 +590,13 @@ FcCacheFini (void);
FcPrivate void
FcDirCacheReference (FcCache *cache, int nref);
+FcPrivate int
+FcDirCacheLock (const FcChar8 *dir,
+ FcConfig *config);
+
+FcPrivate void
+FcDirCacheUnlock (int fd);
+
/* fccfg.c */
FcPrivate FcBool

View File

@ -3,7 +3,7 @@
Summary: Font configuration and customization library
Name: fontconfig
Version: 2.11.94
Release: 2%{?dist}
Release: 3%{?dist}
# src/ftglue.[ch] is in Public Domain
# src/fccache.c contains Public Domain code
# fc-case/CaseFolding.txt is in the UCD
@ -16,6 +16,8 @@ Source1: 25-no-bitmap-fedora.conf
# https://bugzilla.redhat.com/show_bug.cgi?id=140335
Patch0: %{name}-sleep-less.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1236034
Patch1: %{name}-lock-cache.patch
BuildRequires: expat-devel
BuildRequires: freetype-devel >= %{freetype_version}
@ -58,6 +60,7 @@ which is useful for developing applications that uses fontconfig.
%prep
%setup -q
%patch0 -p1 -b .sleep-less
%patch1 -p1 -b .lock-cache
%build
# We don't want to rebuild the docs, but we want to install the included ones.
@ -134,6 +137,9 @@ fi
%doc fontconfig-devel.txt fontconfig-devel
%changelog
* Wed Aug 12 2015 Akira TAGOH <tagoh@redhat.com> - 2.11.94-3
- Lock the cache file until scanning and writing finished. (#1236034)
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.11.94-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild