about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-03-21 10:46:58 -0700
committerEric Wong <normalperson@yhbt.net>2011-03-21 10:46:58 -0700
commita5d552d90942fe3c3d1adfc809638fd78992da6e (patch)
treecaa28dc285e39c787ec1d4a291470679b7c80c8c
parentf86b02018a4195e199136eb0bd8d127d01cae154 (diff)
downloadraindrops-a5d552d90942fe3c3d1adfc809638fd78992da6e.tar.gz
It can detect cross-thread close() calls
-rw-r--r--ext/raindrops/extconf.rb1
-rw-r--r--ext/raindrops/linux_inet_diag.c9
2 files changed, 8 insertions, 2 deletions
diff --git a/ext/raindrops/extconf.rb b/ext/raindrops/extconf.rb
index 08b5f44..141722d 100644
--- a/ext/raindrops/extconf.rb
+++ b/ext/raindrops/extconf.rb
@@ -10,6 +10,7 @@ $CPPFLAGS += " -D_BSD_SOURCE -D_XOPEN_SOURCE=600 "
 have_func("getpagesize", "unistd.h")
 have_func("rb_struct_alloc_noinit")
 have_func('rb_thread_blocking_region')
+have_func('rb_thread_io_blocking_region')
 
 checking_for "GCC 4+ atomic builtins" do
   src = <<SRC
diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c
index f43a8c9..7fef77c 100644
--- a/ext/raindrops/linux_inet_diag.c
+++ b/ext/raindrops/linux_inet_diag.c
@@ -32,6 +32,11 @@ rb_thread_blocking_region(
 }
 #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
 
+#ifndef HAVE_RB_THREAD_IO_BLOCKING_REGION
+#  define rb_thread_io_blocking_region(fn,data,fd) \
+      rb_thread_blocking_region((fn),(data),RUBY_UBF_IO,0)
+#endif /* HAVE_RB_THREAD_IO_BLOCKING_REGION */
+
 #include <assert.h>
 #include <errno.h>
 #include <sys/socket.h>
@@ -543,7 +548,7 @@ static VALUE tcp_stats(struct nogvl_args *args, VALUE addr)
         gen_bytecode(&args->iov[2], &query_addr);
 
         memset(&args->stats, 0, sizeof(struct listen_stats));
-        nl_errcheck(rb_thread_blocking_region(diag, args, 0, 0));
+        nl_errcheck(rb_thread_io_blocking_region(diag, args, args->fd));
 
         return rb_listen_stats(&args->stats);
 }
@@ -610,7 +615,7 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
                          "addr must be an array of strings, a string, or nil");
         }
 
-        nl_errcheck(rb_thread_blocking_region(diag, &args, NULL, 0));
+        nl_errcheck(rb_thread_io_blocking_region(diag, &args, args.fd));
 
         st_foreach(args.table, NIL_P(addrs) ? st_to_hash : st_AND_hash, rv);
         st_free_table(args.table);