sleepy_penguin RubyGem user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation
@ 2013-05-03  1:20 Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 2/4] kqueue: remove timeout handling for nevents==0 Eric Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eric Wong @ 2013-05-03  1:20 UTC (permalink / raw)
  To: sleepy.penguin

Hopefully this will lead to less confusion among new
users.
---
 .document                    |  1 +
 ext/sleepy_penguin/kqueue.c  | 55 +++++++++++++++++++++++++++++++++-----------
 lib/sleepy_penguin/kevent.rb |  4 ++++
 lib/sleepy_penguin/kqueue.rb | 11 +++++++--
 4 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/.document b/.document
index 03969e3..001f785 100644
--- a/.document
+++ b/.document
@@ -10,3 +10,4 @@ ext/sleepy_penguin/init.c
 ext/sleepy_penguin/inotify.c
 ext/sleepy_penguin/signalfd.c
 ext/sleepy_penguin/timerfd.c
+ext/sleepy_penguin/kqueue.c
diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c
index 4d5785f..e7d1deb 100644
--- a/ext/sleepy_penguin/kqueue.c
+++ b/ext/sleepy_penguin/kqueue.c
@@ -117,7 +117,8 @@ out:
  * kqueue descriptors are automatically invalidated across fork, so care
  * must be taken when forking.
  * Setting IO#autoclose=false is recommended for applications which fork
- * after kqueue creation.
+ * after kqueue creation.  Ruby 1.8 does not have IO#autoclose=, so using
+ * this class is not recommended under Ruby 1.8
  */
 static VALUE s_new(VALUE klass)
 {
@@ -321,6 +322,26 @@ static void changelist_prepare(struct kevent *events, VALUE changelist)
 /*
  * call-seq:
  *	kq_io.kevent([changelist[, nevents[, timeout]]]) { |ident,filter,flags,fflags,data,udata| ... }
+ *
+ * This is a wrapper around the kevent(2) system call to change and/or
+ * retrieve events from the underlying kqueue descriptor.
+ *
+ * +changelist+ may be nil, a single Kevent struct or an array of Kevent
+ * structs.  If +changelist+ is nil, no changes will be made to the
+ * underlying kqueue object.
+ *
+ * +nevents+ may be non-negative integer or nil.  If +nevents+ is zero or
+ * nil, no events are retrieved.  If +nevents+ is positive, a block must
+ * be passed to kevent for each event.
+ *
+ * +timeout+ is the numeric timeout in seconds to wait for +nevents+.
+ * If nil and +nevents+ is positive, kevent will sleep forever.
+ * +timeout+ may be in a floating point number if subsecond resolution
+ * is required.  If +nevents+ is nil or zero and +timeout+ is not specified,
+ * +timeout+ is implied to be zero.
+ *
+ * If event retrieval is desired, a block taking 6-elements (one for each
+ * field of the kevent struct) must be passed.
  */
 static VALUE sp_kevent(int argc, VALUE *argv, VALUE self)
 {
@@ -365,6 +386,12 @@ static VALUE sp_kevent(int argc, VALUE *argv, VALUE self)
 /* initialize constants in the SleepyPenguin::Ev namespace */
 static void init_ev(VALUE mSleepyPenguin)
 {
+	/*
+	 * Document-module: SleepyPenguin::Ev
+	 *
+	 * Constants in the SleepyPenguin::Ev namespace are for the +flags+
+	 * field in Kevent structs.
+	 */
 	mEv = rb_define_module_under(mSleepyPenguin, "Ev");
 
 	/* See EV_ADD in the kevent(2) man page */
@@ -402,6 +429,8 @@ static void init_ev(VALUE mSleepyPenguin)
 static void init_evfilt(VALUE mSleepyPenguin)
 {
 	/*
+	 * Document-module: SleepyPenguin::EvFilt
+	 *
 	 * Pre-defined system filters for Kqueue events.  Not all filters
 	 * are supported on all platforms.  Consult the kevent(2) man page
 	 * and source code for your operating system for more information.
@@ -464,7 +493,9 @@ static void init_evfilt(VALUE mSleepyPenguin)
 static void init_note(VALUE mSleepyPenguin)
 {
 	/*
-	 * data/hint flags/mask for EVFILT_USER and friends
+	 * Document-module: SleepyPenguin::Note
+	 *
+	 * Data/hint flags/masks for EVFILT_USER and friends in Kqueue
 	 * On input, the top two bits of fflags specifies how the lower
 	 * twenty four bits should be applied to the stored value of fflags.
 	 *
@@ -569,7 +600,11 @@ static void init_note(VALUE mSleepyPenguin)
 static void init_vq(VALUE mSleepyPenguin)
 {
 #ifdef VQ_NOTRESP
-	/* constants used by the EvFilt::FS filter */
+	/*
+	 * Document-module: SleepyPenguin::VQ
+	 *
+	 * Constants used by the EvFilt::FS filter in the Kqueue interfaces
+	 */
 	mVQ = rb_define_module_under(mSleepyPenguin, "VQ");
 
 	/* server down */
@@ -608,15 +643,6 @@ void sleepy_penguin_init_kqueue(void)
 	init_note(mSleepyPenguin);
 	init_vq(mSleepyPenguin);
 
-	/*
-	 * Document-class: SleepyPenguin::Kqueue
-	 *
-	 * The Kqueue class provides high-level access to kqueue(2)
-	 * functionality in FreeBSD and similar systems.
-	 * It provides fork and GC-safety for Ruby objects stored
-	 * within the IO object and may be passed as an argument to
-	 * IO.select.
-	 */
 	cKqueue = rb_define_class_under(mSleepyPenguin, "Kqueue", rb_cObject);
 
 	/*
@@ -626,7 +652,10 @@ void sleepy_penguin_init_kqueue(void)
 	 * GC-safety, so Ruby IO objects added via kevent must be retained
 	 * by the application until IO#close is called.
 	 *
-	 * Warning: this class is easy to misuse, do not rely on
+	 * Warning: this class is easy to misuse, be careful as failure
+	 * to preserve references objects passed as Kevent#udata may lead
+	 * to crashes in Ruby.  The high-level Kqueue class prevents these
+	 * crashes (but may still return invalid objects).
 	 */
 	cKqueue_IO = rb_define_class_under(cKqueue, "IO", rb_cIO);
 	rb_define_singleton_method(cKqueue_IO, "new", s_new, 0);
diff --git a/lib/sleepy_penguin/kevent.rb b/lib/sleepy_penguin/kevent.rb
index 5b3dca9..1102737 100644
--- a/lib/sleepy_penguin/kevent.rb
+++ b/lib/sleepy_penguin/kevent.rb
@@ -1,3 +1,7 @@
+# This class represents a "struct kevent" structure for Ruby.
+# This may be passed to Kqueue::IO#kevent as either a single element
+# or as an element inside an array to inject changes into the kevent
+# list.
 class SleepyPenguin::Kevent < Struct.new(:ident, :filter, :flags,
                                          :fflags, :data, :udata)
 end
diff --git a/lib/sleepy_penguin/kqueue.rb b/lib/sleepy_penguin/kqueue.rb
index 1eeb641..dd09c51 100644
--- a/lib/sleepy_penguin/kqueue.rb
+++ b/lib/sleepy_penguin/kqueue.rb
@@ -8,6 +8,10 @@
 # Events registered to a Kqueue object cannot be shared across fork
 # due to the underlying implementation of kqueue in *BSDs.
 class SleepyPenguin::Kqueue
+
+  # Initialize a new Kqueue object, this allocates an underlying Kqueue::IO
+  # object and may fail if the system is out of file descriptors or
+  # kernel memory
   def initialize
     @io = SleepyPenguin::Kqueue::IO.new
     @mtx = Mutex.new
@@ -46,8 +50,11 @@ def __kq_check # :nodoc:
     @pid = $$
   end
 
-  # Users are responsible for ensuring udata objects remain visible to the
-  # Ruby GC.
+  # A high-level wrapper around Kqueue::IO#kevent
+  # Users are responsible for ensuring +udata+ objects remain visible to the
+  # Ruby GC, otherwise ObjectSpace._id2ref may return invalid objects.
+  # Unlike the low-level Kqueue::IO#kevent, the block given yields only
+  # a single Kevent struct, not a 6-element array.
   def kevent(changelist = nil, *args)
     @mtx.synchronize { __kq_check }
     if changelist
-- 
1.8.2.1.367.gc875ca7



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [sleepy.penguin] [PATCH 2/4] kqueue: remove timeout handling for nevents==0
  2013-05-03  1:20 [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation Eric Wong
@ 2013-05-03  1:20 ` Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 3/4] test_kqueue_io: additional test for IO-likeness Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 4/4] README: update with latest features Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2013-05-03  1:20 UTC (permalink / raw)
  To: sleepy.penguin

The underlying kevent() itself already bypasses the timeout
if nevents==0 (so it is impossible to emulate a sleep function
with kevent()).
---
 ext/sleepy_penguin/kqueue.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/ext/sleepy_penguin/kqueue.c b/ext/sleepy_penguin/kqueue.c
index e7d1deb..59c3dae 100644
--- a/ext/sleepy_penguin/kqueue.c
+++ b/ext/sleepy_penguin/kqueue.c
@@ -365,14 +365,13 @@ static VALUE sp_kevent(int argc, VALUE *argv, VALUE self)
 			rb_raise(rb_eArgError,
 				"block given but nevents not specified");
 		nevents = NUM2INT(events);
-		if (nevents <= 0)
-			rb_raise(rb_eArgError, "nevents must be positive");
+		if (nevents < 0)
+			rb_raise(rb_eArgError, "nevents must be non-negative");
 	} else {
 		if (!NIL_P(events))
 			rb_raise(rb_eArgError,
 				"nevents specified but block not given");
 		nevents = 0;
-		timeout = INT2FIX(0);
 	}
 
 	kpt = kpt_get(self, nchanges, nevents);
-- 
1.8.2.1.367.gc875ca7



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [sleepy.penguin] [PATCH 3/4] test_kqueue_io: additional test for IO-likeness
  2013-05-03  1:20 [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 2/4] kqueue: remove timeout handling for nevents==0 Eric Wong
@ 2013-05-03  1:20 ` Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 4/4] README: update with latest features Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2013-05-03  1:20 UTC (permalink / raw)
  To: sleepy.penguin

We need to ensure Kqueue::IO remains IO-like
---
 test/test_kqueue_io.rb | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/test/test_kqueue_io.rb b/test/test_kqueue_io.rb
index 076c9f0..04e3103 100644
--- a/test/test_kqueue_io.rb
+++ b/test/test_kqueue_io.rb
@@ -16,6 +16,13 @@ def teardown
     end
   end
 
+  def test_io_like
+    kq = Kqueue::IO.new
+    @to_close << kq
+    assert_equal kq, kq.to_io
+    assert_kind_of Integer, kq.fileno
+  end
+
   def test_bad_type
     kq = Kqueue::IO.new
     @to_close << kq
-- 
1.8.2.1.367.gc875ca7



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [sleepy.penguin] [PATCH 4/4] README: update with latest features
  2013-05-03  1:20 [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 2/4] kqueue: remove timeout handling for nevents==0 Eric Wong
  2013-05-03  1:20 ` [sleepy.penguin] [PATCH 3/4] test_kqueue_io: additional test for IO-likeness Eric Wong
@ 2013-05-03  1:20 ` Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2013-05-03  1:20 UTC (permalink / raw)
  To: sleepy.penguin

We support kqueue and Rubinius.  Nowadays, we also export
the potentially dangerous low-level APIs for epoll and kqueue.
---
 README | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/README b/README
index 551ce8e..9574dce 100644
--- a/README
+++ b/README
@@ -2,19 +2,21 @@
 
 sleepy_penguin provides access to newer, Linux-only system calls to wait
 on events from traditionally non-I/O sources.  Bindings to the eventfd,
-timerfd, inotify, and epoll interfaces are provided.
+timerfd, inotify, and epoll interfaces are provided.  Experimental support
+for kqueue on FreeBSD (and likely OpenBSD/NetBSD) are also provided.
 
 == Features
 
-* Thread-safe blocking operations for all versions of Ruby
+* Thread-safe blocking operations for all versions of Matz Ruby and Rubinius
 
 * IO-like objects are backwards-compatible with IO.select.
 
-* Epoll interface is fork-safe and GC-safe
+* High-level Epoll interface is fork-safe and GC-safe
 
 * Unlike portable event frameworks, the Linux-only epoll interfaces
   allow using edge-triggered or one-shot notifications for possibly
-  improved performance
+  improved performance.  Likewise, the kqueue interface supports
+  one-shot notifiactions, too.
 
 * Fully-documented and user-friendly API
 
-- 
1.8.2.1.367.gc875ca7



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-05-03  1:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-03  1:20 [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation Eric Wong
2013-05-03  1:20 ` [sleepy.penguin] [PATCH 2/4] kqueue: remove timeout handling for nevents==0 Eric Wong
2013-05-03  1:20 ` [sleepy.penguin] [PATCH 3/4] test_kqueue_io: additional test for IO-likeness Eric Wong
2013-05-03  1:20 ` [sleepy.penguin] [PATCH 4/4] README: update with latest features Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/sleepy_penguin.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).