+#ifdef USE_TIMERFD_CREATE
+static void
+rb_read_timerfd(rb_fde_t *F, void *data)
+{
+ struct ev_entry *event = (struct ev_entry *)data;
+ int retlen;
+ uint64_t count;
+
+ if(event == NULL)
+ {
+ rb_close(F);
+ return;
+ }
+
+ retlen = rb_read(F, &count, sizeof(count));
+
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ {
+ rb_close(F);
+ rb_lib_log("rb_read_timerfd: timerfd[%s] closed on error: %s", event->name,
+ strerror(errno));
+ return;
+ }
+ rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event);
+ rb_run_event(event);
+}
+
+
+static int
+rb_epoll_sched_event_timerfd(struct ev_entry *event, int when)
+{
+ struct itimerspec ts;
+ static char buf[FD_DESC_SZ + 8];
+ int fd;
+ rb_fde_t *F;
+
+ if((fd = timerfd_create(CLOCK_REALTIME, 0)) < 0)
+ {
+ rb_lib_log("timerfd_create: %s\n", strerror(errno));
+ return 0;
+ }
+
+ memset(&ts, 0, sizeof(ts));
+ ts.it_value.tv_sec = when;
+ ts.it_value.tv_nsec = 0;
+ if(event->frequency != 0)
+ ts.it_interval = ts.it_value;
+
+ if(timerfd_settime(fd, 0, &ts, NULL) < 0)
+ {
+ rb_lib_log("timerfd_settime: %s\n", strerror(errno));
+ close(fd);
+ return 0;
+ }
+ rb_snprintf(buf, sizeof(buf), "timerfd: %s", event->name);
+ F = rb_open(fd, RB_FD_UNKNOWN, buf);
+ rb_set_nb(F);
+ event->comm_ptr = F;
+ rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event);
+ return 1;
+}
+#endif
+
+
+
+int
+rb_epoll_sched_event(struct ev_entry *event, int when)
+{
+#ifdef USE_TIMERFD_CREATE
+ if(can_do_timerfd)
+ {
+ return rb_epoll_sched_event_timerfd(event, when);
+ }
+#endif
+ return rb_epoll_sched_event_signalfd(event, when);
+}
+