| 1389 | } |
| 1390 | |
| 1391 | int __syscall_poll(struct pollfd* fds, nfds_t nfds, int timeout) { |
| 1392 | auto fileTable = wasmFS.getFileTable().locked(); |
| 1393 | |
| 1394 | // Process the list of FDs and compute their revents masks. Count the number |
| 1395 | // of nonzero such masks, which is our return value. |
| 1396 | int nonzero = 0; |
| 1397 | for (nfds_t i = 0; i < nfds; i++) { |
| 1398 | auto* pollfd = &fds[i]; |
| 1399 | auto fd = pollfd->fd; |
| 1400 | if (fd < 0) { |
| 1401 | // Negative FDs are ignored in poll(). |
| 1402 | pollfd->revents = 0; |
| 1403 | continue; |
| 1404 | } |
| 1405 | // Assume invalid, unless there is an open file. |
| 1406 | auto mask = POLLNVAL; |
| 1407 | auto openFile = fileTable.getEntry(fd); |
| 1408 | if (openFile) { |
| 1409 | mask = 0; |
| 1410 | auto flags = openFile->locked().getFlags(); |
| 1411 | auto accessMode = flags & O_ACCMODE; |
| 1412 | auto readBit = pollfd->events & POLLOUT; |
| 1413 | if (readBit && (accessMode == O_WRONLY || accessMode == O_RDWR)) { |
| 1414 | mask |= readBit; |
| 1415 | } |
| 1416 | auto writeBit = pollfd->events & POLLIN; |
| 1417 | if (writeBit && (accessMode == O_RDONLY || accessMode == O_RDWR)) { |
| 1418 | // If there is data in the file, then there is also the ability to read. |
| 1419 | // TODO: Does this need to consider the position as well? That is, if |
| 1420 | // the position is at the end, we can't read from the current position |
| 1421 | // at least. If we update this, make sure the size isn't an error! |
| 1422 | if (openFile->locked().getFile()->locked().getSize() > 0) { |
| 1423 | mask |= writeBit; |
| 1424 | } |
| 1425 | } |
| 1426 | // TODO: get mask from File dynamically using a poll() hook? |
| 1427 | } |
| 1428 | // TODO: set the state based on the state of the other end of the pipe, for |
| 1429 | // pipes (POLLERR | POLLHUP) |
| 1430 | if (mask) { |
| 1431 | nonzero++; |
| 1432 | } |
| 1433 | pollfd->revents = mask; |
| 1434 | } |
| 1435 | // TODO: This should block based on the timeout. The old FS did not do so due |
| 1436 | // to web limitations, which we should perhaps revisit (especially with |
| 1437 | // pthreads and asyncify). |
| 1438 | return nonzero; |
| 1439 | } |
| 1440 | |
| 1441 | // libc routes zero-timeout poll() calls here (see musl's poll.c). WasmFS's |
| 1442 | // __syscall_poll never blocks, so the zero-timeout probe is the same call. |