| //======================================================================== |
| // GLFW 3.5 POSIX - www.glfw.org |
| //------------------------------------------------------------------------ |
| // Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org> |
| // |
| // This software is provided 'as-is', without any express or implied |
| // warranty. In no event will the authors be held liable for any damages |
| // arising from the use of this software. |
| // |
| // Permission is granted to anyone to use this software for any purpose, |
| // including commercial applications, and to alter it and redistribute it |
| // freely, subject to the following restrictions: |
| // |
| // 1. The origin of this software must not be misrepresented; you must not |
| // claim that you wrote the original software. If you use this software |
| // in a product, an acknowledgment in the product documentation would |
| // be appreciated but is not required. |
| // |
| // 2. Altered source versions must be plainly marked as such, and must not |
| // be misrepresented as being the original software. |
| // |
| // 3. This notice may not be removed or altered from any source |
| // distribution. |
| // |
| //======================================================================== |
| |
| #define _GNU_SOURCE |
| |
| #include "internal.h" |
| |
| #if defined(GLFW_BUILD_POSIX_POLL) |
| |
| #include <signal.h> |
| #include <time.h> |
| #include <errno.h> |
| |
| GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout) |
| { |
| for (;;) |
| { |
| if (timeout) |
| { |
| const uint64_t base = _glfwPlatformGetTimerValue(); |
| |
| #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) |
| const time_t seconds = (time_t) *timeout; |
| const long nanoseconds = (long) ((*timeout - seconds) * 1e9); |
| const struct timespec ts = { seconds, nanoseconds }; |
| const int result = ppoll(fds, count, &ts, NULL); |
| #elif defined(__NetBSD__) |
| const time_t seconds = (time_t) *timeout; |
| const long nanoseconds = (long) ((*timeout - seconds) * 1e9); |
| const struct timespec ts = { seconds, nanoseconds }; |
| const int result = pollts(fds, count, &ts, NULL); |
| #else |
| const int milliseconds = (int) (*timeout * 1e3); |
| const int result = poll(fds, count, milliseconds); |
| #endif |
| const int error = errno; // clock_gettime may overwrite our error |
| |
| *timeout -= (_glfwPlatformGetTimerValue() - base) / |
| (double) _glfwPlatformGetTimerFrequency(); |
| |
| if (result > 0) |
| return GLFW_TRUE; |
| else if (result == -1 && error != EINTR && error != EAGAIN) |
| return GLFW_FALSE; |
| else if (*timeout <= 0.0) |
| return GLFW_FALSE; |
| } |
| else |
| { |
| const int result = poll(fds, count, -1); |
| if (result > 0) |
| return GLFW_TRUE; |
| else if (result == -1 && errno != EINTR && errno != EAGAIN) |
| return GLFW_FALSE; |
| } |
| } |
| } |
| |
| #endif // GLFW_BUILD_POSIX_POLL |
| |