> What does your testing show when you don't have > the extra check, i.e., > > struct timespec delay; > struct timespec remain; > > delay.tv_sec = microsec / 1000000L; > delay.tv_nsec = (microsec % 1000000L) * 1000; > > while (nanosleep(&delay, &remain) == -1 && errno == EINTR) > delay = remain; >
This is similar to the first attempt [1], +pg_usleep_handle_interrupt(long microsec, bool force) { if (microsec > 0) { #ifndef WIN32 struct timespec delay; + struct timespec remaining; delay.tv_sec = microsec / 1000000L; delay.tv_nsec = (microsec % 1000000L) * 1000; - (void) nanosleep(&delay, NULL); + + if (force) + while (nanosleep(&delay, &remaining) == -1 && errno == EINTR) + delay = remaining; but Bertrand found long drifts [2[ which I could not reproduce. To safeguard the long drifts, continue to use the &remain time with an additional safeguard to make sure the actual sleep does not exceed the requested sleep time. [1] https://www.postgresql.org/message-id/7D50DC5B-80C6-47B5-8DA8-A6C68A115EE5%40gmail.com [2] https://www.postgresql.org/message-id/ZoPC5IeP4k7sZpki%40ip-10-97-1-34.eu-west-3.compute.internal Regards, Sami