Radish alpha
H
HardenedBSD Package Manager
Radicle
Git (anonymous pull)
Log in to clone via SSH
Added lock infrastructure.
jlaffaye committed 15 years ago
commit 9ce0ecad62de9feb5c358bd4dab1ce0ac73e0fb8
parent d38de67a59e4294caad96fb04a2ab090d3861d54
5 files changed +57 -13
modified libpkg/pkg.h
@@ -29,6 +29,7 @@ struct pkgdb {
	size_t i;
	struct cdb db;
	unsigned char flags;
+
	int lock_fd;
};

#define PKGDB_FOREACH(pkg, db) for ((db)->i = 0, (pkg) = (db)->pkgs[0]; \
modified libpkg/pkgdb.c
@@ -1,3 +1,7 @@
+
#include <sys/file.h>
+

+
#include <err.h>
+
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -5,11 +9,48 @@
#include "pkgdb.h"
#include "pkgdb_cache.h"

+
#define LOCK_FILE "lock"
+

+
/*
+
 * Acquire a lock to access the database.
+
 * If `writer' is set to 1, an exclusive lock is requested so it wont mess up
+
 * with other writers or readers.
+
 */
+
void
+
pkgdb_lock(struct pkgdb *db, int writer)
+
{
+
	char fname[FILENAME_MAX];
+
	int flags;
+

+
	snprintf(fname, sizeof(fname), "%s/%s", pkgdb_get_dir(), LOCK_FILE);
+
	if ((db->lock_fd = open(fname, O_RDONLY | O_CREAT)) < 0)
+
		err(EXIT_FAILURE, "open(%s)", fname);
+

+
	if (writer == 1)
+
		flags = LOCK_EX;
+
	else
+
		flags = LOCK_SH;
+

+
	if (flock(db->lock_fd, flags) < 0)
+
		errx(EXIT_FAILURE, "unable to acquire a lock to the database");
+
}
+

+
void
+
pkgdb_unlock(struct pkgdb *db)
+
{
+
	flock(db->lock_fd, LOCK_UN);
+
	close(db->lock_fd);
+
	db->lock_fd = -1;
+
}
+

void
pkgdb_init(struct pkgdb *db, const char *pattern, match_t match, unsigned char flags) {
	/* first check if the cache has to be rebuild */
-
	pkgdb_cache_update();
+
	pkgdb_cache_update(db);
+

+
	pkgdb_lock(db, 0);
	pkgdb_cache_init(db, pattern, match, flags);
+
	pkgdb_unlock(db);
}

static void
modified libpkg/pkgdb.h
@@ -12,9 +12,13 @@ typedef enum _match_t {
	MATCH_EREGEX
} match_t;

+
void pkgdb_lock(struct pkgdb *db, int write);
+
void pkgdb_unlock(struct pkgdb *db);
+

+
const char * pkgdb_get_dir(void);
+

void pkgdb_init(struct pkgdb *db, const char *pattern, match_t match, unsigned char flags);
void pkgdb_free(struct pkgdb *db);
size_t pkgdb_count(struct pkgdb *db);
-
const char * pkgdb_get_dir(void);

#endif
modified libpkg/pkgdb_cache.c
@@ -363,7 +363,7 @@ pkgdb_cache_rebuild(const char *pkg_dbdir, const char *cache_path)
}

void
-
pkgdb_cache_update()
+
pkgdb_cache_update(struct pkgdb *db)
{
	const char *pkg_dbdir;
	char cache_path[MAXPATHLEN];
@@ -385,17 +385,15 @@ pkgdb_cache_update()

	snprintf(cache_path, sizeof(cache_path), "%s/pkgdb.cache", pkg_dbdir);

-
	if (stat(cache_path, &cache_st) == -1) {
-
		if (errno == ENOENT) {
-
			pkgdb_cache_rebuild(pkg_dbdir, cache_path);
-
			return;
-
		}
-
		else
-
			err(EXIT_FAILURE, "%s:", cache_path);
-
	}
+
	errno = 0; /* Reset it in case it is set to ENOENT */
+
	if (stat(cache_path, &cache_st) == -1 && errno != ENOENT)
+
		err(EXIT_FAILURE, "%s:", cache_path);

-
	if ( dir_st.st_mtime > cache_st.st_mtime )
+
	if (errno == ENOENT || dir_st.st_mtime > cache_st.st_mtime) {
+
		pkgdb_lock(db, 1);
		pkgdb_cache_rebuild(pkg_dbdir, cache_path);
+
		pkgdb_unlock(db);
+
	}
}

static int
modified libpkg/pkgdb_cache.h
@@ -15,7 +15,7 @@
	} while (0)


-
void pkgdb_cache_update(void);
+
void pkgdb_cache_update(struct pkgdb *db);
void pkgdb_cache_init(struct pkgdb *db, const char *pattern, match_t match, unsigned char flags);

#endif