From a808b3e738540011abce6fefd5f87d3031fcf266 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 23 Feb 2023 06:24:49 -0800 Subject: [PATCH] Serialize ZipOS handle IO across threads --- Makefile | 10 +++++----- libc/zipos/free.c | 2 ++ libc/zipos/lseek.c | 3 +++ libc/zipos/open.c | 1 + libc/zipos/read.c | 5 ++++- libc/zipos/zipos.internal.h | 2 ++ libc/zipos/zipos.mk | 1 + 7 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b804fa929..4f831034b 100644 --- a/Makefile +++ b/Makefile @@ -134,11 +134,11 @@ include libc/crt/crt.mk # │ You can issue system calls include third_party/nsync/nsync.mk # │ include third_party/dlmalloc/dlmalloc.mk #─┘ include libc/mem/mem.mk #─┐ -include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME -include third_party/gdtoa/gdtoa.mk # │ You can now use stdio -include libc/time/time.mk # │ You can finally call malloc() -include third_party/nsync/mem/mem.mk # │ -include libc/thread/thread.mk # │ +include third_party/gdtoa/gdtoa.mk # ├──DYNAMIC RUNTIME +include third_party/nsync/mem/mem.mk # │ You can now use stdio +include libc/thread/thread.mk # │ You can finally call malloc() +include libc/zipos/zipos.mk # │ +include libc/time/time.mk # │ include libc/stdio/stdio.mk # │ include third_party/libcxx/libcxx.mk # │ include net/net.mk # │ diff --git a/libc/zipos/free.c b/libc/zipos/free.c index 512a71eba..2b2c18b3e 100644 --- a/libc/zipos/free.c +++ b/libc/zipos/free.c @@ -21,6 +21,7 @@ #include "libc/intrin/asancodes.h" #include "libc/intrin/cmpxchg.h" #include "libc/str/str.h" +#include "libc/thread/thread.h" #include "libc/zipos/zipos.internal.h" void __zipos_free(struct Zipos *z, struct ZiposHandle *h) { @@ -28,6 +29,7 @@ void __zipos_free(struct Zipos *z, struct ZiposHandle *h) { __asan_poison((char *)h + sizeof(struct ZiposHandle), h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree); } + pthread_mutex_destroy(&h->lock); __zipos_lock(); do h->next = z->freelist; while (!_cmpxchg(&z->freelist, h->next, h)); diff --git a/libc/zipos/lseek.c b/libc/zipos/lseek.c index 352dec699..34fb4f35d 100644 --- a/libc/zipos/lseek.c +++ b/libc/zipos/lseek.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/thread.h" #include "libc/zip.h" #include "libc/zipos/zipos.internal.h" @@ -31,6 +32,7 @@ */ int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) { int64_t rc; + pthread_mutex_lock(&h->lock); switch (whence) { case SEEK_SET: rc = offset; @@ -50,5 +52,6 @@ int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) { } else { rc = einval(); } + pthread_mutex_unlock(&h->lock); return rc; } diff --git a/libc/zipos/open.c b/libc/zipos/open.c index 930e5d285..61b71d1ec 100644 --- a/libc/zipos/open.c +++ b/libc/zipos/open.c @@ -90,6 +90,7 @@ StartOver: if (h) { h->size = size; h->mapsize = mapsize; + pthread_mutex_init(&h->lock, 0); } return h; } diff --git a/libc/zipos/read.c b/libc/zipos/read.c index 3cfd5d025..472a8007f 100644 --- a/libc/zipos/read.c +++ b/libc/zipos/read.c @@ -17,9 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/intrin/safemacros.internal.h" #include "libc/calls/struct/iovec.h" +#include "libc/intrin/safemacros.internal.h" #include "libc/str/str.h" +#include "libc/thread/thread.h" #include "libc/zip.h" #include "libc/zipos/zipos.internal.h" @@ -39,11 +40,13 @@ static size_t GetIovSize(const struct iovec *iov, size_t iovlen) { ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov, size_t iovlen, ssize_t opt_offset) { size_t i, b, x, y; + pthread_mutex_lock(&h->lock); x = y = opt_offset != -1 ? opt_offset : h->pos; for (i = 0; i < iovlen && y < h->size; ++i, y += b) { b = min(iov[i].iov_len, h->size - y); if (b) memcpy(iov[i].iov_base, h->mem + y, b); } if (opt_offset == -1) h->pos = y; + pthread_mutex_unlock(&h->lock); return y - x; } diff --git a/libc/zipos/zipos.internal.h b/libc/zipos/zipos.internal.h index a77a911ab..661d098ec 100644 --- a/libc/zipos/zipos.internal.h +++ b/libc/zipos/zipos.internal.h @@ -1,6 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ #define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ #include "libc/intrin/nopl.internal.h" +#include "libc/thread/thread.h" #include "libc/thread/tls.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -15,6 +16,7 @@ struct ZiposUri { struct ZiposHandle { struct ZiposHandle *next; + pthread_mutex_t lock; size_t size; /* byte length of `mem` */ size_t mapsize; /* total size of this struct */ size_t pos; /* read/write byte offset state */ diff --git a/libc/zipos/zipos.mk b/libc/zipos/zipos.mk index 0632b4a0d..66ae43e7c 100644 --- a/libc/zipos/zipos.mk +++ b/libc/zipos/zipos.mk @@ -34,6 +34,7 @@ LIBC_ZIPOS_A_DIRECTDEPS = \ LIBC_FMT \ LIBC_RUNTIME \ LIBC_SYSV \ + LIBC_THREAD \ LIBC_STR \ LIBC_INTRIN \ LIBC_STUBS \