From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS47066 71.19.144.0/20 X-Spam-Status: No, score=-1.9 required=3.0 tests=AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: normalperson@yhbt.net Received: from zedshaw2.xen.prgmr.com (zedshaw2.xen.prgmr.com [71.19.156.177]) by dcvr.yhbt.net (Postfix) with ESMTP id 7146A1F44D for ; Fri, 3 May 2013 01:20:14 +0000 (UTC) Received: from zedshaw2.xen.prgmr.com (unknown [IPv6:::1]) by zedshaw2.xen.prgmr.com (Postfix) with ESMTP id 8A55873D9F for ; Fri, 3 May 2013 01:22:25 +0000 (UTC) MIME-Version: 1.0 Date: Fri, 3 May 2013 01:20:03 +0000 From: Eric Wong In-Reply-To: <1367544006-11148-1-git-send-email-normalperson@yhbt.net> List-Archive: List-Help: List-Id: List-Post: List-Subscribe: List-Unsubscribe: Message-Id: <1367544006-11148-1-git-send-email-normalperson@yhbt.net> Precedence: list References: <1367544006-11148-1-git-send-email-normalperson@yhbt.net> Sender: sleepy.penguin@librelist.org Subject: [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation To: sleepy.penguin@librelist.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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