Esempio n. 1
0
int32_t SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered)
{
    if (pollEvents == NULL || triggered == NULL)
    {
        return Error_EFAULT;
    }

    if (milliseconds < -1)
    {
        return Error_EINVAL;
    }

    size_t bufferSize;
    if (!multiply_s(sizeof(struct pollfd), (size_t)eventCount, &bufferSize))
    {
        return SystemNative_ConvertErrorPlatformToPal(EOVERFLOW);
    }


    int useStackBuffer = bufferSize <= 2048;
    struct pollfd* pollfds = (struct pollfd*)(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));
    if (pollfds == NULL)
    {
        return Error_ENOMEM;
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const PollEvent* event = &pollEvents[i];
        pollfds[i].fd = event->FileDescriptor;
        // we need to do this for platforms like AIX where PAL_POLL* doesn't
        // match up to their reality; this is PollEvent -> system polling
        switch (event->Events)
        {
            case PAL_POLLIN:
                pollfds[i].events = POLLIN;
                break;
            case PAL_POLLPRI:
                pollfds[i].events = POLLPRI;
                break;
            case PAL_POLLOUT:
                pollfds[i].events = POLLOUT;
                break;
            case PAL_POLLERR:
                pollfds[i].events = POLLERR;
                break;
            case PAL_POLLHUP:
                pollfds[i].events = POLLHUP;
                break;
            case PAL_POLLNVAL:
                pollfds[i].events = POLLNVAL;
                break;
            default:
                pollfds[i].events = event->Events;
                break;
        }
        pollfds[i].revents = 0;
    }

    int rv;
    while ((rv = poll(pollfds, (nfds_t)eventCount, milliseconds)) < 0 && errno == EINTR);

    if (rv < 0)
    {
        if (!useStackBuffer)
        {
            free(pollfds);
        }

        *triggered = 0;
        return SystemNative_ConvertErrorPlatformToPal(errno);
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const struct pollfd* pfd = &pollfds[i];
        assert(pfd->fd == pollEvents[i].FileDescriptor);
        assert(pfd->events == pollEvents[i].Events);

        // same as the other switch, just system -> PollEvent
        switch (pfd->revents)
        {
            case POLLIN:
                pollEvents[i].TriggeredEvents = PAL_POLLIN;
                break;
            case POLLPRI:
                pollEvents[i].TriggeredEvents = PAL_POLLPRI;
                break;
            case POLLOUT:
                pollEvents[i].TriggeredEvents = PAL_POLLOUT;
                break;
            case POLLERR:
                pollEvents[i].TriggeredEvents = PAL_POLLERR;
                break;
            case POLLHUP:
                pollEvents[i].TriggeredEvents = PAL_POLLHUP;
                break;
            case POLLNVAL:
                pollEvents[i].TriggeredEvents = PAL_POLLNVAL;
                break;
            default:
                pollEvents[i].TriggeredEvents = (int16_t)pfd->revents;
                break;
        }
    }

    *triggered = (uint32_t)rv;

    if (!useStackBuffer)
    {
        free(pollfds);
    }

    return Error_SUCCESS;
}
Esempio n. 2
0
extern "C" Error SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered)
{
    if (pollEvents == nullptr || triggered == nullptr)
    {
        return PAL_EFAULT;
    }

    if (milliseconds < -1)
    {
        return PAL_EINVAL;
    }

    size_t bufferSize;
    if (!multiply_s(sizeof(pollfd), static_cast<size_t>(eventCount), &bufferSize))
    {
        return SystemNative_ConvertErrorPlatformToPal(EOVERFLOW);        
    }

    bool useStackBuffer = bufferSize <= 2048;
    pollfd* pollfds = reinterpret_cast<pollfd*>(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));
    if (pollfds == nullptr)
    {
        return PAL_ENOMEM;
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const PollEvent& event = pollEvents[i];
        pollfds[i] = { .fd = event.FileDescriptor, .events = event.Events, .revents = 0 };
    }

    int rv;
    while (CheckInterrupted(rv = poll(pollfds, static_cast<nfds_t>(eventCount), milliseconds)));

    if (rv < 0)
    {
        if (!useStackBuffer)
        {
            free(pollfds);
        }

        *triggered = 0;
        return SystemNative_ConvertErrorPlatformToPal(errno);
    }

    for (uint32_t i = 0; i < eventCount; i++)
    {
        const pollfd& pfd = pollfds[i];
        assert(pfd.fd == pollEvents[i].FileDescriptor);
        assert(pfd.events == pollEvents[i].Events);

        pollEvents[i].TriggeredEvents = static_cast<PollEvents>(pfd.revents);
    }

    *triggered = static_cast<uint32_t>(rv);

    if (!useStackBuffer)
    {
        free(pollfds);
    }

    return PAL_SUCCESS;
}

extern "C" int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, FileAdvice advice)
{
#if HAVE_POSIX_ADVISE
    int32_t result;
    while (CheckInterrupted(
        result =
#if HAVE_POSIX_FADVISE64
            posix_fadvise64(
#else
            posix_fadvise(
#endif
                ToFileDescriptor(fd),
                offset,
                length,
                advice)));
    return result;
#else
    // Not supported on this platform. Caller can ignore this failure since it's just a hint.
    (void)fd, (void)offset, (void)length, (void)advice;
    return ENOTSUP;
#endif
}