about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2013-09-24 16:55:47 +0800
committerEric Wong <normalperson@yhbt.net>2013-09-24 18:00:23 +0000
commitdf5628fee6d8f6c854302d90db5c35ba8dea83c7 (patch)
treeeb5b9be3964f8fdaeb9a94aecf15829cea6f56db
parentf039e80b90260f7c4a831806ddc4d22fc9d27eb4 (diff)
downloadsleepy_penguin-df5628fee6d8f6c854302d90db5c35ba8dea83c7.tar.gz
Fallback mechanism was copied from clogger:

    http://clogger.rubyforge.org/

This would also make sleepy_penguin compiles on Mac OS X,
which is lacking clock_gettime. All tests passed for me.

[ew: fixed indentation
 Note: this project does not and will never officially support
 non-Free OSes, but there are likely other systems without
 clock_gettime but has kqueue (perhaps via libkqueue).]

Signed-off-by: Eric Wong <normalperson@yhbt.net>
-rw-r--r--ext/sleepy_penguin/epoll.c1
-rw-r--r--ext/sleepy_penguin/extconf.rb5
-rw-r--r--ext/sleepy_penguin/kqueue.c1
-rw-r--r--ext/sleepy_penguin/missing_clock_gettime.h36
4 files changed, 43 insertions, 0 deletions
diff --git a/ext/sleepy_penguin/epoll.c b/ext/sleepy_penguin/epoll.c
index 9010e2d..5e5cb20 100644
--- a/ext/sleepy_penguin/epoll.c
+++ b/ext/sleepy_penguin/epoll.c
@@ -3,6 +3,7 @@
 #include <sys/epoll.h>
 #include <unistd.h>
 #include <time.h>
+#include "missing_clock_gettime.h"
 #include "missing_epoll.h"
 #include "missing_rb_thread_fd_close.h"
 #include "missing_rb_update_max_fd.h"
diff --git a/ext/sleepy_penguin/extconf.rb b/ext/sleepy_penguin/extconf.rb
index 2ed9b21..0e6977a 100644
--- a/ext/sleepy_penguin/extconf.rb
+++ b/ext/sleepy_penguin/extconf.rb
@@ -13,6 +13,11 @@ have_header('sys/eventfd.h')
 have_header('sys/timerfd.h')
 have_header('sys/inotify.h')
 have_header('ruby/io.h') and have_struct_member('rb_io_t', 'fd', 'ruby/io.h')
+unless have_macro('CLOCK_MONOTONIC', 'time.h')
+  have_func('CLOCK_MONOTONIC', 'time.h')
+end
+have_type('clockid_t', 'time.h')
+have_func('clock_gettime', 'time.h')
 have_func('epoll_create1', %w(sys/epoll.h))
 have_func('rb_thread_call_without_gvl')
 have_func('rb_thread_blocking_region')
diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c
index 59c3dae..83f3623 100644
--- a/ext/sleepy_penguin/kqueue.c
+++ b/ext/sleepy_penguin/kqueue.c
@@ -5,6 +5,7 @@
 #include <sys/time.h>
 #include <unistd.h>
 #include <time.h>
+#include "missing_clock_gettime.h"
 #include "missing_rb_thread_fd_close.h"
 #include "missing_rb_update_max_fd.h"
 #include "value2timespec.h"
diff --git a/ext/sleepy_penguin/missing_clock_gettime.h b/ext/sleepy_penguin/missing_clock_gettime.h
new file mode 100644
index 0000000..632612b
--- /dev/null
+++ b/ext/sleepy_penguin/missing_clock_gettime.h
@@ -0,0 +1,36 @@
+/*
+ * this header includes functions to support broken systems
+ * without clock_gettime() or CLOCK_MONOTONIC
+ */
+
+#ifndef HAVE_TYPE_CLOCKID_T
+typedef int clockid_t;
+#endif
+
+#ifndef HAVE_CLOCK_GETTIME
+#  ifndef CLOCK_REALTIME
+#    define CLOCK_REALTIME 0 /* whatever */
+#  endif
+static int fake_clock_gettime(clockid_t clk_id, struct timespec *res)
+{
+        struct timeval tv;
+        int r = gettimeofday(&tv, NULL);
+
+        assert(0 == r && "gettimeofday() broke!?");
+        res->tv_sec = tv.tv_sec;
+        res->tv_nsec = tv.tv_usec * 1000;
+
+        return r;
+}
+#  define clock_gettime fake_clock_gettime
+#endif /* broken systems w/o clock_gettime() */
+
+/*
+ * UGH
+ * CLOCK_MONOTONIC is not guaranteed to be a macro, either
+ */
+#ifndef CLOCK_MONOTONIC
+#  if (!defined(_POSIX_MONOTONIC_CLOCK) || !defined(HAVE_CLOCK_MONOTONIC))
+#    define CLOCK_MONOTONIC CLOCK_REALTIME
+#  endif
+#endif