{"thread":{"id":"65394","subject":"[PATCH 0/6] reftable: some more portability improvements","startedAt":"2026-03-31T11:26:55Z","lastAt":"2026-04-02T18:27:06Z","messageCount":28,"participants":["Patrick Steinhardt","Junio C Hamano","René Scharfe","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"540504","messageId":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":null,"subject":"[PATCH 0/6] reftable: some more portability improvements","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:46Z","receivedAt":"2026-03-31T11:26:55Z","isPatch":true,"body":"Hi,\n\nthis patch series contains the last set of portability improvements\nthat currently sits in the reftable implementation of libgit2. With\nthese patches merged lbigit2 is able to fully reuse the reftable library\nwhile only having to provide its own system headers.\n\nI've got a test run with libgit2 at [1], the code in Git is tested at\n[2]. Overall we're quite close -- the pull requests to implement the\nrepository extension and to adjust handling of pseudo-refs have been\nmerged. Still missing is a couple of test fixes, but once those are\nmerged the reftable backend itself will be in review.\n\nThanks!\n\nPatrick\n\n[1]: https://github.com/libgit2/libgit2/pull/7117\n[2]: https://gitlab.com/gitlab-org/git/-/merge_requests/535\n\n---\nPatrick Steinhardt (6):\n      reftable/system: provide `REFTABLE_INLINE()` macro\n      reftable/stack: don't call fsync(3p) unless provided\n      reftable/fsck: use REFTABLE_UNUSED instead of UNUSED\n      reftable/system: add abstraction to retrieve time in milliseconds\n      reftable/system: add abstraction to mmap files\n      reftable: introduce \"reftable-system.h\" header\n\n reftable/basics.h               | 20 ++++++++++----------\n reftable/blocksource.c          | 19 +++++++------------\n reftable/fsck.c                 |  2 +-\n reftable/pq.h                   |  4 ++--\n reftable/record.h               |  4 ++--\n reftable/reftable-basics.h      |  2 +-\n reftable/reftable-block.h       |  3 +--\n reftable/reftable-blocksource.h |  2 +-\n reftable/reftable-error.h       |  2 ++\n reftable/reftable-fsck.h        |  1 +\n reftable/reftable-iterator.h    |  1 +\n reftable/reftable-merged.h      |  1 +\n reftable/reftable-record.h      |  2 +-\n reftable/reftable-stack.h       |  1 +\n reftable/reftable-system.h      |  7 +++++++\n reftable/reftable-table.h       |  1 +\n reftable/reftable-writer.h      |  4 +---\n reftable/stack.c                | 29 +++++------------------------\n reftable/system.c               | 26 ++++++++++++++++++++++++++\n reftable/system.h               | 26 ++++++++++++++++++++++++--\n 20 files changed, 96 insertions(+), 61 deletions(-)\n\n\n---\nbase-commit: 270e10ad6dda3379ea0da7efd11e4fbf2cd7a325\nchange-id: 20260330-pks-reftable-portability-fixes-36ebf9f227c2\n\n"},{"id":"540505","messageId":"20260331-pks-reftable-portability-fixes-v1-1-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:47Z","receivedAt":"2026-03-31T11:26:57Z","isPatch":true,"body":"Not every compiler knows about the `inline` annotation for functions.\nConsequently, Git knows to define `inline` as an empty macro in case\nit's not available.\n\nIn the reftable library though we cannot assume the macro to be\navailable as it is usable as a standalone library. Fix this by\nintroducing a `REFTABLE_INLINE()` macro via \"reftable/system.h\" that\nallows the project to use their own definition.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/basics.h | 20 ++++++++++----------\n reftable/pq.h     |  4 ++--\n reftable/record.h |  4 ++--\n reftable/system.h |  2 ++\n 4 files changed, 16 insertions(+), 14 deletions(-)\n\ndiff --git a/reftable/basics.h b/reftable/basics.h\nindex e4b83b2b03..ebbcec2ac3 100644\n--- a/reftable/basics.h\n+++ b/reftable/basics.h\n@@ -75,14 +75,14 @@ char *reftable_buf_detach(struct reftable_buf *buf);\n \n /* Bigendian en/decoding of integers */\n \n-static inline void reftable_put_be16(void *out, uint16_t i)\n+REFTABLE_INLINE(void) reftable_put_be16(void *out, uint16_t i)\n {\n \tunsigned char *p = out;\n \tp[0] = (uint8_t)((i >> 8) & 0xff);\n \tp[1] = (uint8_t)((i >> 0) & 0xff);\n }\n \n-static inline void reftable_put_be24(void *out, uint32_t i)\n+REFTABLE_INLINE(void) reftable_put_be24(void *out, uint32_t i)\n {\n \tunsigned char *p = out;\n \tp[0] = (uint8_t)((i >> 16) & 0xff);\n@@ -90,7 +90,7 @@ static inline void reftable_put_be24(void *out, uint32_t i)\n \tp[2] = (uint8_t)((i >>  0) & 0xff);\n }\n \n-static inline void reftable_put_be32(void *out, uint32_t i)\n+REFTABLE_INLINE(void) reftable_put_be32(void *out, uint32_t i)\n {\n \tunsigned char *p = out;\n \tp[0] = (uint8_t)((i >> 24) & 0xff);\n@@ -99,7 +99,7 @@ static inline void reftable_put_be32(void *out, uint32_t i)\n \tp[3] = (uint8_t)((i >>  0) & 0xff);\n }\n \n-static inline void reftable_put_be64(void *out, uint64_t i)\n+REFTABLE_INLINE(void) reftable_put_be64(void *out, uint64_t i)\n {\n \tunsigned char *p = out;\n \tp[0] = (uint8_t)((i >> 56) & 0xff);\n@@ -112,14 +112,14 @@ static inline void reftable_put_be64(void *out, uint64_t i)\n \tp[7] = (uint8_t)((i >>  0) & 0xff);\n }\n \n-static inline uint16_t reftable_get_be16(const void *in)\n+REFTABLE_INLINE(uint16_t) reftable_get_be16(const void *in)\n {\n \tconst unsigned char *p = in;\n \treturn (uint16_t)(p[0]) << 8 |\n \t       (uint16_t)(p[1]) << 0;\n }\n \n-static inline uint32_t reftable_get_be24(const void *in)\n+REFTABLE_INLINE(uint32_t) reftable_get_be24(const void *in)\n {\n \tconst unsigned char *p = in;\n \treturn (uint32_t)(p[0]) << 16 |\n@@ -127,7 +127,7 @@ static inline uint32_t reftable_get_be24(const void *in)\n \t       (uint32_t)(p[2]) << 0;\n }\n \n-static inline uint32_t reftable_get_be32(const void *in)\n+REFTABLE_INLINE(uint32_t) reftable_get_be32(const void *in)\n {\n \tconst unsigned char *p = in;\n \treturn (uint32_t)(p[0]) << 24 |\n@@ -136,7 +136,7 @@ static inline uint32_t reftable_get_be32(const void *in)\n \t       (uint32_t)(p[3]) <<  0;\n }\n \n-static inline uint64_t reftable_get_be64(const void *in)\n+REFTABLE_INLINE(uint64_t) reftable_get_be64(const void *in)\n {\n \tconst unsigned char *p = in;\n \treturn (uint64_t)(p[0]) << 56 |\n@@ -187,7 +187,7 @@ void reftable_free(void *p);\n void *reftable_calloc(size_t nelem, size_t elsize);\n char *reftable_strdup(const char *str);\n \n-static inline int reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)\n+REFTABLE_INLINE(int) reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)\n {\n \tif (nelem && elsize > SIZE_MAX / nelem)\n \t\treturn -1;\n@@ -215,7 +215,7 @@ static inline int reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)\n \t\t} \\\n \t} while (0)\n \n-static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,\n+REFTABLE_INLINE(void) *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,\n \t\t\t\t\tsize_t *allocp)\n {\n \tvoid *new_p;\ndiff --git a/reftable/pq.h b/reftable/pq.h\nindex 42310670b0..9210ede273 100644\n--- a/reftable/pq.h\n+++ b/reftable/pq.h\n@@ -27,12 +27,12 @@ int merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry\n void merged_iter_pqueue_release(struct merged_iter_pqueue *pq);\n int pq_less(struct pq_entry *a, struct pq_entry *b);\n \n-static inline struct pq_entry merged_iter_pqueue_top(struct merged_iter_pqueue pq)\n+REFTABLE_INLINE(struct) pq_entry merged_iter_pqueue_top(struct merged_iter_pqueue pq)\n {\n \treturn pq.heap[0];\n }\n \n-static inline int merged_iter_pqueue_is_empty(struct merged_iter_pqueue pq)\n+REFTABLE_INLINE(int) merged_iter_pqueue_is_empty(struct merged_iter_pqueue pq)\n {\n \treturn pq.len == 0;\n }\ndiff --git a/reftable/record.h b/reftable/record.h\nindex 7953f352a3..20c9091371 100644\n--- a/reftable/record.h\n+++ b/reftable/record.h\n@@ -26,7 +26,7 @@ struct string_view {\n };\n \n /* Advance `s.buf` by `n`, and decrease length. */\n-static inline void string_view_consume(struct string_view *s, int n)\n+REFTABLE_INLINE(void) string_view_consume(struct string_view *s, int n)\n {\n \ts->buf += n;\n \ts->len -= n;\n@@ -147,7 +147,7 @@ int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key,\n \t\t\t   uint32_t hash_size, struct reftable_buf *scratch);\n int reftable_record_is_deletion(struct reftable_record *rec);\n \n-static inline uint8_t reftable_record_type(struct reftable_record *rec)\n+REFTABLE_INLINE(uint8_t) reftable_record_type(struct reftable_record *rec)\n {\n \treturn rec->type;\n }\ndiff --git a/reftable/system.h b/reftable/system.h\nindex c54ed4cad6..b15768dbdb 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -15,6 +15,8 @@\n #include \"compat/posix.h\"\n #include \"compat/zlib-compat.h\"\n \n+#define REFTABLE_INLINE(type) static inline type\n+\n /*\n  * Return a random 32 bit integer. This function is expected to return\n  * pre-seeded data.\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540506","messageId":"20260331-pks-reftable-portability-fixes-v1-2-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 2/6] reftable/stack: don't call fsync(3p) unless provided","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:48Z","receivedAt":"2026-03-31T11:26:59Z","isPatch":true,"body":"Users of the reftable library are expected to provide their own function\ncallback in cases they want to sync(3p) data to disk via the reftable\nwrite options. But if no such function was provided we end up calling\nfsync(3p) directly, which may not even be available on some systems.\n\nDrop the call to fsync(3p) and rely on the callback function\nexclusively.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/stack.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/reftable/stack.c b/reftable/stack.c\nindex 1c9f21dfe1..f9ae832e3a 100644\n--- a/reftable/stack.c\n+++ b/reftable/stack.c\n@@ -33,7 +33,7 @@ static int stack_fsync(const struct reftable_write_options *opts, int fd)\n {\n \tif (opts->fsync)\n \t\treturn opts->fsync(fd);\n-\treturn fsync(fd);\n+\treturn 0;\n }\n \n static ssize_t reftable_write_data(int fd, const void *data, size_t size)\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540507","messageId":"20260331-pks-reftable-portability-fixes-v1-3-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 3/6] reftable/fsck: use REFTABLE_UNUSED instead of UNUSED","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:49Z","receivedAt":"2026-03-31T11:27:02Z","isPatch":true,"body":"While we have the reftable-specific `REFTABLE_UNUSED` header, we\naccidentally introduced a new usage of the Git-specific `UNUSED` header\ninto the reftable library in 9051638519 (reftable: add code to\nfacilitate consistency checks, 2025-10-07).\n\nConvert the site to use `REFTABLE_UNUSED`.\n\nIdeally, we'd move the definition of `UNUSED` into \"git-compat-util.h\"\nso that it becomes in accessible to the reftable library. But this is\nunfortunately not easily possible as \"compat/mingw-posix.h\" requires\nthis macro, and this header is included by \"compat/posix.h\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/fsck.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/reftable/fsck.c b/reftable/fsck.c\nindex 26b9115b14..8e73fc83f2 100644\n--- a/reftable/fsck.c\n+++ b/reftable/fsck.c\n@@ -63,7 +63,7 @@ static int table_check_name(struct reftable_table *table,\n \n static int table_checks(struct reftable_table *table,\n \t\t\treftable_fsck_report_fn report_fn,\n-\t\t\treftable_fsck_verbose_fn verbose_fn UNUSED,\n+\t\t\treftable_fsck_verbose_fn verbose_fn REFTABLE_UNUSED,\n \t\t\tvoid *cb_data)\n {\n \ttable_check_fn table_check_fns[] = {\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540508","messageId":"20260331-pks-reftable-portability-fixes-v1-4-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 4/6] reftable/system: add abstraction to retrieve time in milliseconds","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:50Z","receivedAt":"2026-03-31T11:27:06Z","isPatch":true,"body":"We directly call gettimeofday(3p), which may not be available on some\nplatforms. Provide the infrastructure to let projects easily use their\nown implementations of this function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/stack.c  | 27 ++++-----------------------\n reftable/system.c |  6 ++++++\n reftable/system.h |  3 +++\n 3 files changed, 13 insertions(+), 23 deletions(-)\n\ndiff --git a/reftable/stack.c b/reftable/stack.c\nindex f9ae832e3a..2d2c9b1f84 100644\n--- a/reftable/stack.c\n+++ b/reftable/stack.c\n@@ -372,45 +372,26 @@ static int reftable_stack_reload_once(struct reftable_stack *st,\n \treturn err;\n }\n \n-/* return negative if a before b. */\n-static int tv_cmp(struct timeval *a, struct timeval *b)\n-{\n-\ttime_t diff = a->tv_sec - b->tv_sec;\n-\tint udiff = a->tv_usec - b->tv_usec;\n-\n-\tif (diff != 0)\n-\t\treturn diff;\n-\n-\treturn udiff;\n-}\n-\n static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,\n \t\t\t\t\t     int reuse_open)\n {\n \tchar **names = NULL, **names_after = NULL;\n-\tstruct timeval deadline;\n+\tuint64_t deadline;\n \tint64_t delay = 0;\n \tint tries = 0, err;\n \tint fd = -1;\n \n-\terr = gettimeofday(&deadline, NULL);\n-\tif (err < 0)\n-\t\tgoto out;\n-\tdeadline.tv_sec += 3;\n+\tdeadline = reftable_time_ms() + 3000;\n \n \twhile (1) {\n-\t\tstruct timeval now;\n-\n-\t\terr = gettimeofday(&now, NULL);\n-\t\tif (err < 0)\n-\t\t\tgoto out;\n+\t\tuint64_t now = reftable_time_ms();\n \n \t\t/*\n \t\t * Only look at deadlines after the first few times. This\n \t\t * simplifies debugging in GDB.\n \t\t */\n \t\ttries++;\n-\t\tif (tries > 3 && tv_cmp(&now, &deadline) >= 0)\n+\t\tif (tries > 3 && now >= deadline)\n \t\t\tgoto out;\n \n \t\tfd = open(st->list_file, O_RDONLY);\ndiff --git a/reftable/system.c b/reftable/system.c\nindex 725a25844e..7aecd3859d 100644\n--- a/reftable/system.c\n+++ b/reftable/system.c\n@@ -4,6 +4,7 @@\n #include \"basics.h\"\n #include \"reftable-error.h\"\n #include \"../lockfile.h\"\n+#include \"../trace.h\"\n #include \"../tempfile.h\"\n \n uint32_t reftable_rand(void)\n@@ -131,3 +132,8 @@ int flock_commit(struct reftable_flock *l)\n \n \treturn 0;\n }\n+\n+uint64_t reftable_time_ms(void)\n+{\n+\treturn getnanotime() / 1000000;\n+}\ndiff --git a/reftable/system.h b/reftable/system.h\nindex b15768dbdb..6e00cd32a3 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -110,4 +110,7 @@ int flock_release(struct reftable_flock *l);\n  */\n int flock_commit(struct reftable_flock *l);\n \n+/* Report the time in milliseconds. */\n+uint64_t reftable_time_ms(void);\n+\n #endif\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540509","messageId":"20260331-pks-reftable-portability-fixes-v1-5-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 5/6] reftable/system: add abstraction to mmap files","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:51Z","receivedAt":"2026-03-31T11:27:08Z","isPatch":true,"body":"In our codebase we have a couple of wrappers around mmap(3p) that allow\nus to reimplement the syscall on platforms that don't have it natively,\nlike for example Windows. Other projects that embed the reftable library\nmay have a different infra though to hook up mmap wrappers, but these\nare currently hard to integrate.\n\nProvide the infrastructure to let projects easily define the mmap\ninterface with a custom struct and custom functions.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/blocksource.c | 19 +++++++------------\n reftable/system.c      | 20 ++++++++++++++++++++\n reftable/system.h      | 18 ++++++++++++++++++\n 3 files changed, 45 insertions(+), 12 deletions(-)\n\ndiff --git a/reftable/blocksource.c b/reftable/blocksource.c\nindex 573c81287f..7f7441f751 100644\n--- a/reftable/blocksource.c\n+++ b/reftable/blocksource.c\n@@ -93,13 +93,12 @@ void block_source_from_buf(struct reftable_block_source *bs,\n }\n \n struct file_block_source {\n-\tuint64_t size;\n-\tunsigned char *data;\n+\tstruct reftable_mmap mmap;\n };\n \n static uint64_t file_size(void *b)\n {\n-\treturn ((struct file_block_source *)b)->size;\n+\treturn ((struct file_block_source *)b)->mmap.size;\n }\n \n static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_data *dest REFTABLE_UNUSED)\n@@ -109,7 +108,7 @@ static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_dat\n static void file_close(void *v)\n {\n \tstruct file_block_source *b = v;\n-\tmunmap(b->data, b->size);\n+\treftable_munmap(&b->mmap);\n \treftable_free(b);\n }\n \n@@ -117,8 +116,8 @@ static ssize_t file_read_data(void *v, struct reftable_block_data *dest, uint64_\n \t\t\t      uint32_t size)\n {\n \tstruct file_block_source *b = v;\n-\tassert(off + size <= b->size);\n-\tdest->data = b->data + off;\n+\tassert(off + size <= b->mmap.size);\n+\tdest->data = (unsigned char *) b->mmap.data + off;\n \tdest->len = size;\n \treturn size;\n }\n@@ -156,13 +155,9 @@ int reftable_block_source_from_file(struct reftable_block_source *bs,\n \t\tgoto out;\n \t}\n \n-\tp->size = st.st_size;\n-\tp->data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n-\tif (p->data == MAP_FAILED) {\n-\t\terr = REFTABLE_IO_ERROR;\n-\t\tp->data = NULL;\n+\terr = reftable_mmap(&p->mmap, fd, st.st_size);\n+\tif (err < 0)\n \t\tgoto out;\n-\t}\n \n \tassert(!bs->ops);\n \tbs->ops = &file_vtable;\ndiff --git a/reftable/system.c b/reftable/system.c\nindex 7aecd3859d..a5603f5f61 100644\n--- a/reftable/system.c\n+++ b/reftable/system.c\n@@ -137,3 +137,23 @@ uint64_t reftable_time_ms(void)\n {\n \treturn getnanotime() / 1000000;\n }\n+\n+int reftable_mmap(struct reftable_mmap *out, int fd, size_t len)\n+{\n+\tvoid *data = xmmap_gently(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);\n+\tif (data == MAP_FAILED)\n+\t\treturn REFTABLE_IO_ERROR;\n+\n+\tout->data = data;\n+\tout->size = len;\n+\n+\treturn 0;\n+}\n+\n+int reftable_munmap(struct reftable_mmap *mmap)\n+{\n+\tif (munmap(mmap->data, mmap->size) < 0)\n+\t\treturn REFTABLE_IO_ERROR;\n+\tmemset(mmap, 0, sizeof(*mmap));\n+\treturn 0;\n+}\ndiff --git a/reftable/system.h b/reftable/system.h\nindex 6e00cd32a3..dffc717bd4 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -113,4 +113,22 @@ int flock_commit(struct reftable_flock *l);\n /* Report the time in milliseconds. */\n uint64_t reftable_time_ms(void);\n \n+struct reftable_mmap {\n+       void *data;\n+       size_t size;\n+       void *priv;\n+};\n+\n+/*\n+ * Map the file into memory. Returns 0 on success, a reftable error code on\n+ * error.\n+ */\n+int reftable_mmap(struct reftable_mmap *out, int fd, size_t len);\n+\n+/*\n+ * Unmap the file from memory. Returns 0 on success, a reftable error code on\n+ * error.\n+ */\n+int reftable_munmap(struct reftable_mmap *mmap);\n+\n #endif\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540510","messageId":"20260331-pks-reftable-portability-fixes-v1-6-46bfae55c68c@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH 6/6] reftable: introduce \"reftable-system.h\" header","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-03-31T11:26:52Z","receivedAt":"2026-03-31T11:27:11Z","isPatch":true,"body":"We're including a couple of standard headers like <stdint.h> in a bunch\nof locations, which makes it hard for a project to plug in their own\nlogic for making required functionality available. For us this is for\nexample via \"compat/posix.h\", which already includes all of the system\nheaders relevant to us.\n\nIntroduce a new \"reftable-system.h\" header that allows projects to\nprovide their own headers.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/reftable-basics.h      | 2 +-\n reftable/reftable-block.h       | 3 +--\n reftable/reftable-blocksource.h | 2 +-\n reftable/reftable-error.h       | 2 ++\n reftable/reftable-fsck.h        | 1 +\n reftable/reftable-iterator.h    | 1 +\n reftable/reftable-merged.h      | 1 +\n reftable/reftable-record.h      | 2 +-\n reftable/reftable-stack.h       | 1 +\n reftable/reftable-system.h      | 7 +++++++\n reftable/reftable-table.h       | 1 +\n reftable/reftable-writer.h      | 4 +---\n reftable/system.h               | 3 +--\n 13 files changed, 20 insertions(+), 10 deletions(-)\n\ndiff --git a/reftable/reftable-basics.h b/reftable/reftable-basics.h\nindex 6d73f19c85..dc8622682d 100644\n--- a/reftable/reftable-basics.h\n+++ b/reftable/reftable-basics.h\n@@ -9,7 +9,7 @@\n #ifndef REFTABLE_BASICS_H\n #define REFTABLE_BASICS_H\n \n-#include <stddef.h>\n+#include \"reftable-system.h\"\n \n /* A buffer that contains arbitrary byte slices. */\n struct reftable_buf {\ndiff --git a/reftable/reftable-block.h b/reftable/reftable-block.h\nindex 0b05a8f7e3..94c79b5c58 100644\n--- a/reftable/reftable-block.h\n+++ b/reftable/reftable-block.h\n@@ -9,8 +9,7 @@\n #ifndef REFTABLE_BLOCK_H\n #define REFTABLE_BLOCK_H\n \n-#include <stdint.h>\n-\n+#include \"reftable-system.h\"\n #include \"reftable-basics.h\"\n #include \"reftable-blocksource.h\"\n #include \"reftable-iterator.h\"\ndiff --git a/reftable/reftable-blocksource.h b/reftable/reftable-blocksource.h\nindex f5ba867bd6..40c1e94646 100644\n--- a/reftable/reftable-blocksource.h\n+++ b/reftable/reftable-blocksource.h\n@@ -9,7 +9,7 @@\n #ifndef REFTABLE_BLOCKSOURCE_H\n #define REFTABLE_BLOCKSOURCE_H\n \n-#include <stdint.h>\n+#include \"reftable-system.h\"\n \n /*\n  * Generic wrapper for a seekable readable file.\ndiff --git a/reftable/reftable-error.h b/reftable/reftable-error.h\nindex d100e0df92..0535e1478b 100644\n--- a/reftable/reftable-error.h\n+++ b/reftable/reftable-error.h\n@@ -9,6 +9,8 @@\n #ifndef REFTABLE_ERROR_H\n #define REFTABLE_ERROR_H\n \n+#include \"reftable-system.h\"\n+\n /*\n  * Errors in reftable calls are signaled with negative integer return values. 0\n  * means success.\ndiff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h\nindex 007a392cf9..340fc7762e 100644\n--- a/reftable/reftable-fsck.h\n+++ b/reftable/reftable-fsck.h\n@@ -1,6 +1,7 @@\n #ifndef REFTABLE_FSCK_H\n #define REFTABLE_FSCK_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-stack.h\"\n \n enum reftable_fsck_error {\ndiff --git a/reftable/reftable-iterator.h b/reftable/reftable-iterator.h\nindex af582028c2..a050cc153b 100644\n--- a/reftable/reftable-iterator.h\n+++ b/reftable/reftable-iterator.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_ITERATOR_H\n #define REFTABLE_ITERATOR_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-record.h\"\n \n struct reftable_iterator_vtable;\ndiff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h\nindex e5af846b32..02a9966835 100644\n--- a/reftable/reftable-merged.h\n+++ b/reftable/reftable-merged.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_MERGED_H\n #define REFTABLE_MERGED_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-iterator.h\"\n \n /*\ndiff --git a/reftable/reftable-record.h b/reftable/reftable-record.h\nindex 385a74cc86..e18c538238 100644\n--- a/reftable/reftable-record.h\n+++ b/reftable/reftable-record.h\n@@ -9,8 +9,8 @@\n #ifndef REFTABLE_RECORD_H\n #define REFTABLE_RECORD_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-basics.h\"\n-#include <stdint.h>\n \n /*\n  * Basic data types\ndiff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h\nindex c2415cbc6e..5f7be573fa 100644\n--- a/reftable/reftable-stack.h\n+++ b/reftable/reftable-stack.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_STACK_H\n #define REFTABLE_STACK_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-writer.h\"\n \n /*\ndiff --git a/reftable/reftable-system.h b/reftable/reftable-system.h\nnew file mode 100644\nindex 0000000000..f90c415182\n--- /dev/null\n+++ b/reftable/reftable-system.h\n@@ -0,0 +1,7 @@\n+#ifndef REFTABLE_SYSTEM_H\n+#define REFTABLE_SYSTEM_H\n+\n+#define MINGW_DONT_HANDLE_IN_USE_ERROR\n+#include \"compat/posix.h\"\n+\n+#endif\ndiff --git a/reftable/reftable-table.h b/reftable/reftable-table.h\nindex 5f935d02e3..d7666b53a1 100644\n--- a/reftable/reftable-table.h\n+++ b/reftable/reftable-table.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_TABLE_H\n #define REFTABLE_TABLE_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-iterator.h\"\n #include \"reftable-block.h\"\n #include \"reftable-blocksource.h\"\ndiff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h\nindex 1e7003cd69..065dd93dc6 100644\n--- a/reftable/reftable-writer.h\n+++ b/reftable/reftable-writer.h\n@@ -9,11 +9,9 @@\n #ifndef REFTABLE_WRITER_H\n #define REFTABLE_WRITER_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-record.h\"\n \n-#include <stdint.h>\n-#include <unistd.h> /* ssize_t */\n-\n /* Writing single reftables */\n \n /* reftable_write_options sets options for writing a single reftable. */\ndiff --git a/reftable/system.h b/reftable/system.h\nindex dffc717bd4..52f964c04b 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -11,8 +11,7 @@\n \n /* This header glues the reftable library to the rest of Git */\n \n-#define MINGW_DONT_HANDLE_IN_USE_ERROR\n-#include \"compat/posix.h\"\n+#include \"reftable-system.h\"\n #include \"compat/zlib-compat.h\"\n \n #define REFTABLE_INLINE(type) static inline type\n\n-- \n2.53.0.1185.g05d4b7b318.dirty\n\n"},{"id":"540544","messageId":"xmqqbjg327x9.fsf@gitster.g","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-1-46bfae55c68c@pks.im","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-31T18:03:14Z","receivedAt":"2026-03-31T18:03:18Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Not every compiler knows about the `inline` annotation for functions.\n> Consequently, Git knows to define `inline` as an empty macro in case\n> it's not available.\n>\n> In the reftable library though we cannot assume the macro to be\n> available as it is usable as a standalone library. Fix this by\n> introducing a `REFTABLE_INLINE()` macro via \"reftable/system.h\" that\n> allows the project to use their own definition.\n\nAnd our `inline` would be used to define REFTABLE_INLINE() in the\ncontext of this project?  Makes sense to me.\n\n> diff --git a/reftable/system.h b/reftable/system.h\n> index c54ed4cad6..b15768dbdb 100644\n> --- a/reftable/system.h\n> +++ b/reftable/system.h\n> @@ -15,6 +15,8 @@\n>  #include \"compat/posix.h\"\n>  #include \"compat/zlib-compat.h\"\n>  \n> +#define REFTABLE_INLINE(type) static inline type\n> +\n>  /*\n>   * Return a random 32 bit integer. This function is expected to return\n>   * pre-seeded data.\n"},{"id":"540545","messageId":"xmqq5x6b27ms.fsf@gitster.g","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-2-46bfae55c68c@pks.im","subject":"Re: [PATCH 2/6] reftable/stack: don't call fsync(3p) unless provided","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-31T18:09:31Z","receivedAt":"2026-03-31T18:09:33Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Users of the reftable library are expected to provide their own function\n> callback in cases they want to sync(3p) data to disk via the reftable\n> write options. But if no such function was provided we end up calling\n> fsync(3p) directly, which may not even be available on some systems.\n>\n> Drop the call to fsync(3p) and rely on the callback function\n> exclusively.\n\nHmph, reftable-backend.c seems to do\n\n\trefs->write_options.fsync = reftable_be_fsync;\n\nin its _be_init(), so this change is a no-op in the context of our\nsystem, so this may be _safe_, but for a caller that wanted a fsync\nto happen, returning to it without doing anything may be a bit\nunexpected.  I am wondering if it should be more like\n\n\tif (!opts->fsync)\n\t\t/* BUG(\"whoa where is your fsync callback???\") */\n\t\treutrn -1;\n\treturn opts->fsync(fd);\n\ninstead.\n\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  reftable/stack.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/reftable/stack.c b/reftable/stack.c\n> index 1c9f21dfe1..f9ae832e3a 100644\n> --- a/reftable/stack.c\n> +++ b/reftable/stack.c\n> @@ -33,7 +33,7 @@ static int stack_fsync(const struct reftable_write_options *opts, int fd)\n>  {\n>  \tif (opts->fsync)\n>  \t\treturn opts->fsync(fd);\n> -\treturn fsync(fd);\n> +\treturn 0;\n>  }\n>  \n>  static ssize_t reftable_write_data(int fd, const void *data, size_t size)\n"},{"id":"540546","messageId":"xmqq1pgz27in.fsf@gitster.g","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-3-46bfae55c68c@pks.im","subject":"Re: [PATCH 3/6] reftable/fsck: use REFTABLE_UNUSED instead of UNUSED","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-31T18:12:00Z","receivedAt":"2026-03-31T18:12:04Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\nPatrick Steinhardt <ps@pks.im> writes:\n\n> While we have the reftable-specific `REFTABLE_UNUSED` header, we\n> accidentally introduced a new usage of the Git-specific `UNUSED` header\n> into the reftable library in 9051638519 (reftable: add code to\n> facilitate consistency checks, 2025-10-07).\n>\n> Convert the site to use `REFTABLE_UNUSED`.\n\nGood eyes.  Being self-contained is good.\n"},{"id":"540547","messageId":"xmqqwlyrzwh0.fsf@gitster.g","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-6-46bfae55c68c@pks.im","subject":"Re: [PATCH 6/6] reftable: introduce \"reftable-system.h\" header","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-31T18:26:35Z","receivedAt":"2026-03-31T18:26:38Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> We're including a couple of standard headers like <stdint.h> in a bunch\n> of locations, which makes it hard for a project to plug in their own\n> logic for making required functionality available. For us this is for\n> example via \"compat/posix.h\", which already includes all of the system\n> headers relevant to us.\n\nHmmm.  This is interesting.\n\n> diff --git a/reftable/reftable-system.h b/reftable/reftable-system.h\n> new file mode 100644\n> index 0000000000..f90c415182\n> --- /dev/null\n> +++ b/reftable/reftable-system.h\n> @@ -0,0 +1,7 @@\n> +#ifndef REFTABLE_SYSTEM_H\n> +#define REFTABLE_SYSTEM_H\n> +\n> +#define MINGW_DONT_HANDLE_IN_USE_ERROR\n> +#include \"compat/posix.h\"\n> +\n> +#endif\n\nThis one is clearly tailored to be used in the context of our\nsystem.\n\n> diff --git a/reftable/system.h b/reftable/system.h\n> index dffc717bd4..52f964c04b 100644\n> --- a/reftable/system.h\n> +++ b/reftable/system.h\n> @@ -11,8 +11,7 @@\n>  \n>  /* This header glues the reftable library to the rest of Git */\n>  \n> -#define MINGW_DONT_HANDLE_IN_USE_ERROR\n> -#include \"compat/posix.h\"\n> +#include \"reftable-system.h\"\n>  #include \"compat/zlib-compat.h\"\n>  \n>  #define REFTABLE_INLINE(type) static inline type\n\nAnd so far in this series, I was getting the impression that\nreftable/system.c and reftable/system.h are where the target system\nspecific definitions are stored.\n\nThe implementation detail of how we obtain the wallclock time at\nmillisecond resolution is in reftable/system.c, the implementation\ndetail of how our mmap() emulation can work to build reftable_mmap()\nis in reftable/system.c, for example.\n\nBut the corresponding reftable/system.h does not seem to be specific\nto the target system at all---it describes the common abstraction,\nlike \"reftable code proper is expected call reftable_mmap() on any\nsystem\" and \"the way for reftable code is expected to read the\nwallclock is by calling reftable_time_ms()\".\n\nSo <reftable-system.h>, just like <reftable/system.c>, is expected\nto have a target platform specific \"implementation\", and not like\n<reftable/system.h> that is expected to be platform neutral (this\nneutrality comes from the fact that <reftable/system.c> will\nimplement the interface specified in <reftable/system.h> for the\ntarget platform).\n\nWhich somehow feels confusing.\n\nBesides, the definition of \"REFTABLE_INLINE(type)\" being \"static\ninline type\", according to the explanation in [1/6], is valid only\nin the context of this project, so shouldn't it be done inside\n<reftable-system.h>, not <reftable/system.h>\"?  For that matter,\nwhat about inclusion of \"compat/zlib-compat.h\"?  Is it widely\napplicable across target platforms, or very specific to our codebase\nwhere this library is used/embedded in?\n\n\n\n"},{"id":"540559","messageId":"054e69e8-3dab-4321-b68c-a48d43dc052f@web.de","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-1-46bfae55c68c@pks.im","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-03-31T21:12:51Z","receivedAt":"2026-03-31T21:18:09Z","isPatch":true,"body":"On 3/31/26 1:26 PM, Patrick Steinhardt wrote:\n> Not every compiler knows about the `inline` annotation for functions.\n> Consequently, Git knows to define `inline` as an empty macro in case\n> it's not available.\n\nDoes it?  Only in compat/regex/regex_internal.h, which does not leak\nto other code, no?\n\nRené\n\n"},{"id":"540561","messageId":"xmqqpl4jy9p0.fsf@gitster.g","threadId":"65394","inReplyTo":"054e69e8-3dab-4321-b68c-a48d43dc052f@web.de","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-31T21:23:55Z","receivedAt":"2026-03-31T21:23:57Z","isPatch":true,"body":"René Scharfe <l.s.r@web.de> writes:\n\n> On 3/31/26 1:26 PM, Patrick Steinhardt wrote:\n>> Not every compiler knows about the `inline` annotation for functions.\n>> Consequently, Git knows to define `inline` as an empty macro in case\n>> it's not available.\n>\n> Does it?  Only in compat/regex/regex_internal.h, which does not leak\n> to other code, no?\n\nAs we also do \n\nifneq (,$(INLINE))\n        BASIC_CFLAGS += -Dinline=$(INLINE)\nendif\n\nin the Makefile so we cannot tell what people do with their\nconfig.mak ;-).\n\nAnd obviously other projects do not share our Makefile, so it is not\ntoo much of stretch to say Git \"knows to define\", even though it may\nbe more precise to say \"knows to let users redefine\", perhaps?\n\n"},{"id":"540573","messageId":"b19785af-c8cf-4fdd-a44f-d4e8a0f754d5@web.de","threadId":"65394","inReplyTo":"xmqqpl4jy9p0.fsf@gitster.g","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-03-31T22:15:32Z","receivedAt":"2026-03-31T22:15:37Z","isPatch":true,"body":"On 3/31/26 11:23 PM, Junio C Hamano wrote:\n> René Scharfe <l.s.r@web.de> writes:\n> \n>> On 3/31/26 1:26 PM, Patrick Steinhardt wrote:\n>>> Not every compiler knows about the `inline` annotation for functions.\n>>> Consequently, Git knows to define `inline` as an empty macro in case\n>>> it's not available.\n>>\n>> Does it?  Only in compat/regex/regex_internal.h, which does not leak\n>> to other code, no?\n> \n> As we also do \n> \n> ifneq (,$(INLINE))\n>         BASIC_CFLAGS += -Dinline=$(INLINE)\n> endif\n> \n> in the Makefile so we cannot tell what people do with their\n> config.mak ;-).\n\nAh, missed that.\n\nSo setting INLINE to an empty string does nothing.  We do that for an\nancient versions of HP-UX in config.mak.uname.\n\nWhen I set it to '', like we do in config.mak.uname for an ancient\nversion of AIX, I get lots of warnings about unused functions and\nlinking errors due to duplicate symbols.  I can only hope that the\npre-C99 compilers targeted by this measure can better deal with that\nissue somehow.\n\n> And obviously other projects do not share our Makefile, so it is not\n> too much of stretch to say Git \"knows to define\", even though it may\n> be more precise to say \"knows to let users redefine\", perhaps?\n\nFair enough.\n\nRené\n\n"},{"id":"540574","messageId":"acxF0cwfVTbqn-XM@fruit.crustytoothpaste.net","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-1-46bfae55c68c@pks.im","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2026-03-31T22:08:17Z","receivedAt":"2026-03-31T22:17:00Z","isPatch":true,"body":"On 2026-03-31 at 11:26:47, Patrick Steinhardt wrote:\n> Not every compiler knows about the `inline` annotation for functions.\n> Consequently, Git knows to define `inline` as an empty macro in case\n> it's not available.\n\nI thought `inline` was in C99, which would mean that it's been required\nin C for over 26 years old—it's older than some of my colleagues.  What\ncompilers are people using in 2026 that don't know about `inline`?  Or\nmore importantly, what platforms are people using in 2026 that lack a\nusable compiler with at least C99?\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"540636","messageId":"ac0MAbnB_vIArxv0@pks.im","threadId":"65394","inReplyTo":"acxF0cwfVTbqn-XM@fruit.crustytoothpaste.net","subject":"Re: [PATCH 1/6] reftable/system: provide `REFTABLE_INLINE()` macro","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-01T12:13:53Z","receivedAt":"2026-04-01T12:13:59Z","isPatch":true,"body":"On Tue, Mar 31, 2026 at 10:08:17PM +0000, brian m. carlson wrote:\n> On 2026-03-31 at 11:26:47, Patrick Steinhardt wrote:\n> > Not every compiler knows about the `inline` annotation for functions.\n> > Consequently, Git knows to define `inline` as an empty macro in case\n> > it's not available.\n> \n> I thought `inline` was in C99, which would mean that it's been required\n> in C for over 26 years old—it's older than some of my colleagues.  What\n> compilers are people using in 2026 that don't know about `inline`?  Or\n> more importantly, what platforms are people using in 2026 that lack a\n> usable compiler with at least C99?\n\nSurprisingly there are still projects out there that explicitly use C90,\nand libgit2 is one of them. it prouds itself with still compiling on\nAmiga OS. Whether it actually does may be a different question though.\nI kind of doubt it.\n\nPatrick\n"},{"id":"540637","messageId":"ac0MB8O5h7ek_8ZX@pks.im","threadId":"65394","inReplyTo":"xmqq5x6b27ms.fsf@gitster.g","subject":"Re: [PATCH 2/6] reftable/stack: don't call fsync(3p) unless provided","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-01T12:13:59Z","receivedAt":"2026-04-01T12:14:04Z","isPatch":true,"body":"On Tue, Mar 31, 2026 at 11:09:31AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > Users of the reftable library are expected to provide their own function\n> > callback in cases they want to sync(3p) data to disk via the reftable\n> > write options. But if no such function was provided we end up calling\n> > fsync(3p) directly, which may not even be available on some systems.\n> >\n> > Drop the call to fsync(3p) and rely on the callback function\n> > exclusively.\n> \n> Hmph, reftable-backend.c seems to do\n> \n> \trefs->write_options.fsync = reftable_be_fsync;\n> \n> in its _be_init(), so this change is a no-op in the context of our\n> system, so this may be _safe_, but for a caller that wanted a fsync\n> to happen, returning to it without doing anything may be a bit\n> unexpected.  I am wondering if it should be more like\n> \n> \tif (!opts->fsync)\n> \t\t/* BUG(\"whoa where is your fsync callback???\") */\n> \t\treutrn -1;\n> \treturn opts->fsync(fd);\n> \n> instead.\n\nHm, I guess that's a fair concern. Anyone who doesn't want to fsync can\njust provide a no-op function, so it's easy enough for others to stub\nout while being safe by default.\n\nI guess the only question in that case is whether it even makes sense to\nspecify this as an option, or whether we'd rather want to make this part\nof the \"system.{c,h}\" interface, as well.\n\nPatrick\n"},{"id":"540638","messageId":"ac0MDTQR484_yxuv@pks.im","threadId":"65394","inReplyTo":"xmqqwlyrzwh0.fsf@gitster.g","subject":"Re: [PATCH 6/6] reftable: introduce \"reftable-system.h\" header","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-01T12:14:05Z","receivedAt":"2026-04-01T12:14:10Z","isPatch":true,"body":"On Tue, Mar 31, 2026 at 11:26:35AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > We're including a couple of standard headers like <stdint.h> in a bunch\n> > of locations, which makes it hard for a project to plug in their own\n> > logic for making required functionality available. For us this is for\n> > example via \"compat/posix.h\", which already includes all of the system\n> > headers relevant to us.\n> \n> Hmmm.  This is interesting.\n> \n> > diff --git a/reftable/reftable-system.h b/reftable/reftable-system.h\n> > new file mode 100644\n> > index 0000000000..f90c415182\n> > --- /dev/null\n> > +++ b/reftable/reftable-system.h\n> > @@ -0,0 +1,7 @@\n> > +#ifndef REFTABLE_SYSTEM_H\n> > +#define REFTABLE_SYSTEM_H\n> > +\n> > +#define MINGW_DONT_HANDLE_IN_USE_ERROR\n> > +#include \"compat/posix.h\"\n> > +\n> > +#endif\n> \n> This one is clearly tailored to be used in the context of our\n> system.\n> \n> > diff --git a/reftable/system.h b/reftable/system.h\n> > index dffc717bd4..52f964c04b 100644\n> > --- a/reftable/system.h\n> > +++ b/reftable/system.h\n> > @@ -11,8 +11,7 @@\n> >  \n> >  /* This header glues the reftable library to the rest of Git */\n> >  \n> > -#define MINGW_DONT_HANDLE_IN_USE_ERROR\n> > -#include \"compat/posix.h\"\n> > +#include \"reftable-system.h\"\n> >  #include \"compat/zlib-compat.h\"\n> >  \n> >  #define REFTABLE_INLINE(type) static inline type\n> \n> And so far in this series, I was getting the impression that\n> reftable/system.c and reftable/system.h are where the target system\n> specific definitions are stored.\n> \n> The implementation detail of how we obtain the wallclock time at\n> millisecond resolution is in reftable/system.c, the implementation\n> detail of how our mmap() emulation can work to build reftable_mmap()\n> is in reftable/system.c, for example.\n> \n> But the corresponding reftable/system.h does not seem to be specific\n> to the target system at all---it describes the common abstraction,\n> like \"reftable code proper is expected call reftable_mmap() on any\n> system\" and \"the way for reftable code is expected to read the\n> wallclock is by calling reftable_time_ms()\".\n\nIt almost isn't. There are a few small parts in here that are specific.\nI was also wondering whether I want to try and adapt it so that it can\nalways remain the exact same.\n\n> So <reftable-system.h>, just like <reftable/system.c>, is expected\n> to have a target platform specific \"implementation\", and not like\n> <reftable/system.h> that is expected to be platform neutral (this\n> neutrality comes from the fact that <reftable/system.c> will\n> implement the interface specified in <reftable/system.h> for the\n> target platform).\n> \n> Which somehow feels confusing.\n> \n> Besides, the definition of \"REFTABLE_INLINE(type)\" being \"static\n> inline type\", according to the explanation in [1/6], is valid only\n> in the context of this project, so shouldn't it be done inside\n> <reftable-system.h>, not <reftable/system.h>\"?  For that matter,\n> what about inclusion of \"compat/zlib-compat.h\"?  Is it widely\n> applicable across target platforms, or very specific to our codebase\n> where this library is used/embedded in?\n\nIt overall is a tiny bit confusing, agreed. The reftable interfaces are\nsplit into two parts:\n\n  - \"reftable/foo.h\" contains the library-internal API surface.\n\n  - \"reftable/reftable-foo.h\" contains the external API surface as it\n    should be consumed by the project that embeds the reftable library.\n\nNow for most of the part, headers in the \"reftable/reftable-*.h\"\nnamespace are self-contained. But naturally, we also use some types\nthere that require us to include headers, like `uint32_t` et al.\nThe requirements that we have here are significantly smaller though than\nwhat we expose via \"reftable/system.h\".\n\nSo ultimately, the idea was to have \"reftable/reftable-system.h\" expose\nthe POSIX-like environment that is project-specific to make the other\npublic headers compile as standalone units. And then have the\nimplementeation sit in \"reftable/system.c\". But I agree that\n\"reftable/system.h\" itself still sits somewhere in between of being\nplatform specific and containing project-specific stuff, which isn't\ngreat.\n\nI'm overall not a 100% happy myself with the split and agree that it's\nsomewhat confusing. An alternative would be to say that it's the\ncaller's responsibility to ensure that our public-facing headers have\nall dependencies satisfied, which I think is in practice only <stdint.h>.\n\nI'm very open to alternative suggestions though.\n\nThanks!\n\nPatrick\n"},{"id":"540652","messageId":"xmqqse9ewsaw.fsf@gitster.g","threadId":"65394","inReplyTo":"ac0MDTQR484_yxuv@pks.im","subject":"Re: [PATCH 6/6] reftable: introduce \"reftable-system.h\" header","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-01T16:37:11Z","receivedAt":"2026-04-01T16:37:15Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> It overall is a tiny bit confusing, agreed. The reftable interfaces are\n> split into two parts:\n>\n>   - \"reftable/foo.h\" contains the library-internal API surface.\n>\n>   - \"reftable/reftable-foo.h\" contains the external API surface as it\n>     should be consumed by the project that embeds the reftable library.\n>\n> Now for most of the part, headers in the \"reftable/reftable-*.h\"\n> namespace are self-contained. But naturally, we also use some types\n> there that require us to include headers, like `uint32_t` et al.\n> The requirements that we have here are significantly smaller though than\n> what we expose via \"reftable/system.h\".\n>\n> So ultimately, the idea was to have \"reftable/reftable-system.h\" expose\n> the POSIX-like environment that is project-specific to make the other\n> public headers compile as standalone units. And then have the\n> implementeation sit in \"reftable/system.c\". But I agree that\n> \"reftable/system.h\" itself still sits somewhere in between of being\n> platform specific and containing project-specific stuff, which isn't\n> great.\n>\n> I'm overall not a 100% happy myself with the split and agree that it's\n> somewhat confusing. An alternative would be to say that it's the\n> caller's responsibility to ensure that our public-facing headers have\n> all dependencies satisfied, which I think is in practice only <stdint.h>.\n>\n> I'm very open to alternative suggestions though.\n\nSo your assessment starts as \"tiny bit\" and in the end ends ujp with\n\"somewhat\" confusing ;-)?\n\nI am OK with two level:\n\n - A C source file that will be customized for platform and the\n   project that embeds the library to implement a neutral interface.\n\n - A C header file that defines what that neutral interface looks\n   like, without having any platform/project specific implementation\n   details.\n\nBut that header file, in order to define an interface in a neutral\nway, would need to be able to see common types and things like\n\"inline\", so it is inevitable to have the third thing that is a\nheader file that will be customzed for platform and the project that\nembeds the library.\n\nAnd in that context making reftable/system.c in this series the C\nsource that implements the neutral API for the platform and the\nproject, reftable/system.h the C header that declares the neutral\nAPI, and reftable-system.h the platform specific shim to show a\ncommon definition to reftable/system.h, may be a good division of\nlabor.  So, while I found the _naming_ confusing initially, at least\nbetween reftable/system.[ch], I no longer see the naming of the\nfiles a problem.\n\nThe division of labor is not quite honored in the current\nimplementation, though, as I pointed out that just like MINGW\nspecific things that are moved out of reftable/system.h and to the\nreftable-system.h, other things like inline and compat/zlib-compat.h\nare quite specific to our project and belong to reftable-system.h at\nthe layer that exposes a certain system services to reftable/system.h\nand other \"more common\" parts of the library.\n\n"},{"id":"540705","messageId":"ac4JoLv7SUiedzm9@pks.im","threadId":"65394","inReplyTo":"xmqqse9ewsaw.fsf@gitster.g","subject":"Re: [PATCH 6/6] reftable: introduce \"reftable-system.h\" header","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T06:16:00Z","receivedAt":"2026-04-02T06:16:10Z","isPatch":true,"body":"On Wed, Apr 01, 2026 at 09:37:11AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > It overall is a tiny bit confusing, agreed. The reftable interfaces are\n> > split into two parts:\n> >\n> >   - \"reftable/foo.h\" contains the library-internal API surface.\n> >\n> >   - \"reftable/reftable-foo.h\" contains the external API surface as it\n> >     should be consumed by the project that embeds the reftable library.\n> >\n> > Now for most of the part, headers in the \"reftable/reftable-*.h\"\n> > namespace are self-contained. But naturally, we also use some types\n> > there that require us to include headers, like `uint32_t` et al.\n> > The requirements that we have here are significantly smaller though than\n> > what we expose via \"reftable/system.h\".\n> >\n> > So ultimately, the idea was to have \"reftable/reftable-system.h\" expose\n> > the POSIX-like environment that is project-specific to make the other\n> > public headers compile as standalone units. And then have the\n> > implementeation sit in \"reftable/system.c\". But I agree that\n> > \"reftable/system.h\" itself still sits somewhere in between of being\n> > platform specific and containing project-specific stuff, which isn't\n> > great.\n> >\n> > I'm overall not a 100% happy myself with the split and agree that it's\n> > somewhat confusing. An alternative would be to say that it's the\n> > caller's responsibility to ensure that our public-facing headers have\n> > all dependencies satisfied, which I think is in practice only <stdint.h>.\n> >\n> > I'm very open to alternative suggestions though.\n> \n> So your assessment starts as \"tiny bit\" and in the end ends ujp with\n> \"somewhat\" confusing ;-)?\n> \n> I am OK with two level:\n> \n>  - A C source file that will be customized for platform and the\n>    project that embeds the library to implement a neutral interface.\n> \n>  - A C header file that defines what that neutral interface looks\n>    like, without having any platform/project specific implementation\n>    details.\n> \n> But that header file, in order to define an interface in a neutral\n> way, would need to be able to see common types and things like\n> \"inline\", so it is inevitable to have the third thing that is a\n> header file that will be customzed for platform and the project that\n> embeds the library.\n> \n> And in that context making reftable/system.c in this series the C\n> source that implements the neutral API for the platform and the\n> project, reftable/system.h the C header that declares the neutral\n> API, and reftable-system.h the platform specific shim to show a\n> common definition to reftable/system.h, may be a good division of\n> labor.  So, while I found the _naming_ confusing initially, at least\n> between reftable/system.[ch], I no longer see the naming of the\n> files a problem.\n> \n> The division of labor is not quite honored in the current\n> implementation, though, as I pointed out that just like MINGW\n> specific things that are moved out of reftable/system.h and to the\n> reftable-system.h, other things like inline and compat/zlib-compat.h\n> are quite specific to our project and belong to reftable-system.h at\n> the layer that exposes a certain system services to reftable/system.h\n> and other \"more common\" parts of the library.\n\nMakes sense, thanks for your input! Will send a new version soonish.\n\nPatrick\n"},{"id":"540731","messageId":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im","subject":"[PATCH v2 0/5] reftable: some more portability improvements","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:13Z","receivedAt":"2026-04-02T07:31:28Z","isPatch":true,"body":"Hi,\n\nthis patch series contains the last set of portability improvements\nthat currently sits in the reftable implementation of libgit2. With\nthese patches merged lbigit2 is able to fully reuse the reftable library\nwhile only having to provide its own system headers.\n\nI've got a test run with libgit2 at [1], the code in Git is tested at\n[2]. Overall we're quite close -- the pull requests to implement the\nrepository extension and to adjust handling of pseudo-refs have been\nmerged. Still missing is a couple of test fixes, but once those are\nmerged the reftable backend itself will be in review.\n\nChanges in v2:\n  - Reorder commits a bit so that we introduce \"reftable-system.h\" early\n    on.\n  - Make the split between \"reftable-system.h\" and \"system.h\" cleaner\n    and explain it better.\n  - Drop the `REFTABLE_INLINE()` patch. I can work around it in libgit2\n    itself.\n  - Drop the fsync callback and instead require it to exist, so that we\n    can do some macro magic to use our own `fsync_component()` instead.\n  - Rebased the libgit2 changes on top of this series to verify that\n    we're still moving into the right direction.\n  - Link to v1: https://patch.msgid.link/20260331-pks-reftable-portability-fixes-v1-0-46bfae55c68c@pks.im\n\nThanks!\n\nPatrick\n\n[1]: https://github.com/libgit2/libgit2/pull/7117\n[2]: https://gitlab.com/gitlab-org/git/-/merge_requests/535\n\n---\nPatrick Steinhardt (5):\n      reftable: introduce \"reftable-system.h\" header\n      reftable/stack: provide fsync(3p) via system header\n      reftable/fsck: use REFTABLE_UNUSED instead of UNUSED\n      reftable/system: add abstraction to retrieve time in milliseconds\n      reftable/system: add abstraction to mmap files\n\n refs/reftable-backend.c         |  6 ------\n reftable/blocksource.c          | 19 +++++++------------\n reftable/fsck.c                 |  2 +-\n reftable/reftable-basics.h      |  2 +-\n reftable/reftable-block.h       |  3 +--\n reftable/reftable-blocksource.h |  2 +-\n reftable/reftable-error.h       |  2 ++\n reftable/reftable-fsck.h        |  1 +\n reftable/reftable-iterator.h    |  1 +\n reftable/reftable-merged.h      |  1 +\n reftable/reftable-record.h      |  2 +-\n reftable/reftable-stack.h       |  1 +\n reftable/reftable-system.h      | 18 ++++++++++++++++++\n reftable/reftable-table.h       |  1 +\n reftable/reftable-writer.h      | 10 +---------\n reftable/stack.c                | 40 +++++++---------------------------------\n reftable/system.c               | 32 ++++++++++++++++++++++++++++++++\n reftable/system.h               | 32 ++++++++++++++++++++++++++++----\n 18 files changed, 105 insertions(+), 70 deletions(-)\n\nRange-diff versus v1:\n\n1:  77c23e530a < -:  ---------- reftable/system: provide `REFTABLE_INLINE()` macro\n2:  a32aeffa92 < -:  ---------- reftable/stack: don't call fsync(3p) unless provided\n6:  5413397e77 ! 1:  11f69c228e reftable: introduce \"reftable-system.h\" header\n    @@ Commit message\n         headers relevant to us.\n     \n         Introduce a new \"reftable-system.h\" header that allows projects to\n    -    provide their own headers.\n    +    provide their own headers. This new header is supposed to contain all\n    +    the project-specific bits to provide the POSIX-like environment, and some\n    +    additional supporting code. With this change, we thus have the following\n    +    split in our system-specific code:\n    +\n    +      - \"reftable/reftable-system.h\" is the project-specific header that\n    +        provides a POSIX-like environment. Every project is expected to\n    +        provide their own implementation.\n    +\n    +      - \"reftable/system.h\" contains the project-independent definition of\n    +        the interfaces that a project needs to implement. This file should\n    +        not be touched by a project.\n    +\n    +      - \"reftable/system.c\" contains the project-specific implementation of\n    +        the interfaces defined in \"system.h\". Again, every project is\n    +        expected to provide their own implementation.\n     \n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n    @@ reftable/reftable-system.h (new)\n     +#ifndef REFTABLE_SYSTEM_H\n     +#define REFTABLE_SYSTEM_H\n     +\n    ++/*\n    ++ * This header defines the platform-specific bits required to compile the\n    ++ * reftable library. It should provide an environment that bridges over the\n    ++ * gaps between POSIX and your system, as well as the zlib interfaces. This\n    ++ * header is expected to be changed by the individual project.\n    ++ */\n    ++\n     +#define MINGW_DONT_HANDLE_IN_USE_ERROR\n     +#include \"compat/posix.h\"\n    ++#include \"compat/zlib-compat.h\"\n     +\n     +#endif\n     \n    @@ reftable/reftable-writer.h\n     \n      ## reftable/system.h ##\n     @@\n    + #ifndef SYSTEM_H\n    + #define SYSTEM_H\n      \n    - /* This header glues the reftable library to the rest of Git */\n    +-/* This header glues the reftable library to the rest of Git */\n    ++/*\n    ++ * This header defines the platform-agnostic interface that is to be\n    ++ * implemented by the project to make it work on their respective supported\n    ++ * systems, and to integrate it into the project itself. This header is not\n    ++ * expected to be changed by the individual project.\n    ++ */\n      \n     -#define MINGW_DONT_HANDLE_IN_USE_ERROR\n     -#include \"compat/posix.h\"\n    +-#include \"compat/zlib-compat.h\"\n     +#include \"reftable-system.h\"\n    - #include \"compat/zlib-compat.h\"\n      \n    - #define REFTABLE_INLINE(type) static inline type\n    + /*\n    +  * Return a random 32 bit integer. This function is expected to return\n-:  ---------- > 2:  422c12955e reftable/stack: provide fsync(3p) via system header\n3:  94bd6cae41 = 3:  73fa205b5a reftable/fsck: use REFTABLE_UNUSED instead of UNUSED\n4:  ea5aa25f71 ! 4:  139583e68a reftable/system: add abstraction to retrieve time in milliseconds\n    @@ reftable/system.c\n      #include \"../lockfile.h\"\n     +#include \"../trace.h\"\n      #include \"../tempfile.h\"\n    + #include \"../write-or-die.h\"\n      \n    - uint32_t reftable_rand(void)\n    -@@ reftable/system.c: int flock_commit(struct reftable_flock *l)\n    - \n    - \treturn 0;\n    +@@ reftable/system.c: int reftable_fsync(int fd)\n    + {\n    + \treturn fsync_component(FSYNC_COMPONENT_REFERENCE, fd);\n      }\n     +\n     +uint64_t reftable_time_ms(void)\n5:  27d055eecd = 5:  a445a6e6eb reftable/system: add abstraction to mmap files\n\n---\nbase-commit: 270e10ad6dda3379ea0da7efd11e4fbf2cd7a325\nchange-id: 20260330-pks-reftable-portability-fixes-36ebf9f227c2\n\n"},{"id":"540732","messageId":"20260402-pks-reftable-portability-fixes-v2-1-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","subject":"[PATCH v2 1/5] reftable: introduce \"reftable-system.h\" header","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:14Z","receivedAt":"2026-04-02T07:31:31Z","isPatch":true,"body":"We're including a couple of standard headers like <stdint.h> in a bunch\nof locations, which makes it hard for a project to plug in their own\nlogic for making required functionality available. For us this is for\nexample via \"compat/posix.h\", which already includes all of the system\nheaders relevant to us.\n\nIntroduce a new \"reftable-system.h\" header that allows projects to\nprovide their own headers. This new header is supposed to contain all\nthe project-specific bits to provide the POSIX-like environment, and some\nadditional supporting code. With this change, we thus have the following\nsplit in our system-specific code:\n\n  - \"reftable/reftable-system.h\" is the project-specific header that\n    provides a POSIX-like environment. Every project is expected to\n    provide their own implementation.\n\n  - \"reftable/system.h\" contains the project-independent definition of\n    the interfaces that a project needs to implement. This file should\n    not be touched by a project.\n\n  - \"reftable/system.c\" contains the project-specific implementation of\n    the interfaces defined in \"system.h\". Again, every project is\n    expected to provide their own implementation.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/reftable-basics.h      |  2 +-\n reftable/reftable-block.h       |  3 +--\n reftable/reftable-blocksource.h |  2 +-\n reftable/reftable-error.h       |  2 ++\n reftable/reftable-fsck.h        |  1 +\n reftable/reftable-iterator.h    |  1 +\n reftable/reftable-merged.h      |  1 +\n reftable/reftable-record.h      |  2 +-\n reftable/reftable-stack.h       |  1 +\n reftable/reftable-system.h      | 15 +++++++++++++++\n reftable/reftable-table.h       |  1 +\n reftable/reftable-writer.h      |  4 +---\n reftable/system.h               | 11 +++++++----\n 13 files changed, 34 insertions(+), 12 deletions(-)\n\ndiff --git a/reftable/reftable-basics.h b/reftable/reftable-basics.h\nindex 6d73f19c85..dc8622682d 100644\n--- a/reftable/reftable-basics.h\n+++ b/reftable/reftable-basics.h\n@@ -9,7 +9,7 @@\n #ifndef REFTABLE_BASICS_H\n #define REFTABLE_BASICS_H\n \n-#include <stddef.h>\n+#include \"reftable-system.h\"\n \n /* A buffer that contains arbitrary byte slices. */\n struct reftable_buf {\ndiff --git a/reftable/reftable-block.h b/reftable/reftable-block.h\nindex 0b05a8f7e3..94c79b5c58 100644\n--- a/reftable/reftable-block.h\n+++ b/reftable/reftable-block.h\n@@ -9,8 +9,7 @@\n #ifndef REFTABLE_BLOCK_H\n #define REFTABLE_BLOCK_H\n \n-#include <stdint.h>\n-\n+#include \"reftable-system.h\"\n #include \"reftable-basics.h\"\n #include \"reftable-blocksource.h\"\n #include \"reftable-iterator.h\"\ndiff --git a/reftable/reftable-blocksource.h b/reftable/reftable-blocksource.h\nindex f5ba867bd6..40c1e94646 100644\n--- a/reftable/reftable-blocksource.h\n+++ b/reftable/reftable-blocksource.h\n@@ -9,7 +9,7 @@\n #ifndef REFTABLE_BLOCKSOURCE_H\n #define REFTABLE_BLOCKSOURCE_H\n \n-#include <stdint.h>\n+#include \"reftable-system.h\"\n \n /*\n  * Generic wrapper for a seekable readable file.\ndiff --git a/reftable/reftable-error.h b/reftable/reftable-error.h\nindex d100e0df92..0535e1478b 100644\n--- a/reftable/reftable-error.h\n+++ b/reftable/reftable-error.h\n@@ -9,6 +9,8 @@\n #ifndef REFTABLE_ERROR_H\n #define REFTABLE_ERROR_H\n \n+#include \"reftable-system.h\"\n+\n /*\n  * Errors in reftable calls are signaled with negative integer return values. 0\n  * means success.\ndiff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h\nindex 007a392cf9..340fc7762e 100644\n--- a/reftable/reftable-fsck.h\n+++ b/reftable/reftable-fsck.h\n@@ -1,6 +1,7 @@\n #ifndef REFTABLE_FSCK_H\n #define REFTABLE_FSCK_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-stack.h\"\n \n enum reftable_fsck_error {\ndiff --git a/reftable/reftable-iterator.h b/reftable/reftable-iterator.h\nindex af582028c2..a050cc153b 100644\n--- a/reftable/reftable-iterator.h\n+++ b/reftable/reftable-iterator.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_ITERATOR_H\n #define REFTABLE_ITERATOR_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-record.h\"\n \n struct reftable_iterator_vtable;\ndiff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h\nindex e5af846b32..02a9966835 100644\n--- a/reftable/reftable-merged.h\n+++ b/reftable/reftable-merged.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_MERGED_H\n #define REFTABLE_MERGED_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-iterator.h\"\n \n /*\ndiff --git a/reftable/reftable-record.h b/reftable/reftable-record.h\nindex 385a74cc86..e18c538238 100644\n--- a/reftable/reftable-record.h\n+++ b/reftable/reftable-record.h\n@@ -9,8 +9,8 @@\n #ifndef REFTABLE_RECORD_H\n #define REFTABLE_RECORD_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-basics.h\"\n-#include <stdint.h>\n \n /*\n  * Basic data types\ndiff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h\nindex c2415cbc6e..5f7be573fa 100644\n--- a/reftable/reftable-stack.h\n+++ b/reftable/reftable-stack.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_STACK_H\n #define REFTABLE_STACK_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-writer.h\"\n \n /*\ndiff --git a/reftable/reftable-system.h b/reftable/reftable-system.h\nnew file mode 100644\nindex 0000000000..4a18a6a790\n--- /dev/null\n+++ b/reftable/reftable-system.h\n@@ -0,0 +1,15 @@\n+#ifndef REFTABLE_SYSTEM_H\n+#define REFTABLE_SYSTEM_H\n+\n+/*\n+ * This header defines the platform-specific bits required to compile the\n+ * reftable library. It should provide an environment that bridges over the\n+ * gaps between POSIX and your system, as well as the zlib interfaces. This\n+ * header is expected to be changed by the individual project.\n+ */\n+\n+#define MINGW_DONT_HANDLE_IN_USE_ERROR\n+#include \"compat/posix.h\"\n+#include \"compat/zlib-compat.h\"\n+\n+#endif\ndiff --git a/reftable/reftable-table.h b/reftable/reftable-table.h\nindex 5f935d02e3..d7666b53a1 100644\n--- a/reftable/reftable-table.h\n+++ b/reftable/reftable-table.h\n@@ -9,6 +9,7 @@\n #ifndef REFTABLE_TABLE_H\n #define REFTABLE_TABLE_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-iterator.h\"\n #include \"reftable-block.h\"\n #include \"reftable-blocksource.h\"\ndiff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h\nindex 1e7003cd69..065dd93dc6 100644\n--- a/reftable/reftable-writer.h\n+++ b/reftable/reftable-writer.h\n@@ -9,11 +9,9 @@\n #ifndef REFTABLE_WRITER_H\n #define REFTABLE_WRITER_H\n \n+#include \"reftable-system.h\"\n #include \"reftable-record.h\"\n \n-#include <stdint.h>\n-#include <unistd.h> /* ssize_t */\n-\n /* Writing single reftables */\n \n /* reftable_write_options sets options for writing a single reftable. */\ndiff --git a/reftable/system.h b/reftable/system.h\nindex c54ed4cad6..a7eb6acd4a 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -9,11 +9,14 @@\n #ifndef SYSTEM_H\n #define SYSTEM_H\n \n-/* This header glues the reftable library to the rest of Git */\n+/*\n+ * This header defines the platform-agnostic interface that is to be\n+ * implemented by the project to make it work on their respective supported\n+ * systems, and to integrate it into the project itself. This header is not\n+ * expected to be changed by the individual project.\n+ */\n \n-#define MINGW_DONT_HANDLE_IN_USE_ERROR\n-#include \"compat/posix.h\"\n-#include \"compat/zlib-compat.h\"\n+#include \"reftable-system.h\"\n \n /*\n  * Return a random 32 bit integer. This function is expected to return\n\n-- \n2.53.0.1323.g189a785ab5.dirty\n\n"},{"id":"540733","messageId":"20260402-pks-reftable-portability-fixes-v2-2-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","subject":"[PATCH v2 2/5] reftable/stack: provide fsync(3p) via system header","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:15Z","receivedAt":"2026-04-02T07:31:33Z","isPatch":true,"body":"Users of the reftable library are expected to provide their own function\ncallback in cases they want to sync(3p) data to disk via the reftable\nwrite options. But if no such function was provided we end up calling\nfsync(3p) directly, which may not even be available on some systems.\n\nWhile dropping the explicit call to fsync(3p) would work, it would lead\nto an unsafe default behaviour where a project may have forgotten to set\nup the callback function, and that could lead to potential data loss. So\nthis is not a great solution.\n\nInstead, drop the callback function and make it mandatory for the\nproject to define fsync(3p). In the case of Git, we can then easily\ninject our custom implementation via the \"reftable-system.h\" header so\nthat we continue to use `fsync_component()`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n refs/reftable-backend.c    |  6 ------\n reftable/reftable-system.h |  3 +++\n reftable/reftable-writer.h |  6 ------\n reftable/stack.c           | 13 +++----------\n reftable/system.c          |  6 ++++++\n 5 files changed, 12 insertions(+), 22 deletions(-)\n\ndiff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\nindex b124404663..daea30a5b4 100644\n--- a/refs/reftable-backend.c\n+++ b/refs/reftable-backend.c\n@@ -366,11 +366,6 @@ static int reftable_be_config(const char *var, const char *value,\n \treturn 0;\n }\n \n-static int reftable_be_fsync(int fd)\n-{\n-\treturn fsync_component(FSYNC_COMPONENT_REFERENCE, fd);\n-}\n-\n static struct ref_store *reftable_be_init(struct repository *repo,\n \t\t\t\t\t  const char *payload,\n \t\t\t\t\t  const char *gitdir,\n@@ -408,7 +403,6 @@ static struct ref_store *reftable_be_init(struct repository *repo,\n \trefs->write_options.disable_auto_compact =\n \t\t!git_env_bool(\"GIT_TEST_REFTABLE_AUTOCOMPACTION\", 1);\n \trefs->write_options.lock_timeout_ms = 100;\n-\trefs->write_options.fsync = reftable_be_fsync;\n \n \trepo_config(the_repository, reftable_be_config, &refs->write_options);\n \ndiff --git a/reftable/reftable-system.h b/reftable/reftable-system.h\nindex 4a18a6a790..76f3e33e90 100644\n--- a/reftable/reftable-system.h\n+++ b/reftable/reftable-system.h\n@@ -12,4 +12,7 @@\n #include \"compat/posix.h\"\n #include \"compat/zlib-compat.h\"\n \n+int reftable_fsync(int fd);\n+#define fsync(fd) reftable_fsync(fd)\n+\n #endif\ndiff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h\nindex 065dd93dc6..a66db415c8 100644\n--- a/reftable/reftable-writer.h\n+++ b/reftable/reftable-writer.h\n@@ -61,12 +61,6 @@ struct reftable_write_options {\n \t */\n \tlong lock_timeout_ms;\n \n-\t/*\n-\t * Optional callback used to fsync files to disk. Falls back to using\n-\t * fsync(3P) when unset.\n-\t */\n-\tint (*fsync)(int fd);\n-\n \t/*\n \t * Callback function to execute whenever the stack is being reloaded.\n \t * This can be used e.g. to discard cached information that relies on\ndiff --git a/reftable/stack.c b/reftable/stack.c\nindex 1c9f21dfe1..fa87b46c37 100644\n--- a/reftable/stack.c\n+++ b/reftable/stack.c\n@@ -29,13 +29,6 @@ static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st,\n \treturn 0;\n }\n \n-static int stack_fsync(const struct reftable_write_options *opts, int fd)\n-{\n-\tif (opts->fsync)\n-\t\treturn opts->fsync(fd);\n-\treturn fsync(fd);\n-}\n-\n static ssize_t reftable_write_data(int fd, const void *data, size_t size)\n {\n \tsize_t total_written = 0;\n@@ -69,7 +62,7 @@ static ssize_t fd_writer_write(void *arg, const void *data, size_t sz)\n static int fd_writer_flush(void *arg)\n {\n \tstruct fd_writer *writer = arg;\n-\treturn stack_fsync(writer->opts, writer->fd);\n+\treturn fsync(writer->fd);\n }\n \n static int fd_read_lines(int fd, char ***namesp)\n@@ -812,7 +805,7 @@ int reftable_addition_commit(struct reftable_addition *add)\n \t\tgoto done;\n \t}\n \n-\terr = stack_fsync(&add->stack->opts, add->tables_list_lock.fd);\n+\terr = fsync(add->tables_list_lock.fd);\n \tif (err < 0) {\n \t\terr = REFTABLE_IO_ERROR;\n \t\tgoto done;\n@@ -1480,7 +1473,7 @@ static int stack_compact_range(struct reftable_stack *st,\n \t\tgoto done;\n \t}\n \n-\terr = stack_fsync(&st->opts, tables_list_lock.fd);\n+\terr = fsync(tables_list_lock.fd);\n \tif (err < 0) {\n \t\terr = REFTABLE_IO_ERROR;\n \t\tunlink(new_table_path.buf);\ndiff --git a/reftable/system.c b/reftable/system.c\nindex 725a25844e..4d7e366b55 100644\n--- a/reftable/system.c\n+++ b/reftable/system.c\n@@ -5,6 +5,7 @@\n #include \"reftable-error.h\"\n #include \"../lockfile.h\"\n #include \"../tempfile.h\"\n+#include \"../write-or-die.h\"\n \n uint32_t reftable_rand(void)\n {\n@@ -131,3 +132,8 @@ int flock_commit(struct reftable_flock *l)\n \n \treturn 0;\n }\n+\n+int reftable_fsync(int fd)\n+{\n+\treturn fsync_component(FSYNC_COMPONENT_REFERENCE, fd);\n+}\n\n-- \n2.53.0.1323.g189a785ab5.dirty\n\n"},{"id":"540734","messageId":"20260402-pks-reftable-portability-fixes-v2-3-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","subject":"[PATCH v2 3/5] reftable/fsck: use REFTABLE_UNUSED instead of UNUSED","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:16Z","receivedAt":"2026-04-02T07:31:36Z","isPatch":true,"body":"While we have the reftable-specific `REFTABLE_UNUSED` header, we\naccidentally introduced a new usage of the Git-specific `UNUSED` header\ninto the reftable library in 9051638519 (reftable: add code to\nfacilitate consistency checks, 2025-10-07).\n\nConvert the site to use `REFTABLE_UNUSED`.\n\nIdeally, we'd move the definition of `UNUSED` into \"git-compat-util.h\"\nso that it becomes in accessible to the reftable library. But this is\nunfortunately not easily possible as \"compat/mingw-posix.h\" requires\nthis macro, and this header is included by \"compat/posix.h\".\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/fsck.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/reftable/fsck.c b/reftable/fsck.c\nindex 26b9115b14..8e73fc83f2 100644\n--- a/reftable/fsck.c\n+++ b/reftable/fsck.c\n@@ -63,7 +63,7 @@ static int table_check_name(struct reftable_table *table,\n \n static int table_checks(struct reftable_table *table,\n \t\t\treftable_fsck_report_fn report_fn,\n-\t\t\treftable_fsck_verbose_fn verbose_fn UNUSED,\n+\t\t\treftable_fsck_verbose_fn verbose_fn REFTABLE_UNUSED,\n \t\t\tvoid *cb_data)\n {\n \ttable_check_fn table_check_fns[] = {\n\n-- \n2.53.0.1323.g189a785ab5.dirty\n\n"},{"id":"540735","messageId":"20260402-pks-reftable-portability-fixes-v2-4-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","subject":"[PATCH v2 4/5] reftable/system: add abstraction to retrieve time in milliseconds","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:17Z","receivedAt":"2026-04-02T07:31:38Z","isPatch":true,"body":"We directly call gettimeofday(3p), which may not be available on some\nplatforms. Provide the infrastructure to let projects easily use their\nown implementations of this function.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/stack.c  | 27 ++++-----------------------\n reftable/system.c |  6 ++++++\n reftable/system.h |  3 +++\n 3 files changed, 13 insertions(+), 23 deletions(-)\n\ndiff --git a/reftable/stack.c b/reftable/stack.c\nindex fa87b46c37..1fba96ddb3 100644\n--- a/reftable/stack.c\n+++ b/reftable/stack.c\n@@ -365,45 +365,26 @@ static int reftable_stack_reload_once(struct reftable_stack *st,\n \treturn err;\n }\n \n-/* return negative if a before b. */\n-static int tv_cmp(struct timeval *a, struct timeval *b)\n-{\n-\ttime_t diff = a->tv_sec - b->tv_sec;\n-\tint udiff = a->tv_usec - b->tv_usec;\n-\n-\tif (diff != 0)\n-\t\treturn diff;\n-\n-\treturn udiff;\n-}\n-\n static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,\n \t\t\t\t\t     int reuse_open)\n {\n \tchar **names = NULL, **names_after = NULL;\n-\tstruct timeval deadline;\n+\tuint64_t deadline;\n \tint64_t delay = 0;\n \tint tries = 0, err;\n \tint fd = -1;\n \n-\terr = gettimeofday(&deadline, NULL);\n-\tif (err < 0)\n-\t\tgoto out;\n-\tdeadline.tv_sec += 3;\n+\tdeadline = reftable_time_ms() + 3000;\n \n \twhile (1) {\n-\t\tstruct timeval now;\n-\n-\t\terr = gettimeofday(&now, NULL);\n-\t\tif (err < 0)\n-\t\t\tgoto out;\n+\t\tuint64_t now = reftable_time_ms();\n \n \t\t/*\n \t\t * Only look at deadlines after the first few times. This\n \t\t * simplifies debugging in GDB.\n \t\t */\n \t\ttries++;\n-\t\tif (tries > 3 && tv_cmp(&now, &deadline) >= 0)\n+\t\tif (tries > 3 && now >= deadline)\n \t\t\tgoto out;\n \n \t\tfd = open(st->list_file, O_RDONLY);\ndiff --git a/reftable/system.c b/reftable/system.c\nindex 4d7e366b55..cd76e56be8 100644\n--- a/reftable/system.c\n+++ b/reftable/system.c\n@@ -4,6 +4,7 @@\n #include \"basics.h\"\n #include \"reftable-error.h\"\n #include \"../lockfile.h\"\n+#include \"../trace.h\"\n #include \"../tempfile.h\"\n #include \"../write-or-die.h\"\n \n@@ -137,3 +138,8 @@ int reftable_fsync(int fd)\n {\n \treturn fsync_component(FSYNC_COMPONENT_REFERENCE, fd);\n }\n+\n+uint64_t reftable_time_ms(void)\n+{\n+\treturn getnanotime() / 1000000;\n+}\ndiff --git a/reftable/system.h b/reftable/system.h\nindex a7eb6acd4a..071bfa3d58 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -111,4 +111,7 @@ int flock_release(struct reftable_flock *l);\n  */\n int flock_commit(struct reftable_flock *l);\n \n+/* Report the time in milliseconds. */\n+uint64_t reftable_time_ms(void);\n+\n #endif\n\n-- \n2.53.0.1323.g189a785ab5.dirty\n\n"},{"id":"540736","messageId":"20260402-pks-reftable-portability-fixes-v2-5-bc110cee0ae0@pks.im","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-0-bc110cee0ae0@pks.im","subject":"[PATCH v2 5/5] reftable/system: add abstraction to mmap files","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-04-02T07:31:18Z","receivedAt":"2026-04-02T07:31:41Z","isPatch":true,"body":"In our codebase we have a couple of wrappers around mmap(3p) that allow\nus to reimplement the syscall on platforms that don't have it natively,\nlike for example Windows. Other projects that embed the reftable library\nmay have a different infra though to hook up mmap wrappers, but these\nare currently hard to integrate.\n\nProvide the infrastructure to let projects easily define the mmap\ninterface with a custom struct and custom functions.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n reftable/blocksource.c | 19 +++++++------------\n reftable/system.c      | 20 ++++++++++++++++++++\n reftable/system.h      | 18 ++++++++++++++++++\n 3 files changed, 45 insertions(+), 12 deletions(-)\n\ndiff --git a/reftable/blocksource.c b/reftable/blocksource.c\nindex 573c81287f..7f7441f751 100644\n--- a/reftable/blocksource.c\n+++ b/reftable/blocksource.c\n@@ -93,13 +93,12 @@ void block_source_from_buf(struct reftable_block_source *bs,\n }\n \n struct file_block_source {\n-\tuint64_t size;\n-\tunsigned char *data;\n+\tstruct reftable_mmap mmap;\n };\n \n static uint64_t file_size(void *b)\n {\n-\treturn ((struct file_block_source *)b)->size;\n+\treturn ((struct file_block_source *)b)->mmap.size;\n }\n \n static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_data *dest REFTABLE_UNUSED)\n@@ -109,7 +108,7 @@ static void file_release_data(void *b REFTABLE_UNUSED, struct reftable_block_dat\n static void file_close(void *v)\n {\n \tstruct file_block_source *b = v;\n-\tmunmap(b->data, b->size);\n+\treftable_munmap(&b->mmap);\n \treftable_free(b);\n }\n \n@@ -117,8 +116,8 @@ static ssize_t file_read_data(void *v, struct reftable_block_data *dest, uint64_\n \t\t\t      uint32_t size)\n {\n \tstruct file_block_source *b = v;\n-\tassert(off + size <= b->size);\n-\tdest->data = b->data + off;\n+\tassert(off + size <= b->mmap.size);\n+\tdest->data = (unsigned char *) b->mmap.data + off;\n \tdest->len = size;\n \treturn size;\n }\n@@ -156,13 +155,9 @@ int reftable_block_source_from_file(struct reftable_block_source *bs,\n \t\tgoto out;\n \t}\n \n-\tp->size = st.st_size;\n-\tp->data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n-\tif (p->data == MAP_FAILED) {\n-\t\terr = REFTABLE_IO_ERROR;\n-\t\tp->data = NULL;\n+\terr = reftable_mmap(&p->mmap, fd, st.st_size);\n+\tif (err < 0)\n \t\tgoto out;\n-\t}\n \n \tassert(!bs->ops);\n \tbs->ops = &file_vtable;\ndiff --git a/reftable/system.c b/reftable/system.c\nindex cd76e56be8..9063641f30 100644\n--- a/reftable/system.c\n+++ b/reftable/system.c\n@@ -143,3 +143,23 @@ uint64_t reftable_time_ms(void)\n {\n \treturn getnanotime() / 1000000;\n }\n+\n+int reftable_mmap(struct reftable_mmap *out, int fd, size_t len)\n+{\n+\tvoid *data = xmmap_gently(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);\n+\tif (data == MAP_FAILED)\n+\t\treturn REFTABLE_IO_ERROR;\n+\n+\tout->data = data;\n+\tout->size = len;\n+\n+\treturn 0;\n+}\n+\n+int reftable_munmap(struct reftable_mmap *mmap)\n+{\n+\tif (munmap(mmap->data, mmap->size) < 0)\n+\t\treturn REFTABLE_IO_ERROR;\n+\tmemset(mmap, 0, sizeof(*mmap));\n+\treturn 0;\n+}\ndiff --git a/reftable/system.h b/reftable/system.h\nindex 071bfa3d58..c0e2cbe0ff 100644\n--- a/reftable/system.h\n+++ b/reftable/system.h\n@@ -114,4 +114,22 @@ int flock_commit(struct reftable_flock *l);\n /* Report the time in milliseconds. */\n uint64_t reftable_time_ms(void);\n \n+struct reftable_mmap {\n+       void *data;\n+       size_t size;\n+       void *priv;\n+};\n+\n+/*\n+ * Map the file into memory. Returns 0 on success, a reftable error code on\n+ * error.\n+ */\n+int reftable_mmap(struct reftable_mmap *out, int fd, size_t len);\n+\n+/*\n+ * Unmap the file from memory. Returns 0 on success, a reftable error code on\n+ * error.\n+ */\n+int reftable_munmap(struct reftable_mmap *mmap);\n+\n #endif\n\n-- \n2.53.0.1323.g189a785ab5.dirty\n\n"},{"id":"540781","messageId":"xmqqika9qlye.fsf@gitster.g","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-2-bc110cee0ae0@pks.im","subject":"Re: [PATCH v2 2/5] reftable/stack: provide fsync(3p) via system header","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-02T18:03:05Z","receivedAt":"2026-04-02T18:03:08Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Users of the reftable library are expected to provide their own function\n> callback in cases they want to sync(3p) data to disk via the reftable\n> write options. But if no such function was provided we end up calling\n> fsync(3p) directly, which may not even be available on some systems.\n>\n> While dropping the explicit call to fsync(3p) would work, it would lead\n> to an unsafe default behaviour where a project may have forgotten to set\n> up the callback function, and that could lead to potential data loss. So\n> this is not a great solution.\n>\n> Instead, drop the callback function and make it mandatory for the\n> project to define fsync(3p). In the case of Git, we can then easily\n> inject our custom implementation via the \"reftable-system.h\" header so\n> that we continue to use `fsync_component()`.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  refs/reftable-backend.c    |  6 ------\n>  reftable/reftable-system.h |  3 +++\n>  reftable/reftable-writer.h |  6 ------\n>  reftable/stack.c           | 13 +++----------\n>  reftable/system.c          |  6 ++++++\n>  5 files changed, 12 insertions(+), 22 deletions(-)\n>\n> diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c\n> index b124404663..daea30a5b4 100644\n> --- a/refs/reftable-backend.c\n> +++ b/refs/reftable-backend.c\n> @@ -366,11 +366,6 @@ static int reftable_be_config(const char *var, const char *value,\n>  \treturn 0;\n>  }\n>  \n> -static int reftable_be_fsync(int fd)\n> -{\n> -\treturn fsync_component(FSYNC_COMPONENT_REFERENCE, fd);\n> -}\n> -\n>  static struct ref_store *reftable_be_init(struct repository *repo,\n>  \t\t\t\t\t  const char *payload,\n>  \t\t\t\t\t  const char *gitdir,\n> @@ -408,7 +403,6 @@ static struct ref_store *reftable_be_init(struct repository *repo,\n>  \trefs->write_options.disable_auto_compact =\n>  \t\t!git_env_bool(\"GIT_TEST_REFTABLE_AUTOCOMPACTION\", 1);\n>  \trefs->write_options.lock_timeout_ms = 100;\n> -\trefs->write_options.fsync = reftable_be_fsync;\n\n\nIt used to be that by swapping the write_options settings the\nproject can choose to perform its fsync in different ways depending\non what they are writing, but now we have a chance to specify a\nsingle fsync() in <reftable/system.c>?  \n\nThe project code does not set up write_options and the project code\nhas no say in the choice of the kind of fsync used for different\ndata files the reftable library uses, so it is not a problem.\n\nOK.\n\n"},{"id":"540783","messageId":"xmqqa4vlqkug.fsf@gitster.g","threadId":"65394","inReplyTo":"20260402-pks-reftable-portability-fixes-v2-4-bc110cee0ae0@pks.im","subject":"Re: [PATCH v2 4/5] reftable/system: add abstraction to retrieve time in milliseconds","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-02T18:27:03Z","receivedAt":"2026-04-02T18:27:06Z","isPatch":true,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> We directly call gettimeofday(3p), which may not be available on some\n> platforms. Provide the infrastructure to let projects easily use their\n> own implementations of this function.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  reftable/stack.c  | 27 ++++-----------------------\n>  reftable/system.c |  6 ++++++\n>  reftable/system.h |  3 +++\n>  3 files changed, 13 insertions(+), 23 deletions(-)\n> ...\n> +uint64_t reftable_time_ms(void)\n> +{\n> +\treturn getnanotime() / 1000000;\n> +}\n> diff --git a/reftable/system.h b/reftable/system.h\n> index a7eb6acd4a..071bfa3d58 100644\n> --- a/reftable/system.h\n> +++ b/reftable/system.h\n> @@ -111,4 +111,7 @@ int flock_release(struct reftable_flock *l);\n>   */\n>  int flock_commit(struct reftable_flock *l);\n>  \n> +/* Report the time in milliseconds. */\n> +uint64_t reftable_time_ms(void);\n\nThis must be give the current time in milliseconds, measured from\nsome fixed point in time.  It is up to the implementation to choose\nwhat absolute time as the epoch, since we only use this to compare\none timestamp returned by a call to this function with another.\n\nThe \"we do not care what epoch you choose, but you have to be\nconsistent\" requirement may want to be written down here, though.\n"}]}