commit - d52aad142172d4a9c6219ac2f685a90832fa0838
commit + b5c757f5f816a8061f4879da9e68a39141148e40
blob - c9025f9b0c09acff3245e5476c5242711a24a7b7
blob + 7520e71fd4327bf9eb5df008f47f25845a44564e
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
if (html && fcgi_printf(c, "</div>\n") == -1)
return;
done:
- if (c->t->repo != NULL && qs && qs->action != INDEX)
- got_repo_close(c->t->repo);
if (html && srv != NULL)
gotweb_render_footer(c);
}
gotweb_free_repo_dir(repo_dir);
repo_dir = NULL;
- error = got_repo_close(t->repo);
- if (error)
- goto done;
t->next_disp++;
if (d_disp == srv->max_repos_display)
break;
return error;
}
+static struct got_repository *
+find_cached_repo(struct server *srv, const char *path)
+{
+ int i;
+
+ for (i = 0; i < srv->ncached_repos; i++) {
+ if (strcmp(srv->cached_repos[i].path, path) == 0)
+ return srv->cached_repos[i].repo;
+ }
+
+ return NULL;
+}
+
static const struct got_error *
+cache_repo(struct got_repository **new, struct server *srv,
+ struct repo_dir *repo_dir, struct socket *sock)
+{
+ const struct got_error *error = NULL;
+ struct got_repository *repo;
+ struct cached_repo *cr;
+ int evicted = 0;
+
+ if (srv->ncached_repos >= nitems(srv->cached_repos)) {
+ cr = &srv->cached_repos[srv->ncached_repos - 1];
+ error = got_repo_close(cr->repo);
+ memset(cr, 0, sizeof(*cr));
+ srv->ncached_repos--;
+ if (error)
+ return error;
+ memmove(&srv->cached_repos[1], &srv->cached_repos[0],
+ srv->ncached_repos * sizeof(srv->cached_repos[0]));
+ cr = &srv->cached_repos[0];
+ evicted = 1;
+ } else {
+ cr = &srv->cached_repos[srv->ncached_repos];
+ }
+
+ error = got_repo_open(&repo, repo_dir->path, NULL, sock->pack_fds);
+ if (error) {
+ if (evicted) {
+ memmove(&srv->cached_repos[0], &srv->cached_repos[1],
+ srv->ncached_repos * sizeof(srv->cached_repos[0]));
+ }
+ return error;
+ }
+
+ if (strlcpy(cr->path, repo_dir->path, sizeof(cr->path))
+ >= sizeof(cr->path)) {
+ if (evicted) {
+ memmove(&srv->cached_repos[0], &srv->cached_repos[1],
+ srv->ncached_repos * sizeof(srv->cached_repos[0]));
+ }
+ return got_error(GOT_ERR_NO_SPACE);
+ }
+
+ cr->repo = repo;
+ srv->ncached_repos++;
+ *new = repo;
+ return NULL;
+}
+
+static const struct got_error *
gotweb_load_got_path(struct request *c, struct repo_dir *repo_dir)
{
const struct got_error *error = NULL;
struct socket *sock = c->sock;
struct server *srv = c->srv;
struct transport *t = c->t;
+ struct got_repository *repo = NULL;
DIR *dt;
char *dir_test;
int opened = 0;
} else
opened = 1;
done:
- error = got_repo_open(&t->repo, repo_dir->path, NULL, sock->pack_fds);
- if (error)
- goto err;
+ repo = find_cached_repo(srv, repo_dir->path);
+ if (repo == NULL) {
+ error = cache_repo(&repo, srv, repo_dir, sock);
+ if (error)
+ goto err;
+ }
+ t->repo = repo;
error = gotweb_get_repo_description(&repo_dir->description, srv,
repo_dir->path);
if (error)
blob - ae08f3df1ae9fb58a5fac19a6fcfd02a1aad9247
blob + 74ee67ae6734f6af0af3ab58f3276ceeccc8863a
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
#define GOTWEBD_MAXPORT 6
#define GOTWEBD_NUMPROC 3
#define GOTWEBD_MAXIFACE 16
+#define GOTWEBD_REPO_CACHESIZE 4
/* GOTWEB DEFAULTS */
#define MAX_QUERYSTRING 2048
};
TAILQ_HEAD(addresslist, address);
+struct cached_repo {
+ char path[PATH_MAX];
+ struct got_repository *repo;
+};
+
struct server {
TAILQ_ENTRY(server) entry;
struct addresslist al;
+ struct cached_repo cached_repos[GOTWEBD_REPO_CACHESIZE];
+ int ncached_repos;
+
char name[GOTWEBD_MAXTEXT];
char repos_path[PATH_MAX];
blob - 7e510af9c4ae6f2609874519758443d006c1afc3
blob + c0691c5575dca8c931af0e8e30d9e086b5a5bccc
--- gotwebd/sockets.c
+++ gotwebd/sockets.c
#include "got_error.h"
#include "got_opentemp.h"
+#include "got_repository.h"
#include "proc.h"
#include "gotwebd.h"
{
struct server *srv, *tsrv;
struct socket *sock, *tsock;
+ int i;
sockets_purge(gotwebd_env);
}
/* clean servers */
- TAILQ_FOREACH_SAFE(srv, &gotwebd_env->servers, entry, tsrv)
+ TAILQ_FOREACH_SAFE(srv, &gotwebd_env->servers, entry, tsrv) {
+ for (i = 0; i < srv->ncached_repos; i++)
+ got_repo_close(srv->cached_repos[i].repo);
free(srv);
+ }
free(gotwebd_env);
}