Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Refactor a bit fetch interface to make it reentrant
Baptiste Daroussin committed 13 years ago
commit 4c426b7aa349f7f8a9e5dedcd5e9e75ca977f784
parent 4e1974d
4 files changed +59 -32
modified libpkg/fetch.c
@@ -43,16 +43,8 @@
#include "private/pkg.h"
#include "private/utils.h"

-
struct http_mirror {
-
	struct url *url;
-
	struct http_mirror *next;
-
};
-

-
static struct dns_srvinfo *srv_mirrors = NULL;
-
static struct http_mirror *http_mirrors = NULL;
-

static void
-
gethttpmirrors(const char *url) {
+
gethttpmirrors(struct pkg_fetch *fetch, const char *url) {
	FILE *f;
	char *line = NULL;
	size_t linecap = 0;
@@ -79,7 +71,7 @@ gethttpmirrors(const char *url) {
			if ((u = fetchParseURL(line)) != NULL) {
				m = malloc(sizeof(struct http_mirror));
				m->url = u;
-
				LL_APPEND(http_mirrors, m);
+
				LL_APPEND(fetch->http, m);
			}
		}
	}
@@ -88,17 +80,39 @@ gethttpmirrors(const char *url) {
}

int
+
pkg_fetch_new(struct pkg_fetch **f)
+
{
+
	if ((*f = calloc(1, sizeof(struct pkg_fetch))) == NULL) {
+
		pkg_emit_errno("calloc", "fetch");
+
		return (EPKG_FATAL);
+
	}
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkg_fetch_free(struct pkg_fetch *f)
+
{
+
	free(f);
+

+
	return (EPKG_OK);
+
}
+

+
int
pkg_fetch_file(const char *url, const char *dest, time_t t)
{
	int fd = -1;
	int retcode = EPKG_FATAL;
+
	struct pkg_fetch *f;

	if ((fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) == -1) {
		pkg_emit_errno("open", dest);
		return(EPKG_FATAL);
	}

-
	retcode = pkg_fetch_file_to_fd(url, fd, &t);
+
	pkg_fetch_new(&f);
+
	retcode = pkg_fetch_file_to_fd(f, url, fd, &t);
+
	pkg_fetch_free(f);

	if (t != 0) {
		struct timeval ftimes[2] = {
@@ -124,7 +138,7 @@ pkg_fetch_file(const char *url, const char *dest, time_t t)
}

int
-
pkg_fetch_file_to_fd(const char *url, int dest, time_t *t)
+
pkg_fetch_file_to_fd(struct pkg_fetch *f, const char *url, int dest, time_t *t)
{
	FILE *remote = NULL;
	struct url *u;
@@ -171,28 +185,24 @@ pkg_fetch_file_to_fd(const char *url, int dest, time_t *t)
				srv = true;
				snprintf(zone, sizeof(zone),
				    "_%s._tcp.%s", u->scheme, u->host);
-
				pthread_mutex_lock(&mirror_mtx);
-
				if (srv_mirrors == NULL)
-
					srv_mirrors = dns_getsrvinfo(zone);
-
				pthread_mutex_unlock(&mirror_mtx);
-
				srv_current = srv_mirrors;
+
				if (f->srv == NULL)
+
					f->srv = dns_getsrvinfo(zone);
+
				srv_current = f->srv;
			} else if (mt != NULL && strncasecmp(mt, "http", 4) == 0 && \
			           strcmp(u->scheme, "file") != 0 && \
			           strcmp(u->scheme, "ftp") != 0) {
				http = true;
				snprintf(zone, sizeof(zone),
				    "%s://%s", u->scheme, u->host);
-
				pthread_mutex_lock(&mirror_mtx);
-
				if (http_mirrors == NULL)
-
					gethttpmirrors(zone);
-
				pthread_mutex_unlock(&mirror_mtx);
-
				http_current = http_mirrors;
+
				if (f->http == NULL)
+
					gethttpmirrors(f, zone);
+
				http_current = f->http;
			}
		}

-
		if (srv && srv_mirrors != NULL)
+
		if (srv && f->srv != NULL)
			strlcpy(u->host, srv_current->host, sizeof(u->host));
-
		else if (http && http_mirrors != NULL) {
+
		else if (http && f->http != NULL) {
			strlcpy(u->scheme, http_current->url->scheme, sizeof(u->scheme));
			strlcpy(u->host, http_current->url->host, sizeof(u->host));
			snprintf(docpath, MAXPATHLEN, "%s%s", http_current->url->doc, doc);
@@ -213,14 +223,14 @@ pkg_fetch_file_to_fd(const char *url, int dest, time_t *t)
				retcode = EPKG_FATAL;
				goto cleanup;
			}
-
			if (srv && srv_mirrors != NULL) {
+
			if (srv && f->srv != NULL) {
				srv_current = srv_current->next;
				if (srv_current == NULL)
-
					srv_current = srv_mirrors;
-
			} else if (http && http_mirrors != NULL) {
-
				http_current = http_mirrors->next;
+
					srv_current = f->srv;
+
			} else if (http && f->http != NULL) {
+
				http_current = f->http->next;
				if (http_current == NULL)
-
					http_current = http_mirrors;
+
					http_current = f->http;
			} else {
				sleep(1);
			}
modified libpkg/pkg_repo.c
@@ -61,6 +61,7 @@ pkg_repo_fetch(struct pkg *pkg)
	bool multirepos_enabled = false;
	int retcode = EPKG_OK;
	const char *repopath, *repourl, *sum, *name, *version;
+
	struct pkg_fetch *f;

	assert((pkg->type & PKG_REMOTE) == PKG_REMOTE);

@@ -111,7 +112,9 @@ pkg_repo_fetch(struct pkg *pkg)
	else
		snprintf(url, sizeof(url), "%s/%s", packagesite, repopath);

+
	pkg_fetch_new(&f);
	retcode = pkg_fetch_file(url, dest, 0);
+
	pkg_fetch_free(f);
	fetched = 1;

	if (retcode != EPKG_OK)
modified libpkg/private/pkg.h
@@ -95,7 +95,6 @@
			return (EPKG_OK);     \
	} while (0)

-
extern pthread_mutex_t mirror_mtx;
extern int eventpipe;

struct pkg {
@@ -250,6 +249,16 @@ struct pkg_abstract {
	UT_hash_handle	 hh;
};

+
struct http_mirror {
+
	struct url *url;
+
	struct http_mirror *next;
+
};
+

+
struct pkg_fetch {
+
	struct dns_srvinfo *srv;
+
	struct http_mirror *http;
+
};
+

/* sql helpers */

typedef struct _sql_prstmt {
@@ -282,7 +291,9 @@ int pkg_delete(struct pkg *pkg, struct pkgdb *db, unsigned flags);
#define PKG_DELETE_UPGRADE (1<<1)
#define PKG_DELETE_NOSCRIPT (1<<2)

-
int pkg_fetch_file_to_fd(const char *url, int dest, time_t *t);
+
int pkg_fetch_new(struct pkg_fetch **f);
+
int pkg_fetch_free(struct pkg_fetch *f);
+
int pkg_fetch_file_to_fd(struct pkg_fetch *f, const char *url, int dest, time_t *t);
int pkg_repo_fetch(struct pkg *pkg);

int pkg_start_stop_rc_scripts(struct pkg *, pkg_rc_attr attr);
modified libpkg/update.c
@@ -74,6 +74,7 @@ repo_fetch_remote_tmp(const char *reponame, const char *filename, const char *ex
	char tmp[MAXPATHLEN];
	int fd;
	const char *tmpdir;
+
	struct pkg_fetch *f;

	snprintf(url, MAXPATHLEN, "%s/%s.%s", reponame, filename, extension);

@@ -91,10 +92,12 @@ repo_fetch_remote_tmp(const char *reponame, const char *filename, const char *ex
	}
	(void)unlink(tmp);

-
	if ((*rc = pkg_fetch_file_to_fd(url, fd, t)) != EPKG_OK) {
+
	pkg_fetch_new(&f);
+
	if ((*rc = pkg_fetch_file_to_fd(f, url, fd, t)) != EPKG_OK) {
		close(fd);
		fd = -1;
	}
+
	pkg_fetch_free(f);

	return (fd);
}