From 38306423cd445b729ebeb87a71481b0ec16082a5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 28 Aug 2019 17:11:45 +0100 Subject: [PATCH] freebsd: In nbdkit_nanosleep, fallback to calling nanosleep(2). Rather than failing to compile on platforms which lack POLLRDHUP such as FreeBSD, simply fallback to the old method of sleeping. This leaves the porting suggestions as a comment in case someone wants to implement a better solution for particular platforms. --- server/public.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/server/public.c b/server/public.c index a992df10..630de9b3 100644 --- a/server/public.c +++ b/server/public.c @@ -304,6 +304,16 @@ nbdkit_realpath (const char *path) int nbdkit_nanosleep (unsigned sec, unsigned nsec) { + struct timespec ts; + + if (sec >= INT_MAX - nsec / 1000000000) { + nbdkit_error ("sleep request is too long"); + errno = EINVAL; + return -1; + } + ts.tv_sec = sec + nsec / 1000000000; + ts.tv_nsec = nsec % 1000000000; + #if defined HAVE_PPOLL && defined POLLRDHUP /* End the sleep early if any of these happen: * - nbdkit has received a signal to shut down the server @@ -311,7 +321,6 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec) * NBD_CMD_DISC or a problem with the connection * - the input socket detects POLLRDHUP/POLLHUP/POLLERR */ - struct timespec ts; struct connection *conn = threadlocal_get_conn (); struct pollfd fds[] = { [0].fd = quit_fd, @@ -323,14 +332,6 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec) }; sigset_t all; - if (sec >= INT_MAX - nsec / 1000000000) { - nbdkit_error ("sleep request is too long"); - errno = EINVAL; - return -1; - } - ts.tv_sec = sec + nsec / 1000000000; - ts.tv_nsec = nsec % 1000000000; - /* Block all signals to this thread during the poll, so we don't * have to worry about EINTR */ @@ -354,9 +355,13 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec) nbdkit_error ("aborting sleep to shut down"); errno = ESHUTDOWN; return -1; + #else -# error "Please port this to your platform" - /* Porting ideas, in order of preference: + /* The fallback path simply calls ordinary nanosleep, and will + * cause long delays on server shutdown. + * + * If however you want to port this to your platform, then + * porting ideas, in order of preference: * - POSIX requires pselect; it's a bit clunkier to set up than poll, * but the same ability to atomically mask all signals and operate * on struct timespec makes it similar to the preferred ppoll interface @@ -364,8 +369,13 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec) * a recalculation of the timeout to still reach the end time (masking * signals in that case is not safe, as it is a non-atomic race) */ - nbdkit_error ("nbdkit_nanosleep not yet ported to systems without ppoll"); - errno = ENOSYS; - return -1; + int r; + + r = nanosleep (&ts, NULL); + if (r == -1 && errno != EINTR && errno != EAGAIN) { + nbdkit_error ("nanosleep: %m"); + return -1; + } + return 0; #endif } -- 2.11.4.GIT