about summary refs log tree commit homepage
path: root/ext/kgio/autopush.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-01-31 17:05:48 -0800
committerEric Wong <normalperson@yhbt.net>2011-01-31 17:19:32 -0800
commit8a1fc65c88dee174940735bb46074c72ac47ce61 (patch)
treec9f3daabd6431fecbb302a9815c4e8d3e5006b09 /ext/kgio/autopush.c
parent6479b6d3934b8930910e0057f516aa019dd7a8c7 (diff)
downloadkgio-8a1fc65c88dee174940735bb46074c72ac47ce61.tar.gz
We know that all versions of MRI have a small RFile structure
that is allocated in the same object slots as other Ruby types
and also zeroed on allocation.

This optimization enables us to fall back to using ivars in
case MRI changes or if we're used on other Rubies.
Diffstat (limited to 'ext/kgio/autopush.c')
-rw-r--r--ext/kgio/autopush.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/ext/kgio/autopush.c b/ext/kgio/autopush.c
index fa24055..cc83fdb 100644
--- a/ext/kgio/autopush.c
+++ b/ext/kgio/autopush.c
@@ -38,6 +38,26 @@ enum autopush_state {
         AUTOPUSH_STATE_ACCEPTOR = 3
 };
 
+#if defined(R_CAST) && \
+    defined(HAVE_TYPE_STRUCT_RFILE) && \
+    defined(HAVE_TYPE_STRUCT_ROBJECT) && \
+    ((SIZEOF_STRUCT_RFILE + SIZEOF_INT) <= (SIZEOF_STRUCT_ROBJECT))
+
+struct AutopushSocket {
+        struct RFile rfile;
+        enum autopush_state autopush_state;
+};
+
+static enum autopush_state state_get(VALUE io)
+{
+        return ((struct AutopushSocket *)(io))->autopush_state;
+}
+
+static void state_set(VALUE io, enum autopush_state state)
+{
+        ((struct AutopushSocket *)(io))->autopush_state = state;
+}
+#else
 static enum autopush_state state_get(VALUE io)
 {
         VALUE val;
@@ -53,6 +73,7 @@ static void state_set(VALUE io, enum autopush_state state)
 {
         rb_ivar_set(io, id_autopush_state, INT2NUM(state));
 }
+#endif /* IVAR fallback */
 
 static enum autopush_state detect_acceptor_state(VALUE io);
 static void push_pending_data(VALUE io);