posix_poll.c (3044B)
1 //======================================================================== 2 // GLFW 3.4 POSIX - www.glfw.org 3 //------------------------------------------------------------------------ 4 // Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org> 5 // 6 // This software is provided 'as-is', without any express or implied 7 // warranty. In no event will the authors be held liable for any damages 8 // arising from the use of this software. 9 // 10 // Permission is granted to anyone to use this software for any purpose, 11 // including commercial applications, and to alter it and redistribute it 12 // freely, subject to the following restrictions: 13 // 14 // 1. The origin of this software must not be misrepresented; you must not 15 // claim that you wrote the original software. If you use this software 16 // in a product, an acknowledgment in the product documentation would 17 // be appreciated but is not required. 18 // 19 // 2. Altered source versions must be plainly marked as such, and must not 20 // be misrepresented as being the original software. 21 // 22 // 3. This notice may not be removed or altered from any source 23 // distribution. 24 // 25 //======================================================================== 26 27 #define _GNU_SOURCE 28 29 #include "internal.h" 30 31 #if defined(GLFW_BUILD_POSIX_POLL) 32 33 #include <signal.h> 34 #include <time.h> 35 #include <errno.h> 36 37 GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout) 38 { 39 for (;;) 40 { 41 if (timeout) 42 { 43 const uint64_t base = _glfwPlatformGetTimerValue(); 44 45 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) 46 const time_t seconds = (time_t) *timeout; 47 const long nanoseconds = (long) ((*timeout - seconds) * 1e9); 48 const struct timespec ts = { seconds, nanoseconds }; 49 const int result = ppoll(fds, count, &ts, NULL); 50 #elif defined(__NetBSD__) 51 const time_t seconds = (time_t) *timeout; 52 const long nanoseconds = (long) ((*timeout - seconds) * 1e9); 53 const struct timespec ts = { seconds, nanoseconds }; 54 const int result = pollts(fds, count, &ts, NULL); 55 #else 56 const int milliseconds = (int) (*timeout * 1e3); 57 const int result = poll(fds, count, milliseconds); 58 #endif 59 const int error = errno; // clock_gettime may overwrite our error 60 61 *timeout -= (_glfwPlatformGetTimerValue() - base) / 62 (double) _glfwPlatformGetTimerFrequency(); 63 64 if (result > 0) 65 return GLFW_TRUE; 66 else if (result == -1 && error != EINTR && error != EAGAIN) 67 return GLFW_FALSE; 68 else if (*timeout <= 0.0) 69 return GLFW_FALSE; 70 } 71 else 72 { 73 const int result = poll(fds, count, -1); 74 if (result > 0) 75 return GLFW_TRUE; 76 else if (result == -1 && errno != EINTR && errno != EAGAIN) 77 return GLFW_FALSE; 78 } 79 } 80 } 81 82 #endif // GLFW_BUILD_POSIX_POLL 83