Serialize ZipOS handle IO across threads

This commit is contained in:
Justine Tunney 2023-02-23 06:24:49 -08:00
parent 0f1ead8943
commit a808b3e738
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
7 changed files with 18 additions and 6 deletions

View file

@ -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 # │

View file

@ -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));

View file

@ -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;
}

View file

@ -90,6 +90,7 @@ StartOver:
if (h) {
h->size = size;
h->mapsize = mapsize;
pthread_mutex_init(&h->lock, 0);
}
return h;
}

View file

@ -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;
}

View file

@ -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 */

View file

@ -34,6 +34,7 @@ LIBC_ZIPOS_A_DIRECTDEPS = \
LIBC_FMT \
LIBC_RUNTIME \
LIBC_SYSV \
LIBC_THREAD \
LIBC_STR \
LIBC_INTRIN \
LIBC_STUBS \