diff options
author | Eric Wong <normalperson@yhbt.net> | 2011-01-31 17:05:48 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-01-31 17:19:32 -0800 |
commit | 8a1fc65c88dee174940735bb46074c72ac47ce61 (patch) | |
tree | c9f3daabd6431fecbb302a9815c4e8d3e5006b09 | |
parent | 6479b6d3934b8930910e0057f516aa019dd7a8c7 (diff) | |
download | kgio-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.
-rw-r--r-- | ext/kgio/autopush.c | 21 | ||||
-rw-r--r-- | ext/kgio/extconf.rb | 8 |
2 files changed, 27 insertions, 2 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); diff --git a/ext/kgio/extconf.rb b/ext/kgio/extconf.rb index dcc1418..e7220a4 100644 --- a/ext/kgio/extconf.rb +++ b/ext/kgio/extconf.rb @@ -3,8 +3,9 @@ $CPPFLAGS << ' -D_GNU_SOURCE' have_func('accept4', %w(sys/socket.h)) if have_header('ruby/io.h') - have_struct_member("rb_io_t", "fd", "ruby/io.h") - have_struct_member("rb_io_t", "mode", "ruby/io.h") + rubyio = %w(ruby.h ruby/io.h) + have_struct_member("rb_io_t", "fd", rubyio) + have_struct_member("rb_io_t", "mode", rubyio) else rubyio = %w(ruby.h rubyio.h) rb_io_t = have_type("OpenFile", rubyio) ? "OpenFile" : "rb_io_t" @@ -13,6 +14,9 @@ else have_struct_member(rb_io_t, "mode", rubyio) have_func('rb_fdopen') end +have_type("struct RFile", rubyio) and check_sizeof("struct RFile", rubyio) +have_type("struct RObject") and check_sizeof("struct RObject") +check_sizeof("int") have_func('rb_io_ascii8bit_binmode') have_func('rb_thread_blocking_region') have_func('rb_str_set_len') |