From: Eric Wong <normalperson@yhbt.net>
To: sleepy.penguin@librelist.org
Subject: [sleepy.penguin] [PATCH 1/4] doc: flesh out kqueue-related documentation
Date: Fri, 3 May 2013 01:20:03 +0000 [thread overview]
Message-ID: <1367544006-11148-1-git-send-email-normalperson@yhbt.net> (raw)
In-Reply-To: <1367544006-11148-1-git-send-email-normalperson@yhbt.net>
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
next parent reply other threads:[~2013-05-03 1:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-03 1:20 Eric Wong [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/sleepy_penguin/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1367544006-11148-1-git-send-email-normalperson@yhbt.net \
--to=normalperson@yhbt.net \
--cc=sleepy.penguin@librelist.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).