--- IO-AIO/AIO.xs 2018/02/20 04:32:59 1.253 +++ IO-AIO/AIO.xs 2018/02/20 05:23:47 1.254 @@ -112,6 +112,10 @@ # include #endif +#if HAVE_TIMERFD +# include +#endif + #if HAVE_RLIMITS #include #include @@ -975,6 +979,23 @@ } } +/*****************************************************************************/ + +static void +ts_set (struct timespec *ts, NV value) +{ + ts->tv_sec = value; + ts->tv_nsec = (value - ts->tv_sec) * 1e9; +} + +static NV +ts_get (const struct timespec *ts) +{ + return ts->tv_sec + ts->tv_nsec * 1e-9; +} + +/*****************************************************************************/ + XS(boot_IO__AIO) ecb_cold; MODULE = IO::AIO PACKAGE = IO::AIO @@ -1171,6 +1192,18 @@ const_iv (EFD_NONBLOCK) const_iv (EFD_SEMAPHORE) + const_iv (CLOCK_REALTIME) + const_iv (CLOCK_MONOTONIC) + const_iv (CLOCK_BOOTTIME) + const_iv (CLOCK_REALTIME_ALARM) + const_iv (CLOCK_BOOTTIME_ALARM) + + const_iv (TFD_NONBLOCK) + const_iv (TFD_CLOEXEC) + + const_iv (TFD_TIMER_ABSTIME) + const_iv (TFD_TIMER_CANCEL_ON_SET) + /* these are libeio constants, and are independent of gendef0 */ const_eio (SEEK_SET) const_eio (SEEK_CUR) @@ -2180,6 +2213,65 @@ XPUSHs (newmortalFH (fd, O_RDWR)); } +void +timerfd_create (int clockid, int flags = 0) + PPCODE: +{ + int fd; +#if HAVE_TIMERFD + fd = timerfd_create (clockid, flags); +#else + fd = (errno = ENOSYS, -1); +#endif + + XPUSHs (newmortalFH (fd, O_RDWR)); +} + +void +timerfd_settime (SV *fh, int flags, NV interval, NV value) + PPCODE: +{ + int fd = s_fileno_croak (fh, 0); + int res; + struct itimerspec its, ots; + + ts_set (&its.it_interval, interval); + ts_set (&its.it_value , value); +#if HAVE_TIMERFD + res = timerfd_settime (fd, flags, &its, &ots); +#else + res = (errno = ENOSYS, -1); +#endif + + if (!res) + { + EXTEND (SP, 2); + PUSHs (newSVnv (ts_get (&ots.it_interval))); + PUSHs (newSVnv (ts_get (&ots.it_value))); + } +} + +void +timerfd_gettime (SV *fh) + PPCODE: +{ + int fd = s_fileno_croak (fh, 0); + int res; + struct itimerspec ots; +#if HAVE_TIMERFD + res = timerfd_gettime (fd, &ots); +#else + res = (errno = ENOSYS, -1); +#endif + + if (!res) + { + EXTEND (SP, 2); + PUSHs (newSVnv (ts_get (&ots.it_interval))); + PUSHs (newSVnv (ts_get (&ots.it_value))); + } +} + UV get_fdlimit () CODE: