[前][次][番号順一覧][スレッド一覧]

ruby-changes:51214

From: normal <ko1@a...>
Date: Tue, 15 May 2018 08:51:40 +0900 (JST)
Subject: [ruby-changes:51214] normal:r63421 (trunk): test_wait_for_single_fd: ensure this works with kqueue

normal	2018-05-15 08:51:35 +0900 (Tue, 15 May 2018)

  New Revision: 63421

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63421

  Log:
    test_wait_for_single_fd: ensure this works with kqueue
    
    Regardless of future features, this needs to work with
    kqueue descriptors across platforms.
    
    Today this will be useful for 3rd-party libraries using
    kqueue.  In the future, Ruby may use kqueue natively
    and we shall ensure we can wait on it.

  Modified files:
    trunk/ext/-test-/wait_for_single_fd/extconf.rb
    trunk/ext/-test-/wait_for_single_fd/wait_for_single_fd.c
    trunk/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
Index: test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
===================================================================
--- test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb	(revision 63420)
+++ test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb	(revision 63421)
@@ -52,5 +52,8 @@ class TestWaitForSingleFD < Test::Unit:: https://github.com/ruby/ruby/blob/trunk/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb#L52
     end
   end
 
-
+  def test_wait_for_kqueue
+    skip 'no kqueue' unless IO.respond_to?(:kqueue_test_wait)
+    assert_equal RB_WAITFD_IN, IO.kqueue_test_wait
+  end
 end
Index: ext/-test-/wait_for_single_fd/wait_for_single_fd.c
===================================================================
--- ext/-test-/wait_for_single_fd/wait_for_single_fd.c	(revision 63420)
+++ ext/-test-/wait_for_single_fd/wait_for_single_fd.c	(revision 63421)
@@ -19,6 +19,67 @@ wait_for_single_fd(VALUE ign, VALUE fd, https://github.com/ruby/ruby/blob/trunk/ext/-test-/wait_for_single_fd/wait_for_single_fd.c#L19
     return INT2NUM(rc);
 }
 
+#ifdef HAVE_KQUEUE
+/* ensure rb_wait_for_single_fd works on kqueue descriptors */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/event.h>
+static VALUE
+kqueue_test_wait(VALUE klass)
+{
+    int kqfd = -1;
+    int p[2] = { -1, -1 };
+    struct timeval tv = { 0, 0 };
+    const struct timespec ts = { 1, 0 };
+    struct kevent kev;
+    const char *msg;
+    VALUE ret = Qfalse;
+    int e = 0;
+    int n;
+
+    msg = "pipe";
+    if (rb_cloexec_pipe(p) < 0) goto err;
+
+    msg = "kqueue";
+    kqfd = kqueue();
+    if (kqfd < 0) goto err;
+
+    n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
+    if (n != 0) {
+        msg = "spurious wakeup";
+        errno = 0;
+        goto err;
+    }
+
+    msg = "write";
+    if (write(p[1], "", 1) < 0) goto err;
+
+    EV_SET(&kev, p[0], EVFILT_READ, EV_ADD, 0, 0, 0);
+
+    msg = "kevent";
+    n = kevent(kqfd, &kev, 1, &kev, 1, &ts);
+    if (n < 0) goto err;
+    msg = NULL;
+    if (n == 1) {
+        n = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN, &tv);
+        ret = INT2NUM(n);
+    }
+    else {
+        rb_warn("kevent did not return readiness");
+    }
+err:
+    if (msg) e = errno;
+    if (p[0] >= 0) close(p[0]);
+    if (p[1] >= 0) close(p[1]);
+    if (kqfd >= 0) close(kqfd);
+    if (msg) {
+        if (e) rb_syserr_fail(e, msg);
+        rb_raise(rb_eRuntimeError, msg);
+    }
+    return ret;
+}
+#endif /* HAVE_KQUEUE */
+
 void
 Init_wait_for_single_fd(void)
 {
@@ -27,4 +88,7 @@ Init_wait_for_single_fd(void) https://github.com/ruby/ruby/blob/trunk/ext/-test-/wait_for_single_fd/wait_for_single_fd.c#L88
     rb_define_const(rb_cObject, "RB_WAITFD_PRI", INT2NUM(RB_WAITFD_PRI));
     rb_define_singleton_method(rb_cIO, "wait_for_single_fd",
                                wait_for_single_fd, 3);
+#ifdef HAVE_KQUEUE
+    rb_define_singleton_method(rb_cIO, "kqueue_test_wait", kqueue_test_wait, 0);
+#endif
 }
Index: ext/-test-/wait_for_single_fd/extconf.rb
===================================================================
--- ext/-test-/wait_for_single_fd/extconf.rb	(revision 63420)
+++ ext/-test-/wait_for_single_fd/extconf.rb	(revision 63421)
@@ -1,2 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/wait_for_single_fd/extconf.rb#L1
 # frozen_string_literal: false
+headers = %w(sys/types.h sys/time.h sys/event.h).select { |h| have_header(h) }
+have_func('kqueue', headers)
 create_makefile("-test-/wait_for_single_fd")

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]