mirror of
https://github.com/git-for-windows/git.git
synced 2026-04-09 23:33:34 -05:00
Merge branch 'ps/reftable-portability'
Update reftable library part with what is used in libgit2 to improve portability to different target codebases and platforms. * ps/reftable-portability: reftable/system: add abstraction to mmap files reftable/system: add abstraction to retrieve time in milliseconds reftable/fsck: use REFTABLE_UNUSED instead of UNUSED reftable/stack: provide fsync(3p) via system header reftable: introduce "reftable-system.h" header
This commit is contained in:
@@ -366,11 +366,6 @@ static int reftable_be_config(const char *var, const char *value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reftable_be_fsync(int fd)
|
||||
{
|
||||
return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
|
||||
}
|
||||
|
||||
static struct ref_store *reftable_be_init(struct repository *repo,
|
||||
const char *payload,
|
||||
const char *gitdir,
|
||||
@@ -408,7 +403,6 @@ static struct ref_store *reftable_be_init(struct repository *repo,
|
||||
refs->write_options.disable_auto_compact =
|
||||
!git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
|
||||
refs->write_options.lock_timeout_ms = 100;
|
||||
refs->write_options.fsync = reftable_be_fsync;
|
||||
|
||||
repo_config(the_repository, reftable_be_config, &refs->write_options);
|
||||
|
||||
|
||||
@@ -93,13 +93,12 @@ void block_source_from_buf(struct reftable_block_source *bs,
|
||||
}
|
||||
|
||||
struct file_block_source {
|
||||
uint64_t size;
|
||||
unsigned char *data;
|
||||
struct reftable_mmap mmap;
|
||||
};
|
||||
|
||||
static uint64_t file_size(void *b)
|
||||
{
|
||||
return ((struct file_block_source *)b)->size;
|
||||
return ((struct file_block_source *)b)->mmap.size;
|
||||
}
|
||||
|
||||
static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_data *dest REFTABLE_UNUSED)
|
||||
@@ -109,7 +108,7 @@ static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_dat
|
||||
static void file_close(void *v)
|
||||
{
|
||||
struct file_block_source *b = v;
|
||||
munmap(b->data, b->size);
|
||||
reftable_munmap(&b->mmap);
|
||||
reftable_free(b);
|
||||
}
|
||||
|
||||
@@ -117,8 +116,8 @@ static ssize_t file_read_data(void *v, struct reftable_block_data *dest, uint64_
|
||||
uint32_t size)
|
||||
{
|
||||
struct file_block_source *b = v;
|
||||
assert(off + size <= b->size);
|
||||
dest->data = b->data + off;
|
||||
assert(off + size <= b->mmap.size);
|
||||
dest->data = (unsigned char *) b->mmap.data + off;
|
||||
dest->len = size;
|
||||
return size;
|
||||
}
|
||||
@@ -156,13 +155,9 @@ int reftable_block_source_from_file(struct reftable_block_source *bs,
|
||||
goto out;
|
||||
}
|
||||
|
||||
p->size = st.st_size;
|
||||
p->data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (p->data == MAP_FAILED) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
p->data = NULL;
|
||||
err = reftable_mmap(&p->mmap, fd, st.st_size);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
assert(!bs->ops);
|
||||
bs->ops = &file_vtable;
|
||||
|
||||
@@ -63,7 +63,7 @@ static int table_check_name(struct reftable_table *table,
|
||||
|
||||
static int table_checks(struct reftable_table *table,
|
||||
reftable_fsck_report_fn report_fn,
|
||||
reftable_fsck_verbose_fn verbose_fn UNUSED,
|
||||
reftable_fsck_verbose_fn verbose_fn REFTABLE_UNUSED,
|
||||
void *cb_data)
|
||||
{
|
||||
table_check_fn table_check_fns[] = {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef REFTABLE_BASICS_H
|
||||
#define REFTABLE_BASICS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "reftable-system.h"
|
||||
|
||||
/* A buffer that contains arbitrary byte slices. */
|
||||
struct reftable_buf {
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
#ifndef REFTABLE_BLOCK_H
|
||||
#define REFTABLE_BLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-basics.h"
|
||||
#include "reftable-blocksource.h"
|
||||
#include "reftable-iterator.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef REFTABLE_BLOCKSOURCE_H
|
||||
#define REFTABLE_BLOCKSOURCE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "reftable-system.h"
|
||||
|
||||
/*
|
||||
* Generic wrapper for a seekable readable file.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#ifndef REFTABLE_ERROR_H
|
||||
#define REFTABLE_ERROR_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
|
||||
/*
|
||||
* Errors in reftable calls are signaled with negative integer return values. 0
|
||||
* means success.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef REFTABLE_FSCK_H
|
||||
#define REFTABLE_FSCK_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-stack.h"
|
||||
|
||||
enum reftable_fsck_error {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef REFTABLE_ITERATOR_H
|
||||
#define REFTABLE_ITERATOR_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-record.h"
|
||||
|
||||
struct reftable_iterator_vtable;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef REFTABLE_MERGED_H
|
||||
#define REFTABLE_MERGED_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-iterator.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#ifndef REFTABLE_RECORD_H
|
||||
#define REFTABLE_RECORD_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-basics.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Basic data types
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef REFTABLE_STACK_H
|
||||
#define REFTABLE_STACK_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-writer.h"
|
||||
|
||||
/*
|
||||
|
||||
18
reftable/reftable-system.h
Normal file
18
reftable/reftable-system.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef REFTABLE_SYSTEM_H
|
||||
#define REFTABLE_SYSTEM_H
|
||||
|
||||
/*
|
||||
* This header defines the platform-specific bits required to compile the
|
||||
* reftable library. It should provide an environment that bridges over the
|
||||
* gaps between POSIX and your system, as well as the zlib interfaces. This
|
||||
* header is expected to be changed by the individual project.
|
||||
*/
|
||||
|
||||
#define MINGW_DONT_HANDLE_IN_USE_ERROR
|
||||
#include "compat/posix.h"
|
||||
#include "compat/zlib-compat.h"
|
||||
|
||||
int reftable_fsync(int fd);
|
||||
#define fsync(fd) reftable_fsync(fd)
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef REFTABLE_TABLE_H
|
||||
#define REFTABLE_TABLE_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-iterator.h"
|
||||
#include "reftable-block.h"
|
||||
#include "reftable-blocksource.h"
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
#ifndef REFTABLE_WRITER_H
|
||||
#define REFTABLE_WRITER_H
|
||||
|
||||
#include "reftable-system.h"
|
||||
#include "reftable-record.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h> /* ssize_t */
|
||||
|
||||
/* Writing single reftables */
|
||||
|
||||
/* reftable_write_options sets options for writing a single reftable. */
|
||||
@@ -63,12 +61,6 @@ struct reftable_write_options {
|
||||
*/
|
||||
long lock_timeout_ms;
|
||||
|
||||
/*
|
||||
* Optional callback used to fsync files to disk. Falls back to using
|
||||
* fsync(3P) when unset.
|
||||
*/
|
||||
int (*fsync)(int fd);
|
||||
|
||||
/*
|
||||
* Callback function to execute whenever the stack is being reloaded.
|
||||
* This can be used e.g. to discard cached information that relies on
|
||||
|
||||
@@ -29,13 +29,6 @@ static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stack_fsync(const struct reftable_write_options *opts, int fd)
|
||||
{
|
||||
if (opts->fsync)
|
||||
return opts->fsync(fd);
|
||||
return fsync(fd);
|
||||
}
|
||||
|
||||
static ssize_t reftable_write_data(int fd, const void *data, size_t size)
|
||||
{
|
||||
size_t total_written = 0;
|
||||
@@ -69,7 +62,7 @@ static ssize_t fd_writer_write(void *arg, const void *data, size_t sz)
|
||||
static int fd_writer_flush(void *arg)
|
||||
{
|
||||
struct fd_writer *writer = arg;
|
||||
return stack_fsync(writer->opts, writer->fd);
|
||||
return fsync(writer->fd);
|
||||
}
|
||||
|
||||
static int fd_read_lines(int fd, char ***namesp)
|
||||
@@ -372,45 +365,26 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* return negative if a before b. */
|
||||
static int tv_cmp(struct timeval *a, struct timeval *b)
|
||||
{
|
||||
time_t diff = a->tv_sec - b->tv_sec;
|
||||
int udiff = a->tv_usec - b->tv_usec;
|
||||
|
||||
if (diff != 0)
|
||||
return diff;
|
||||
|
||||
return udiff;
|
||||
}
|
||||
|
||||
static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
|
||||
int reuse_open)
|
||||
{
|
||||
char **names = NULL, **names_after = NULL;
|
||||
struct timeval deadline;
|
||||
uint64_t deadline;
|
||||
int64_t delay = 0;
|
||||
int tries = 0, err;
|
||||
int fd = -1;
|
||||
|
||||
err = gettimeofday(&deadline, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
deadline.tv_sec += 3;
|
||||
deadline = reftable_time_ms() + 3000;
|
||||
|
||||
while (1) {
|
||||
struct timeval now;
|
||||
|
||||
err = gettimeofday(&now, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
uint64_t now = reftable_time_ms();
|
||||
|
||||
/*
|
||||
* Only look at deadlines after the first few times. This
|
||||
* simplifies debugging in GDB.
|
||||
*/
|
||||
tries++;
|
||||
if (tries > 3 && tv_cmp(&now, &deadline) >= 0)
|
||||
if (tries > 3 && now >= deadline)
|
||||
goto out;
|
||||
|
||||
fd = open(st->list_file, O_RDONLY);
|
||||
@@ -812,7 +786,7 @@ int reftable_addition_commit(struct reftable_addition *add)
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = stack_fsync(&add->stack->opts, add->tables_list_lock.fd);
|
||||
err = fsync(add->tables_list_lock.fd);
|
||||
if (err < 0) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
goto done;
|
||||
@@ -1480,7 +1454,7 @@ static int stack_compact_range(struct reftable_stack *st,
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = stack_fsync(&st->opts, tables_list_lock.fd);
|
||||
err = fsync(tables_list_lock.fd);
|
||||
if (err < 0) {
|
||||
err = REFTABLE_IO_ERROR;
|
||||
unlink(new_table_path.buf);
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "basics.h"
|
||||
#include "reftable-error.h"
|
||||
#include "../lockfile.h"
|
||||
#include "../trace.h"
|
||||
#include "../tempfile.h"
|
||||
#include "../write-or-die.h"
|
||||
|
||||
uint32_t reftable_rand(void)
|
||||
{
|
||||
@@ -131,3 +133,33 @@ int flock_commit(struct reftable_flock *l)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reftable_fsync(int fd)
|
||||
{
|
||||
return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
|
||||
}
|
||||
|
||||
uint64_t reftable_time_ms(void)
|
||||
{
|
||||
return getnanotime() / 1000000;
|
||||
}
|
||||
|
||||
int reftable_mmap(struct reftable_mmap *out, int fd, size_t len)
|
||||
{
|
||||
void *data = xmmap_gently(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (data == MAP_FAILED)
|
||||
return REFTABLE_IO_ERROR;
|
||||
|
||||
out->data = data;
|
||||
out->size = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reftable_munmap(struct reftable_mmap *mmap)
|
||||
{
|
||||
if (munmap(mmap->data, mmap->size) < 0)
|
||||
return REFTABLE_IO_ERROR;
|
||||
memset(mmap, 0, sizeof(*mmap));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
/* This header glues the reftable library to the rest of Git */
|
||||
/*
|
||||
* This header defines the platform-agnostic interface that is to be
|
||||
* implemented by the project to make it work on their respective supported
|
||||
* systems, and to integrate it into the project itself. This header is not
|
||||
* expected to be changed by the individual project.
|
||||
*/
|
||||
|
||||
#define MINGW_DONT_HANDLE_IN_USE_ERROR
|
||||
#include "compat/posix.h"
|
||||
#include "compat/zlib-compat.h"
|
||||
#include "reftable-system.h"
|
||||
|
||||
/*
|
||||
* Return a random 32 bit integer. This function is expected to return
|
||||
@@ -108,4 +111,25 @@ int flock_release(struct reftable_flock *l);
|
||||
*/
|
||||
int flock_commit(struct reftable_flock *l);
|
||||
|
||||
/* Report the time in milliseconds. */
|
||||
uint64_t reftable_time_ms(void);
|
||||
|
||||
struct reftable_mmap {
|
||||
void *data;
|
||||
size_t size;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/*
|
||||
* Map the file into memory. Returns 0 on success, a reftable error code on
|
||||
* error.
|
||||
*/
|
||||
int reftable_mmap(struct reftable_mmap *out, int fd, size_t len);
|
||||
|
||||
/*
|
||||
* Unmap the file from memory. Returns 0 on success, a reftable error code on
|
||||
* error.
|
||||
*/
|
||||
int reftable_munmap(struct reftable_mmap *mmap);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user