[前][次][番号順一覧][スレッド一覧]

ruby-changes:18989

From: kosaki <ko1@a...>
Date: Sat, 5 Mar 2011 01:38:45 +0900 (JST)
Subject: [ruby-changes:18989] Ruby:r31025 (trunk): * io.c (io_cntl, nogvl_io_cntl): IO.fcntl() and IO.ioctl()

kosaki	2011-03-05 01:38:34 +0900 (Sat, 05 Mar 2011)

  New Revision: 31025

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31025

  Log:
    * io.c (io_cntl, nogvl_io_cntl): IO.fcntl() and IO.ioctl()
      release GVL during calling kernel interface.
      Suggested by Eric Wong. [ruby-core:35417][Bug #4463]
    
    * test/ruby/test_io.rb (TestIO#test_fcntl_lock): add new test for
      IO.fcntl().

  Modified files:
    trunk/ChangeLog
    trunk/io.c
    trunk/test/ruby/test_io.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31024)
+++ ChangeLog	(revision 31025)
@@ -1,3 +1,12 @@
+Sat Mar  5 01:33:46 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* io.c (io_cntl, nogvl_io_cntl): IO.fcntl() and IO.ioctl()
+	  release GVL during calling kernel interface.
+	  Suggested by Eric Wong. [ruby-core:35417][Bug #4463]
+
+	* test/ruby/test_io.rb (TestIO#test_fcntl_lock): add new test for
+	  IO.fcntl().
+
 Fri Mar  4 23:09:12 2011  CHIKANAGA Tomoyuki  <nagachika00@g...>
 
 	* test/testunit/test_parallel.rb
Index: io.c
===================================================================
--- io.c	(revision 31024)
+++ io.c	(revision 31025)
@@ -7649,28 +7649,47 @@
 
 }
 
+struct io_cntl_arg {
+    int		fd;
+    int		cmd;
+    long	narg;
+    int		io_p;
+};
+
+static VALUE nogvl_io_cntl(void *ptr)
+{
+    struct io_cntl_arg *arg = ptr;
+
+    if (arg->io_p)
+	return (VALUE)ioctl(arg->fd, arg->cmd, arg->narg);
+    else
+	return (VALUE)fcntl(arg->fd, arg->cmd, arg->narg);
+}
+
 static int
 io_cntl(int fd, int cmd, long narg, int io_p)
 {
     int retval;
+    struct io_cntl_arg arg;
 
-#ifdef HAVE_FCNTL
-# if defined(__CYGWIN__)
-    retval = io_p?ioctl(fd, cmd, (void*)narg):fcntl(fd, cmd, narg);
-# else
-    retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg);
-# endif
-# if defined(F_DUPFD)
-    if (!io_p && retval != -1 && cmd == F_DUPFD) {
-        UPDATE_MAXFD(retval);
-    }
-# endif
-#else
+#ifndef HAVE_FCNTL
     if (!io_p) {
 	rb_notimplement();
     }
-    retval = ioctl(fd, cmd, narg);
 #endif
+
+    arg.fd = fd;
+    arg.cmd = cmd;
+    arg.narg = narg;
+    arg.io_p = io_p;
+
+    retval = (int)rb_thread_blocking_region(nogvl_io_cntl, &arg, RUBY_UBF_IO, 0);
+#if defined(F_DUPFD)
+    if (!io_p && retval != -1 && cmd == F_DUPFD) {
+	UPDATE_MAXFD(retval);
+    }
+#endif
+
     return retval;
 }
 
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 31024)
+++ test/ruby/test_io.rb	(revision 31025)
@@ -1776,4 +1776,38 @@
       end
     end
   end
+
+
+  if /x86_64-linux/ =~ RUBY_PLATFORM # A binary form of struct flock depend on platform
+    F_WRLCK = 1
+    F_UNLCK = 2
+    SEEK_SET = 0
+
+    def test_fcntl_lock
+      pad = 0
+      flocktype = "s!s!s!s!L!L!i!"
+
+      Tempfile.open(self.class.name) do |f|
+        r, w = IO.pipe
+        pid = fork do
+          r.close
+          lock = [F_WRLCK, SEEK_SET, pad, pad, 0, 0, 0].pack(flocktype)
+          f.fcntl Fcntl::F_SETLKW, lock
+          w.syswrite "."
+          sleep
+        end
+        w.close
+        assert_equal ".", r.read(1)
+        r.close
+        pad = 0
+        getlock = [F_WRLCK, 0, pad, pad, 0, 0, 0].pack(flocktype)
+        f.fcntl Fcntl::F_GETLK, getlock
+
+        ptype, whence, pad, pad, start, len, lockpid = getlock.unpack(flocktype)
+        assert_equal(pid, lockpid)
+        Process.kill :TERM, pid
+        Process.waitpid2(pid)
+      end
+    end
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]