]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sys_linux: avoid blocking in reading of external PHC timestamp
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 1 Mar 2023 13:41:34 +0000 (14:41 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 2 Mar 2023 14:13:18 +0000 (15:13 +0100)
The kernel has a common queue for all readers of a PHC device. With
multiple PHC refclocks using the same device some reads blocked. PHC
devices don't seem to support non-blocking reads. Use poll() to check if
a timestamp is available before reading from the descriptor.

sys_linux.c

index 8e647e33d9f14ae0be84d0e0f1920d1d4c64afd9..2a5eb8ffd132170b653b70474ce3e78e845edca2 100644 (file)
@@ -35,6 +35,7 @@
 
 #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
 #include <linux/ptp_clock.h>
+#include <poll.h>
 #endif
 
 #ifdef FEAT_SCFILTER
@@ -994,6 +995,16 @@ int
 SYS_Linux_ReadPHCExtTimestamp(int fd, struct timespec *phc_ts, int *channel)
 {
   struct ptp_extts_event extts_event;
+  struct pollfd pfd;
+
+  /* Make sure the read will not block in case we have multiple
+     descriptors of the same PHC (O_NONBLOCK does not work) */
+  pfd.fd = fd;
+  pfd.events = POLLIN;
+  if (poll(&pfd, 1, 0) != 1 || pfd.revents != POLLIN) {
+    DEBUG_LOG("Missing PHC extts event");
+    return 0;
+  }
 
   if (read(fd, &extts_event, sizeof (extts_event)) != sizeof (extts_event)) {
     DEBUG_LOG("Could not read PHC extts event");