mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-06-01 06:27:11 +00:00
Fix __wasi_subscription_t inconsistent with wasi-libc issue (#964)
Fix __wasi_subscription_t structure definition inconsistent with wasi-libc definition issue, reported by #961, tested with sleep, poll API and other wasi cases on x86-64, x86-32 and arm32 targets.
This commit is contained in:
parent
e0511fe822
commit
552f85075d
|
@ -441,47 +441,100 @@ _Static_assert(sizeof(void *) != 4 ||
|
||||||
_Static_assert(sizeof(void *) != 8 ||
|
_Static_assert(sizeof(void *) != 8 ||
|
||||||
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||||
|
|
||||||
typedef struct __wasi_subscription_t {
|
/**
|
||||||
__wasi_userdata_t userdata;
|
* The contents of a `subscription` when type is `eventtype::clock`.
|
||||||
|
*/
|
||||||
|
typedef struct __wasi_subscription_clock_t {
|
||||||
|
/**
|
||||||
|
* The clock against which to compare the timestamp.
|
||||||
|
*/
|
||||||
|
__wasi_clockid_t clock_id;
|
||||||
|
|
||||||
|
uint8_t __paddings1[4];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute or relative timestamp.
|
||||||
|
*/
|
||||||
|
__wasi_timestamp_t timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of time that the implementation may wait additionally
|
||||||
|
* to coalesce with other events.
|
||||||
|
*/
|
||||||
|
__wasi_timestamp_t precision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags specifying whether the timeout is absolute or relative
|
||||||
|
*/
|
||||||
|
__wasi_subclockflags_t flags;
|
||||||
|
|
||||||
|
uint8_t __paddings2[4];
|
||||||
|
|
||||||
|
} __wasi_subscription_clock_t __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
_Static_assert(sizeof(__wasi_subscription_clock_t) == 32, "witx calculated size");
|
||||||
|
_Static_assert(_Alignof(__wasi_subscription_clock_t) == 8, "witx calculated align");
|
||||||
|
_Static_assert(offsetof(__wasi_subscription_clock_t, clock_id) == 0, "witx calculated offset");
|
||||||
|
_Static_assert(offsetof(__wasi_subscription_clock_t, timeout) == 8, "witx calculated offset");
|
||||||
|
_Static_assert(offsetof(__wasi_subscription_clock_t, precision) == 16, "witx calculated offset");
|
||||||
|
_Static_assert(offsetof(__wasi_subscription_clock_t, flags) == 24, "witx calculated offset");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of a `subscription` when type is type is
|
||||||
|
* `eventtype::fd_read` or `eventtype::fd_write`.
|
||||||
|
*/
|
||||||
|
typedef struct __wasi_subscription_fd_readwrite_t {
|
||||||
|
/**
|
||||||
|
* The file descriptor on which to wait for it to become ready for reading or writing.
|
||||||
|
*/
|
||||||
|
__wasi_fd_t fd;
|
||||||
|
|
||||||
|
} __wasi_subscription_fd_readwrite_t;
|
||||||
|
|
||||||
|
_Static_assert(sizeof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated size");
|
||||||
|
_Static_assert(_Alignof(__wasi_subscription_fd_readwrite_t) == 4, "witx calculated align");
|
||||||
|
_Static_assert(offsetof(__wasi_subscription_fd_readwrite_t, fd) == 0, "witx calculated offset");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The contents of a `subscription`.
|
||||||
|
*/
|
||||||
|
typedef union __wasi_subscription_u_u_t {
|
||||||
|
__wasi_subscription_clock_t clock;
|
||||||
|
__wasi_subscription_fd_readwrite_t fd_readwrite;
|
||||||
|
} __wasi_subscription_u_u_t ;
|
||||||
|
|
||||||
|
typedef struct __wasi_subscription_u_t {
|
||||||
__wasi_eventtype_t type;
|
__wasi_eventtype_t type;
|
||||||
uint8_t __paddings[7];
|
__wasi_subscription_u_u_t u;
|
||||||
union __wasi_subscription_u {
|
} __wasi_subscription_u_t __attribute__((aligned(8)));
|
||||||
struct __wasi_subscription_u_clock_t {
|
|
||||||
__wasi_userdata_t identifier;
|
_Static_assert(sizeof(__wasi_subscription_u_t) == 40, "witx calculated size");
|
||||||
__wasi_clockid_t clock_id;
|
_Static_assert(_Alignof(__wasi_subscription_u_t) == 8, "witx calculated align");
|
||||||
uint8_t __paddings1[4];
|
_Static_assert(offsetof(__wasi_subscription_u_t, u) == 8, "witx calculated union offset");
|
||||||
__wasi_timestamp_t timeout;
|
_Static_assert(sizeof(__wasi_subscription_u_u_t) == 32, "witx calculated union size");
|
||||||
__wasi_timestamp_t precision;
|
_Static_assert(_Alignof(__wasi_subscription_u_u_t) == 8, "witx calculated union align");
|
||||||
__wasi_subclockflags_t flags;
|
|
||||||
uint8_t __paddings2[6];
|
/**
|
||||||
} clock;
|
* Subscription to an event.
|
||||||
struct __wasi_subscription_u_fd_readwrite_t {
|
*/
|
||||||
__wasi_fd_t fd;
|
typedef struct __wasi_subscription_t {
|
||||||
} fd_readwrite;
|
/**
|
||||||
} u;
|
* User-provided value that is attached to the subscription in the
|
||||||
} __wasi_subscription_t __attribute__((aligned(8)));
|
* implementation and returned through `event::userdata`.
|
||||||
_Static_assert(
|
*/
|
||||||
offsetof(__wasi_subscription_t, userdata) == 0, "non-wasi data layout");
|
__wasi_userdata_t userdata;
|
||||||
_Static_assert(
|
|
||||||
offsetof(__wasi_subscription_t, type) == 8, "non-wasi data layout");
|
/**
|
||||||
_Static_assert(
|
* The type of the event to which to subscribe, and its contents
|
||||||
offsetof(__wasi_subscription_t, u.clock.identifier) == 16,
|
*/
|
||||||
"non-wasi data layout");
|
__wasi_subscription_u_t u;
|
||||||
_Static_assert(
|
|
||||||
offsetof(__wasi_subscription_t, u.clock.clock_id) == 24,
|
} __wasi_subscription_t;
|
||||||
"non-wasi data layout");
|
|
||||||
_Static_assert(
|
_Static_assert(sizeof(__wasi_subscription_t) == 48, "witx calculated size");
|
||||||
offsetof(__wasi_subscription_t, u.clock.timeout) == 32, "non-wasi data layout");
|
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
|
||||||
_Static_assert(
|
_Static_assert(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
|
||||||
offsetof(__wasi_subscription_t, u.clock.precision) == 40,
|
_Static_assert(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
|
||||||
"non-wasi data layout");
|
|
||||||
_Static_assert(
|
|
||||||
offsetof(__wasi_subscription_t, u.clock.flags) == 48, "non-wasi data layout");
|
|
||||||
_Static_assert(
|
|
||||||
offsetof(__wasi_subscription_t, u.fd_readwrite.fd) == 16,
|
|
||||||
"non-wasi data layout");
|
|
||||||
_Static_assert(sizeof(__wasi_subscription_t) == 56, "non-wasi data layout");
|
|
||||||
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "non-wasi data layout");
|
|
||||||
|
|
||||||
#if defined(WASMTIME_SSP_WASI_API)
|
#if defined(WASMTIME_SSP_WASI_API)
|
||||||
#define WASMTIME_SSP_SYSCALL_NAME(name) \
|
#define WASMTIME_SSP_SYSCALL_NAME(name) \
|
||||||
|
|
|
@ -2418,19 +2418,19 @@ wasmtime_ssp_poll_oneoff(
|
||||||
size_t *nevents) NO_LOCK_ANALYSIS
|
size_t *nevents) NO_LOCK_ANALYSIS
|
||||||
{
|
{
|
||||||
// Sleeping.
|
// Sleeping.
|
||||||
if (nsubscriptions == 1 && in[0].type == __WASI_EVENTTYPE_CLOCK) {
|
if (nsubscriptions == 1 && in[0].u.type == __WASI_EVENTTYPE_CLOCK) {
|
||||||
out[0] = (__wasi_event_t){
|
out[0] = (__wasi_event_t){
|
||||||
.userdata = in[0].userdata,
|
.userdata = in[0].userdata,
|
||||||
.type = in[0].type,
|
.type = in[0].u.type,
|
||||||
};
|
};
|
||||||
#if CONFIG_HAS_CLOCK_NANOSLEEP
|
#if CONFIG_HAS_CLOCK_NANOSLEEP
|
||||||
clockid_t clock_id;
|
clockid_t clock_id;
|
||||||
if (convert_clockid(in[0].u.clock.clock_id, &clock_id)) {
|
if (convert_clockid(in[0].u.u.clock.clock_id, &clock_id)) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
convert_timestamp(in[0].u.clock.timeout, &ts);
|
convert_timestamp(in[0].u.u.clock.timeout, &ts);
|
||||||
int ret = clock_nanosleep(
|
int ret = clock_nanosleep(
|
||||||
clock_id,
|
clock_id,
|
||||||
(in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) != 0
|
(in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME) != 0
|
||||||
? TIMER_ABSTIME
|
? TIMER_ABSTIME
|
||||||
: 0,
|
: 0,
|
||||||
&ts, NULL);
|
&ts, NULL);
|
||||||
|
@ -2441,9 +2441,9 @@ wasmtime_ssp_poll_oneoff(
|
||||||
out[0].error = __WASI_ENOTSUP;
|
out[0].error = __WASI_ENOTSUP;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
switch (in[0].u.clock.clock_id) {
|
switch (in[0].u.u.clock.clock_id) {
|
||||||
case __WASI_CLOCK_MONOTONIC:
|
case __WASI_CLOCK_MONOTONIC:
|
||||||
if ((in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
if ((in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
// TODO(ed): Implement.
|
// TODO(ed): Implement.
|
||||||
fputs("Unimplemented absolute sleep on monotonic clock\n",
|
fputs("Unimplemented absolute sleep on monotonic clock\n",
|
||||||
|
@ -2454,12 +2454,12 @@ wasmtime_ssp_poll_oneoff(
|
||||||
// Perform relative sleeps on the monotonic clock also using
|
// Perform relative sleeps on the monotonic clock also using
|
||||||
// nanosleep(). This is incorrect, but good enough for now.
|
// nanosleep(). This is incorrect, but good enough for now.
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
convert_timestamp(in[0].u.clock.timeout, &ts);
|
convert_timestamp(in[0].u.u.clock.timeout, &ts);
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case __WASI_CLOCK_REALTIME:
|
case __WASI_CLOCK_REALTIME:
|
||||||
if ((in[0].u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
if ((in[0].u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
// Sleeping to an absolute point in time can only be done
|
// Sleeping to an absolute point in time can only be done
|
||||||
// by waiting on a condition variable.
|
// by waiting on a condition variable.
|
||||||
|
@ -2473,7 +2473,8 @@ wasmtime_ssp_poll_oneoff(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mutex_lock(&mutex);
|
mutex_lock(&mutex);
|
||||||
cond_timedwait(&cond, &mutex, in[0].u.clock.timeout, true);
|
cond_timedwait(&cond, &mutex, in[0].u.u.clock.timeout,
|
||||||
|
true);
|
||||||
mutex_unlock(&mutex);
|
mutex_unlock(&mutex);
|
||||||
mutex_destroy(&mutex);
|
mutex_destroy(&mutex);
|
||||||
cond_destroy(&cond);
|
cond_destroy(&cond);
|
||||||
|
@ -2481,7 +2482,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
else {
|
else {
|
||||||
// Relative sleeps can be done using nanosleep().
|
// Relative sleeps can be done using nanosleep().
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
convert_timestamp(in[0].u.clock.timeout, &ts);
|
convert_timestamp(in[0].u.u.clock.timeout, &ts);
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2519,18 +2520,18 @@ wasmtime_ssp_poll_oneoff(
|
||||||
const __wasi_subscription_t *clock_subscription = NULL;
|
const __wasi_subscription_t *clock_subscription = NULL;
|
||||||
for (size_t i = 0; i < nsubscriptions; ++i) {
|
for (size_t i = 0; i < nsubscriptions; ++i) {
|
||||||
const __wasi_subscription_t *s = &in[i];
|
const __wasi_subscription_t *s = &in[i];
|
||||||
switch (s->type) {
|
switch (s->u.type) {
|
||||||
case __WASI_EVENTTYPE_FD_READ:
|
case __WASI_EVENTTYPE_FD_READ:
|
||||||
case __WASI_EVENTTYPE_FD_WRITE:
|
case __WASI_EVENTTYPE_FD_WRITE:
|
||||||
{
|
{
|
||||||
__wasi_errno_t error =
|
__wasi_errno_t error =
|
||||||
fd_object_get_locked(&fos[i], ft, s->u.fd_readwrite.fd,
|
fd_object_get_locked(&fos[i], ft, s->u.u.fd_readwrite.fd,
|
||||||
__WASI_RIGHT_POLL_FD_READWRITE, 0);
|
__WASI_RIGHT_POLL_FD_READWRITE, 0);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
// Proper file descriptor on which we can poll().
|
// Proper file descriptor on which we can poll().
|
||||||
pfds[i] = (struct pollfd){
|
pfds[i] = (struct pollfd){
|
||||||
.fd = fd_number(fos[i]),
|
.fd = fd_number(fos[i]),
|
||||||
.events = s->type == __WASI_EVENTTYPE_FD_READ
|
.events = s->u.type == __WASI_EVENTTYPE_FD_READ
|
||||||
? POLLRDNORM
|
? POLLRDNORM
|
||||||
: POLLWRNORM,
|
: POLLWRNORM,
|
||||||
};
|
};
|
||||||
|
@ -2542,14 +2543,14 @@ wasmtime_ssp_poll_oneoff(
|
||||||
out[(*nevents)++] = (__wasi_event_t){
|
out[(*nevents)++] = (__wasi_event_t){
|
||||||
.userdata = s->userdata,
|
.userdata = s->userdata,
|
||||||
.error = error,
|
.error = error,
|
||||||
.type = s->type,
|
.type = s->u.type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case __WASI_EVENTTYPE_CLOCK:
|
case __WASI_EVENTTYPE_CLOCK:
|
||||||
if (clock_subscription == NULL
|
if (clock_subscription == NULL
|
||||||
&& (s->u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
&& (s->u.u.clock.flags & __WASI_SUBSCRIPTION_CLOCK_ABSTIME)
|
||||||
== 0) {
|
== 0) {
|
||||||
// Relative timeout.
|
// Relative timeout.
|
||||||
fos[i] = NULL;
|
fos[i] = NULL;
|
||||||
|
@ -2565,7 +2566,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
out[(*nevents)++] = (__wasi_event_t){
|
out[(*nevents)++] = (__wasi_event_t){
|
||||||
.userdata = s->userdata,
|
.userdata = s->userdata,
|
||||||
.error = __WASI_ENOSYS,
|
.error = __WASI_ENOSYS,
|
||||||
.type = s->type,
|
.type = s->u.type,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2579,7 +2580,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
}
|
}
|
||||||
else if (clock_subscription != NULL) {
|
else if (clock_subscription != NULL) {
|
||||||
__wasi_timestamp_t ts = clock_subscription->u.clock.timeout / 1000000;
|
__wasi_timestamp_t ts = clock_subscription->u.u.clock.timeout / 1000000;
|
||||||
timeout = ts > INT_MAX ? -1 : (int)ts;
|
timeout = ts > INT_MAX ? -1 : (int)ts;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2603,7 +2604,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
for (size_t i = 0; i < nsubscriptions; ++i) {
|
for (size_t i = 0; i < nsubscriptions; ++i) {
|
||||||
if (pfds[i].fd >= 0) {
|
if (pfds[i].fd >= 0) {
|
||||||
__wasi_filesize_t nbytes = 0;
|
__wasi_filesize_t nbytes = 0;
|
||||||
if (in[i].type == __WASI_EVENTTYPE_FD_READ) {
|
if (in[i].u.type == __WASI_EVENTTYPE_FD_READ) {
|
||||||
int l;
|
int l;
|
||||||
if (ioctl(fd_number(fos[i]), FIONREAD, &l) == 0)
|
if (ioctl(fd_number(fos[i]), FIONREAD, &l) == 0)
|
||||||
nbytes = (__wasi_filesize_t)l;
|
nbytes = (__wasi_filesize_t)l;
|
||||||
|
@ -2622,7 +2623,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
#else
|
#else
|
||||||
.error = __WASI_EBADF,
|
.error = __WASI_EBADF,
|
||||||
#endif
|
#endif
|
||||||
.type = in[i].type,
|
.type = in[i].u.type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if ((pfds[i].revents & POLLERR) != 0) {
|
else if ((pfds[i].revents & POLLERR) != 0) {
|
||||||
|
@ -2630,14 +2631,14 @@ wasmtime_ssp_poll_oneoff(
|
||||||
out[(*nevents)++] = (__wasi_event_t){
|
out[(*nevents)++] = (__wasi_event_t){
|
||||||
.userdata = in[i].userdata,
|
.userdata = in[i].userdata,
|
||||||
.error = __WASI_EIO,
|
.error = __WASI_EIO,
|
||||||
.type = in[i].type,
|
.type = in[i].u.type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if ((pfds[i].revents & POLLHUP) != 0) {
|
else if ((pfds[i].revents & POLLHUP) != 0) {
|
||||||
// End-of-file.
|
// End-of-file.
|
||||||
out[(*nevents)++] = (__wasi_event_t){
|
out[(*nevents)++] = (__wasi_event_t){
|
||||||
.userdata = in[i].userdata,
|
.userdata = in[i].userdata,
|
||||||
.type = in[i].type,
|
.type = in[i].u.type,
|
||||||
.u.fd_readwrite.nbytes = nbytes,
|
.u.fd_readwrite.nbytes = nbytes,
|
||||||
.u.fd_readwrite.flags =
|
.u.fd_readwrite.flags =
|
||||||
__WASI_EVENT_FD_READWRITE_HANGUP,
|
__WASI_EVENT_FD_READWRITE_HANGUP,
|
||||||
|
@ -2647,7 +2648,7 @@ wasmtime_ssp_poll_oneoff(
|
||||||
// Read or write possible.
|
// Read or write possible.
|
||||||
out[(*nevents)++] = (__wasi_event_t){
|
out[(*nevents)++] = (__wasi_event_t){
|
||||||
.userdata = in[i].userdata,
|
.userdata = in[i].userdata,
|
||||||
.type = in[i].type,
|
.type = in[i].u.type,
|
||||||
.u.fd_readwrite.nbytes = nbytes,
|
.u.fd_readwrite.nbytes = nbytes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user