Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Commit

Permalink
[Pal] Make DkStreamsWaitEvents always poll underlying fds
Browse files Browse the repository at this point in the history
If `DkStreamsWaitEvents` spotted a previous error, it skipped polling
the fd, which could result in missing return events or hangs.

Signed-off-by: Borys Popławski <[email protected]>
  • Loading branch information
boryspoplawski committed Apr 21, 2021
1 parent 56123cf commit 5a4b8a9
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 57 deletions.
4 changes: 0 additions & 4 deletions Pal/src/db_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ int DkSynchronizationObjectWait(PAL_HANDLE handle, PAL_NUM timeout_us) {
* error code otherwise. */
int DkStreamsWaitEvents(PAL_NUM count, PAL_HANDLE* handle_array, PAL_FLG* events,
PAL_FLG* ret_events, PAL_NUM timeout_us) {
if (!count || !handle_array || !events || !ret_events) {
return -PAL_ERROR_INVAL;
}

for (PAL_NUM i = 0; i < count; i++) {
if (UNKNOWN_HANDLE(handle_array[i])) {
return -PAL_ERROR_INVAL;
Expand Down
32 changes: 5 additions & 27 deletions Pal/src/host/Linux-SGX/db_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events

/* collect all FDs of all PAL handles that may report read/write events */
size_t nfds = 0;
size_t ret_events_updated = 0;
for (size_t i = 0; i < count; i++) {
ret_events[i] = 0;

Expand All @@ -70,15 +69,6 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
/* hdl might be a mutex/event/non-pollable object, simply ignore it */
if (hdl->generic.fds[j] == PAL_IDX_POISON)
continue;
if (flags & ERROR(j)) {
/* PAL handle is requested for read/write but already marked with error:
* skip it but update its ret_events */
if (events[i] & (PAL_WAIT_READ | PAL_WAIT_WRITE)) {
ret_events[i] |= PAL_WAIT_ERROR;
ret_events_updated++;
}
continue;
}

int fdevents = 0;
fdevents |= ((flags & RFD(j)) && (events[i] & PAL_WAIT_READ)) ? POLLIN : 0;
Expand All @@ -95,29 +85,15 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
}

if (!nfds) {
if (ret_events_updated > 0) {
/* we skip actual ppoll, but there was at least one PAL handle with updated ret_events
*/
ret = 0;
} else {
/* did not find any waitable FDs (LibOS supplied closed/errored FDs or empty events) */
ret = -PAL_ERROR_TRYAGAIN;
}
/* did not find any waitable FDs (LibOS supplied closed FDs or empty events) */
ret = -PAL_ERROR_INVAL;
goto out;
}

ret = ocall_poll(fds, nfds, timeout_us);

if (ret < 0) {
switch (ret) {
case -EINTR:
case -ERESTART:
ret = -PAL_ERROR_INTERRUPTED;
break;
default:
ret = unix_to_pal_error(ret);
break;
}
ret = unix_to_pal_error(ret);
goto out;
}

Expand Down Expand Up @@ -147,6 +123,8 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
for (size_t k = 0; k < MAX_FDS; k++) {
if (hdl->generic.fds[k] != (PAL_IDX)fds[i].fd)
continue;
if (HANDLE_HDR(hdl)->flags & ERROR(k))
ret_events[j] |= PAL_WAIT_ERROR;
if (fds[i].revents & (POLLHUP | POLLERR | POLLNVAL))
HANDLE_HDR(hdl)->flags |= ERROR(k);
}
Expand Down
31 changes: 5 additions & 26 deletions Pal/src/host/Linux/db_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events

/* collect all FDs of all PAL handles that may report read/write events */
size_t nfds = 0;
size_t ret_events_updated = 0;
for (size_t i = 0; i < count; i++) {
ret_events[i] = 0;

Expand All @@ -68,15 +67,6 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
/* hdl might be a mutex/event/non-pollable object, simply ignore it */
if (hdl->generic.fds[j] == PAL_IDX_POISON)
continue;
if (flags & ERROR(j)) {
/* PAL handle is requested for read/write but already marked with error:
* skip it but update its ret_events */
if (events[i] & (PAL_WAIT_READ | PAL_WAIT_WRITE)) {
ret_events[i] |= PAL_WAIT_ERROR;
ret_events_updated++;
}
continue;
}

int fdevents = 0;
fdevents |= ((flags & RFD(j)) && (events[i] & PAL_WAIT_READ)) ? POLLIN : 0;
Expand All @@ -93,13 +83,8 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
}

if (!nfds) {
if (ret_events_updated > 0) {
/* we skip actual ppoll, but there was at least one PAL handle with updated ret_events */
ret = 0;
} else {
/* did not find any waitable FDs (LibOS supplied closed/errored FDs or empty events) */
ret = -PAL_ERROR_TRYAGAIN;
}
/* did not find any waitable FDs (LibOS supplied closed FDs or empty events) */
ret = -PAL_ERROR_INVAL;
goto out;
}

Expand All @@ -115,15 +100,7 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
ret = INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout_us >= 0 ? &timeout_ts : NULL, NULL, 0);

if (ret < 0) {
switch (ret) {
case -EINTR:
case -ERESTART:
ret = -PAL_ERROR_INTERRUPTED;
break;
default:
ret = unix_to_pal_error(ret);
break;
}
ret = unix_to_pal_error(ret);
goto out;
}

Expand Down Expand Up @@ -153,6 +130,8 @@ int _DkStreamsWaitEvents(size_t count, PAL_HANDLE* handle_array, PAL_FLG* events
for (size_t k = 0; k < MAX_FDS; k++) {
if (hdl->generic.fds[k] != (PAL_IDX)fds[i].fd)
continue;
if (HANDLE_HDR(hdl)->flags & ERROR(k))
ret_events[j] |= PAL_WAIT_ERROR;
if (fds[i].revents & (POLLHUP | POLLERR | POLLNVAL))
HANDLE_HDR(hdl)->flags |= ERROR(k);
}
Expand Down

0 comments on commit 5a4b8a9

Please sign in to comment.