diff --git a/system/ulib/fdio/private-remoteio.h b/system/ulib/fdio/private-remoteio.h index fe6aafa74c229f3be512768aa02c7cb77100a842..202db4fca53b72ea1d7c74ddeac7cbb19cdc5eef 100644 --- a/system/ulib/fdio/private-remoteio.h +++ b/system/ulib/fdio/private-remoteio.h @@ -8,17 +8,7 @@ #include "private.h" -// Implements the |fdio_t| contract using |zxio_remote_t|. -// -// Has an ops table that translates fdio ops into zxio ops. Some of the fdio ops -// require using the underlying handles in the |zxio_remote_t|, which is why -// this object needs to use |zxio_remote_t| directly. -// -// Will be removed once the transition to the zxio backend is complete. -typedef struct fdio_zxio_remote { - fdio_t io; - zxio_remote_t remote; -} fdio_zxio_remote_t; +zxio_remote_t* fdio_get_zxio_remote(fdio_t* io); // open operation directly on remoteio handle zx_status_t zxrio_open_handle(zx_handle_t h, const char* path, uint32_t flags, diff --git a/system/ulib/fdio/service.c b/system/ulib/fdio/service.c index abbde55b3378b64b178c0924e68a8ac562c89ee5..866d9af26e4719e846fccc17b8dc12e7754f8d5a 100644 --- a/system/ulib/fdio/service.c +++ b/system/ulib/fdio/service.c @@ -101,8 +101,8 @@ zx_status_t fdio_get_service_handle(int fd, zx_handle_t* out) { svc->h = ZX_HANDLE_INVALID; r = ZX_OK; } else if (io->ops == &fdio_zxio_remote_ops) { - fdio_zxio_remote_t* rio = (fdio_zxio_remote_t*) io; - r = zxio_release(&rio->remote.io, out); + zxio_remote_t* file = fdio_get_zxio_remote(io); + r = zxio_release(&file->io, out); } else { r = ZX_ERR_NOT_SUPPORTED; io->ops->close(io); @@ -122,8 +122,8 @@ zx_handle_t fdio_unsafe_borrow_channel(fdio_t* io) { zxsvc_t* svc = (zxsvc_t*) io; return svc->h; } else if (io->ops == &fdio_zxio_remote_ops) { - fdio_zxio_remote_t* rio = (fdio_zxio_remote_t*) io; - return rio->remote.control; + zxio_remote_t* file = fdio_get_zxio_remote(io); + return file->control; } return ZX_HANDLE_INVALID; } diff --git a/system/ulib/fdio/zxio.c b/system/ulib/fdio/zxio.c index aa4caf56603f6d9bb2e6a32fa692c02397f99f1e..42612883a24cf8c7c0550828966095894bb9d670 100644 --- a/system/ulib/fdio/zxio.c +++ b/system/ulib/fdio/zxio.c @@ -21,19 +21,19 @@ // // Every |fdio_t| implementation starts with an embedded |fdio_t|, which the // callers use to find the fdio |ops| table. There are several |fdio_t| -// implementations that use zxio as a backed. All of them have an initial memory -// layout that matches this structure. Defining this structure lets us define +// implementations that use zxio as a backed. All of them have a memory layout +// that matches this structure. Defining this structure lets us define // most of the fdio ops that use the zxio backend in a generic way. // // Will be removed once the transition to the zxio backend is complete. typedef struct fdio_zxio { fdio_t io; - zxio_t zio; + zxio_storage_t storage; } fdio_zxio_t; static inline zxio_t* fdio_get_zxio(fdio_t* io) { fdio_zxio_t* wrapper = (fdio_zxio_t*)io; - return &wrapper->zio; + return &wrapper->storage.io; } static zx_status_t fdio_zxio_close(fdio_t* io) { @@ -201,18 +201,14 @@ static zx_status_t fdio_zxio_set_flags(fdio_t* io, uint32_t flags) { // Remote ---------------------------------------------------------------------- -static_assert(offsetof(fdio_zxio_t, zio) == offsetof(fdio_zxio_remote_t, remote.io), - "fdio_zxio_remote_t layout must match fdio_zxio_t"); - // POLL_MASK and POLL_SHIFT intend to convert the lower five POLL events into // ZX_USER_SIGNALs and vice-versa. Other events need to be manually converted to // a zx_signals_t, if they are desired. #define POLL_SHIFT 24 #define POLL_MASK 0x1F -static inline zxio_remote_t* fdio_get_zxio_remote(fdio_t* io) { - fdio_zxio_remote_t* wrapper = (fdio_zxio_remote_t*)io; - return &wrapper->remote; +zxio_remote_t* fdio_get_zxio_remote(fdio_t* io) { + return (zxio_remote_t*)fdio_get_zxio(io); } static zx_status_t fdio_zxio_remote_open(fdio_t* io, const char* path, @@ -428,7 +424,7 @@ fdio_ops_t fdio_zxio_remote_ops = { __EXPORT fdio_t* fdio_remote_create(zx_handle_t control, zx_handle_t event) { - fdio_zxio_remote_t* fv = fdio_alloc(sizeof(fdio_zxio_remote_t)); + fdio_zxio_t* fv = fdio_alloc(sizeof(fdio_zxio_t)); if (fv == NULL) { zx_handle_close(control); zx_handle_close(event); @@ -437,7 +433,7 @@ fdio_t* fdio_remote_create(zx_handle_t control, zx_handle_t event) { fv->io.ops = &fdio_zxio_remote_ops; fv->io.magic = FDIO_MAGIC; atomic_init(&fv->io.refcount, 1); - zx_status_t status = zxio_remote_init(&fv->remote, control, event); + zx_status_t status = zxio_remote_init(&fv->storage, control, event); if (status != ZX_OK) { return NULL; } @@ -446,21 +442,8 @@ fdio_t* fdio_remote_create(zx_handle_t control, zx_handle_t event) { // Vmofile --------------------------------------------------------------------- -// Implements the |fdio_t| contract using |zxio_vmofile_t|. -// -// Has an ops table that translates fdio ops into zxio ops. Some of the fdio ops -// require using the underlying handles in the |zxio_vmofile_t|, which is why -// this object needs to use |zxio_vmofile_t| directly. -// -// Will be removed once the transition to the zxio backend is complete. -typedef struct fdio_zxio_vmofile { - fdio_t io; - zxio_vmofile_t file; -} fdio_zxio_vmofile_t; - static inline zxio_vmofile_t* fdio_get_zxio_vmofile(fdio_t* io) { - fdio_zxio_vmofile_t* wrapper = (fdio_zxio_vmofile_t*)io; - return &wrapper->file; + return (zxio_vmofile_t*)fdio_get_zxio(io); } static zx_status_t fdio_zxio_vmofile_get_vmo(fdio_t* io, int flags, @@ -535,7 +518,7 @@ fdio_ops_t fdio_zxio_vmofile_ops = { fdio_t* fdio_zxio_vmofile_create(zx_handle_t control, zx_handle_t vmo, zx_off_t offset, zx_off_t length, zx_off_t seek) { - fdio_zxio_vmofile_t* fv = fdio_alloc(sizeof(fdio_zxio_vmofile_t)); + fdio_zxio_t* fv = fdio_alloc(sizeof(fdio_zxio_t)); if (fv == NULL) { zx_handle_close(control); zx_handle_close(vmo); @@ -544,7 +527,7 @@ fdio_t* fdio_zxio_vmofile_create(zx_handle_t control, zx_handle_t vmo, fv->io.ops = &fdio_zxio_vmofile_ops; fv->io.magic = FDIO_MAGIC; atomic_init(&fv->io.refcount, 1); - zx_status_t status = zxio_vmofile_init(&fv->file, control, vmo, offset, + zx_status_t status = zxio_vmofile_init(&fv->storage, control, vmo, offset, length, seek); if (status != ZX_OK) { return NULL; @@ -554,21 +537,6 @@ fdio_t* fdio_zxio_vmofile_create(zx_handle_t control, zx_handle_t vmo, // Pipe ------------------------------------------------------------------------ -// Implements the |fdio_t| contract using |zxio_pipe_t|. -// -// Has an ops table that translates fdio ops into zxio ops. Some of the fdio ops -// require using the underlying handles in the |zxio_pipe_t|, which is why -// this object needs to use |zxio_pipe_t| directly. -// -// Will be removed once the transition to the zxio backend is complete. -typedef struct fdio_zxio_pipe { - fdio_t io; - zxio_pipe_t pipe; -} fdio_zxio_pipe_t; - -static_assert(offsetof(fdio_zxio_t, zio) == offsetof(fdio_zxio_pipe_t, pipe.io), - "fdio_zxio_pipe_t layout must match fdio_zxio_t"); - static zx_status_t read_blocking(zxio_t* io, void* buffer, size_t capacity, size_t* out_actual) { for (;;) { @@ -624,8 +592,7 @@ static ssize_t write_internal(zxio_t* io, bool blocking, const void* data, size_ } static inline zxio_pipe_t* fdio_get_zxio_pipe(fdio_t* io) { - fdio_zxio_pipe_t* wrapper = (fdio_zxio_pipe_t*)io; - return &wrapper->pipe; + return (zxio_pipe_t*)fdio_get_zxio(io); } static zx_status_t fdio_zxio_pipe_clone(fdio_t* io, zx_handle_t* handles, uint32_t* types) { @@ -807,7 +774,7 @@ static fdio_ops_t fdio_zxio_pipe_ops = { }; fdio_t* fdio_pipe_create(zx_handle_t socket) { - fdio_zxio_pipe_t* fv = fdio_alloc(sizeof(fdio_zxio_pipe_t)); + fdio_zxio_t* fv = fdio_alloc(sizeof(fdio_zxio_t)); if (fv == NULL) { zx_handle_close(socket); return NULL; @@ -815,7 +782,7 @@ fdio_t* fdio_pipe_create(zx_handle_t socket) { fv->io.ops = &fdio_zxio_pipe_ops; fv->io.magic = FDIO_MAGIC; atomic_init(&fv->io.refcount, 1); - zx_status_t status = zxio_pipe_init(&fv->pipe, socket); + zx_status_t status = zxio_pipe_init(&fv->storage, socket); if (status != ZX_OK) { return NULL; } diff --git a/system/ulib/zxio/include/lib/zxio/inception.h b/system/ulib/zxio/include/lib/zxio/inception.h index eac4c188261a391544e9918fe90790af60ca2af2..6c461621517f13dcbf14744e6588959f884bedf5 100644 --- a/system/ulib/zxio/include/lib/zxio/inception.h +++ b/system/ulib/zxio/include/lib/zxio/inception.h @@ -35,7 +35,10 @@ typedef struct zxio_remote { zx_handle_t event; } zxio_remote_t; -zx_status_t zxio_remote_init(zxio_remote_t* remote, zx_handle_t control, +static_assert(sizeof(zxio_remote_t) <= sizeof(zxio_storage_t), + "zxio_remote_t must fit inside zxio_storage_t."); + +zx_status_t zxio_remote_init(zxio_storage_t* remote, zx_handle_t control, zx_handle_t event); // vmofile --------------------------------------------------------------------- @@ -51,7 +54,10 @@ typedef struct zxio_vmofile { mtx_t lock; } zxio_vmofile_t; -zx_status_t zxio_vmofile_init(zxio_vmofile_t* file, zx_handle_t control, +static_assert(sizeof(zxio_vmofile_t) <= sizeof(zxio_storage_t), + "zxio_vmofile_t must fit inside zxio_storage_t."); + +zx_status_t zxio_vmofile_init(zxio_storage_t* file, zx_handle_t control, zx_handle_t vmo, zx_off_t offset, zx_off_t length, zx_off_t seek); @@ -68,7 +74,10 @@ typedef struct zxio_pipe { zx_handle_t socket; } zxio_pipe_t; -zx_status_t zxio_pipe_init(zxio_pipe_t* pipe, zx_handle_t socket); +static_assert(sizeof(zxio_pipe_t) <= sizeof(zxio_storage_t), + "zxio_vmofile_t must fit inside zxio_storage_t."); + +zx_status_t zxio_pipe_init(zxio_storage_t* pipe, zx_handle_t socket); __END_CDECLS diff --git a/system/ulib/zxio/include/lib/zxio/ops.h b/system/ulib/zxio/include/lib/zxio/ops.h index 6e42ce9e10bdb1606f884cf82c0736fb15b955d4..1dab9559326e5a67caff3e5dc05767916b57aec2 100644 --- a/system/ulib/zxio/include/lib/zxio/ops.h +++ b/system/ulib/zxio/include/lib/zxio/ops.h @@ -18,6 +18,17 @@ typedef struct zxio { uint64_t reserved[4]; } zxio_t; +// Storage for the |zxio_ops_t| implementation. +typedef struct zxio_private { + uint64_t reserved[6]; +} zxio_private_t; + +// The storage backing a |zxio_t|. +typedef struct zxio_storage { + zxio_t io; + zxio_private_t reserved; +} zxio_storage_t; + // A table of operations for a zxio_t. // // Most of the functions that operate on a zxio_t call through this operations diff --git a/system/ulib/zxio/pipe.cpp b/system/ulib/zxio/pipe.cpp index 82846409c02416b236781739c5e4c256055ca665..5513a9534a258db1dda21070addde61cc4aa78a9 100644 --- a/system/ulib/zxio/pipe.cpp +++ b/system/ulib/zxio/pipe.cpp @@ -113,7 +113,8 @@ static const zxio_ops_t zxio_pipe_ops = { .rewind = zxio_null_rewind, }; -zx_status_t zxio_pipe_init(zxio_pipe_t* pipe, zx_handle_t socket) { +zx_status_t zxio_pipe_init(zxio_storage_t* storage, zx_handle_t socket) { + zxio_pipe_t* pipe = reinterpret_cast<zxio_pipe_t*>(storage); zxio_init(&pipe->io, &zxio_pipe_ops); pipe->socket = socket; return ZX_OK; diff --git a/system/ulib/zxio/remote.cpp b/system/ulib/zxio/remote.cpp index dfe0f3a16db3233c67c90f7379fc12d2b0faa37c..adffe8cc64c1ace117f5a90a201314e0d0aa5d67 100644 --- a/system/ulib/zxio/remote.cpp +++ b/system/ulib/zxio/remote.cpp @@ -379,10 +379,11 @@ static const zxio_ops_t zxio_remote_ops = { .rewind = zxio_remote_rewind, }; -zx_status_t zxio_remote_init(zxio_remote_t* rio, zx_handle_t control, +zx_status_t zxio_remote_init(zxio_storage_t* storage, zx_handle_t control, zx_handle_t event) { - zxio_init(&rio->io, &zxio_remote_ops); - rio->control = control; - rio->event = event; + zxio_remote_t* remote = reinterpret_cast<zxio_remote_t*>(storage); + zxio_init(&remote->io, &zxio_remote_ops); + remote->control = control; + remote->event = event; return ZX_OK; } diff --git a/system/ulib/zxio/vmofile.cpp b/system/ulib/zxio/vmofile.cpp index a7906c9faa69d41381a608a69b1a6db1a2781d8a..e4ef5023ca298773a256d271d9fa1f7dbff4349b 100644 --- a/system/ulib/zxio/vmofile.cpp +++ b/system/ulib/zxio/vmofile.cpp @@ -176,9 +176,10 @@ static const zxio_ops_t zxio_vmofile_ops = { .rewind = zxio_null_rewind, }; -zx_status_t zxio_vmofile_init(zxio_vmofile_t* file, zx_handle_t control, +zx_status_t zxio_vmofile_init(zxio_storage_t* storage, zx_handle_t control, zx_handle_t vmo, zx_off_t offset, zx_off_t length, zx_off_t seek) { + zxio_vmofile_t* file = reinterpret_cast<zxio_vmofile_t*>(storage); zxio_init(&file->io, &zxio_vmofile_ops); if (seek > length) seek = length; diff --git a/system/utest/zxio/vmofile-test.cpp b/system/utest/zxio/vmofile-test.cpp index c81d2656c109d92784f10b513c52e30b2db20ea0..6b8f0648639fac2140df085cc43dfd22935ff761 100644 --- a/system/utest/zxio/vmofile-test.cpp +++ b/system/utest/zxio/vmofile-test.cpp @@ -19,9 +19,9 @@ bool vmofile_basic_test(void) { ASSERT_EQ(ZX_OK, backing.write(ALPHABET, 0, len)); ASSERT_EQ(ZX_OK, backing.write(ALPHABET, len, len + len)); - zxio_vmofile_t file; - zxio_vmofile_init(&file, ZX_HANDLE_INVALID, backing.release(), 4, len, 3); - zxio_t* io = &file.io; + zxio_storage_t storage; + zxio_vmofile_init(&storage, ZX_HANDLE_INVALID, backing.release(), 4, len, 3); + zxio_t* io = &storage.io; zxio_signals_t observed = ZXIO_SIGNAL_NONE; ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, zxio_wait_one(io, ZXIO_READABLE,