summaryrefslogtreecommitdiff
path: root/src/rmd_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rmd_cache.c')
-rw-r--r--src/rmd_cache.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/src/rmd_cache.c b/src/rmd_cache.c
index db7682e..9e42be3 100644
--- a/src/rmd_cache.c
+++ b/src/rmd_cache.c
@@ -28,18 +28,48 @@
#include "rmd_cache.h"
#include "rmd_specsfile.h"
+#include "rmd_threads.h"
#include "rmd_types.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
+#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#define CACHE_FILE_SIZE_LIMIT (500 * 1024 * 1024)
+/* periodic fdatasync thread for cache writers when fdatasyncing is enabled */
+static void * rmdCacheFileSyncer(CacheFile *file)
+{
+ struct timespec delay;
+ int fd;
+
+ assert(file);
+ assert(file->periodic_datasync_ms);
+
+ rmdThreadsSetName("rmdCacheSyncer");
+
+ delay.tv_sec = file->periodic_datasync_ms / 1000;
+ delay.tv_nsec = (file->periodic_datasync_ms - delay.tv_sec * 1000) * 1000000;
+
+ if (file->gzfp)
+ fd = file->gzfd;
+ else
+ fd = fileno(file->fp);
+
+ for (;;) {
+ nanosleep(&delay, NULL);
+ fdatasync(fd);
+ }
+
+ return NULL;
+}
+
+
/* open file @ path storing the file handles in *file,
* this doesn't store the new path since it's primarily
* for the purposes of opening new chapters for the same
@@ -48,10 +78,12 @@
static int _rmdCacheFileOpen(CacheFile *file, const char *path)
{
const char *modestr = "rb";
+ int flags = O_RDONLY;
assert(file);
if (file->mode == RMD_CACHE_FILE_MODE_WRITE) {
+ flags = O_CREAT|O_WRONLY;
modestr = "wb";
if (file->compressed)
@@ -59,7 +91,12 @@ static int _rmdCacheFileOpen(CacheFile *file, const char *path)
}
if (file->compressed) {
- file->gzfp = gzopen(path, modestr);
+ /* zlib doesn't expose a fileno() equivalent for the syncer */
+ file->gzfd = open(path, flags, S_IRUSR|S_IWUSR);
+ if (file->gzfd < 0)
+ return -1;
+
+ file->gzfp = gzdopen(file->gzfd, modestr);
} else {
file->fp = fopen(path, modestr);
}
@@ -69,6 +106,9 @@ static int _rmdCacheFileOpen(CacheFile *file, const char *path)
file->chapter_n_bytes = 0;
+ if (file->mode == RMD_CACHE_FILE_MODE_WRITE && file->periodic_datasync_ms)
+ pthread_create(&file->syncer_thread, NULL, (void *(*)(void *))rmdCacheFileSyncer, file);
+
return 0;
}
@@ -78,6 +118,11 @@ static int _rmdCacheFileClose(CacheFile *file)
{
assert(file);
+ if (file->mode == RMD_CACHE_FILE_MODE_WRITE && file->periodic_datasync_ms) {
+ pthread_cancel(file->syncer_thread);
+ pthread_join(file->syncer_thread, NULL);
+ }
+
/* TODO: return meaningful -errno on errors? */
if (file->gzfp) {
if (gzclose(file->gzfp) != Z_OK)
@@ -114,8 +159,8 @@ CacheFile * rmdCacheFileOpen(ProgData *pdata, const char *path, CacheFileMode mo
}
f->mode = mode;
- if (!pdata->args.zerocompression)
- f->compressed = 1;
+ f->compressed = !pdata->args.zerocompression;
+ f->periodic_datasync_ms = pdata->args.periodic_datasync_ms;
if (_rmdCacheFileOpen(f, path) < 0)
return NULL;
© All Rights Reserved