Hi
I've managed to fix a working fcntl implementation that sets nonblocking io
when asked to. Patch is attached.
This makes a simple daytime server work flawlessly.
When I scale this up and try something like this:
require 'webrick'
include WEBrick
s = HTTPServer.new(
:Port => 2000,
:DocumentRoot => %q(d:\web\htdocs)
)
trap("INT"){ s.shutdown }
s.start
... we get into trouble again. Guess what it is?
java.lang.RuntimeException: java.lang.InterruptedException
at org.jruby.RubyThread.criticalizeOrDieIfKilled(RubyThread.java:293)
at org.jruby.RubyThread.pollThreadEvents(RubyThread.java:278)
at
org.jruby.runtime.ThreadContext.pollThreadEvents(ThreadContext.java:471)
at
org.jruby.evaluator.EvaluationState.executeNext(EvaluationState.java:257)
at org.jruby.evaluator.EvaluationState.begin(EvaluationState.java:297)
at
org.jruby.internal.runtime.methods.EvaluateCallable.internalCall(EvaluateCallable.java:67)
at
org.jruby.internal.runtime.methods.AbstractCallable.call(AbstractCallable.java:64)
at org.jruby.runtime.ThreadContext.yield(ThreadContext.java:347)
at org.jruby.runtime.Block.call(Block.java:114)
at org.jruby.RubyProc.call(RubyProc.java:118)
at org.jruby.RubyProc.call(RubyProc.java:104)
at
org.jruby.internal.runtime.RubyNativeThread.run(RubyNativeThread.java:75)
Caused by: java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:429)
at org.jruby.RubyThread.waitIfCriticalized(RubyThread.java:260)
at org.jruby.RubyThread.criticalizeOrDieIfKilled(RubyThread.java:290)
... 11 more
Our old friend. The server actually does work, but sillyness slow, even on
a localhost. Maybe some uses of timeout here too? Doesn't seem to be in the
relevant parts, actually, but there is obviously something strange going on...
Anyway, fcntl takes us one step further.
Regards
Ola Bini
Index: src/org/jruby/runtime/builtin/meta/IOMetaClass.java
===================================================================
RCS file:
/cvsroot/jruby/jruby/src/org/jruby/runtime/builtin/meta/IOMetaClass.java,v
retrieving revision 1.18
diff -u -r1.18 IOMetaClass.java
--- src/org/jruby/runtime/builtin/meta/IOMetaClass.java 26 May 2006 01:47:52
-0000 1.18
+++ src/org/jruby/runtime/builtin/meta/IOMetaClass.java 13 Jun 2006 11:34:47
-0000
@@ -95,6 +95,7 @@
defineMethod("each_line", Arity.optional());
defineMethod("eof", Arity.noArguments());
defineAlias("eof?", "eof");
+ defineMethod("fcntl", Arity.twoArguments());
defineMethod("fileno", Arity.noArguments());
defineMethod("flush", Arity.noArguments());
defineMethod("fsync", Arity.noArguments());
Index: src/org/jruby/RubyIO.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyIO.java,v
retrieving revision 1.52
diff -u -r1.52 RubyIO.java
--- src/org/jruby/RubyIO.java 24 May 2006 01:34:03 -0000 1.52
+++ src/org/jruby/RubyIO.java 13 Jun 2006 11:47:55 -0000
@@ -40,6 +40,7 @@
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.nio.channels.Channel;
+import java.nio.channels.SelectableChannel;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.IOHandler;
@@ -806,6 +807,31 @@
return result;
}
+ public IRubyObject fcntl(final IRubyObject cmd, final IRubyObject arg)
throws IOException {
+ if(arg instanceof RubyNumeric) {
+ final long realCmd = ((RubyNumeric)cmd).getLongValue();
+ final long realArg = ((RubyNumeric)arg).getLongValue();
+ if(realCmd == 1L) {
+ // cmd is F_SETFL
+ boolean block = false;
+ if((realArg & IOModes.NONBLOCK) == IOModes.NONBLOCK) {
+ block = true;
+ }
+ final Channel chn = getChannel();
+ if(chn != null && chn instanceof SelectableChannel) {
+ try {
+ ((SelectableChannel)chn).configureBlocking(block);
+ } catch(final IOException e) {
+ throw getRuntime().newIOError(e.getMessage());
+ }
+ }
+ }
+ return RubyFixnum.zero(getRuntime());
+ } else {
+ return getRuntime().getNil();
+ }
+ }
+
public IRubyObject puts(IRubyObject[] args) {
checkArgumentCount(args, 0, -1);
Index: src/builtin/fcntl.rb
===================================================================
RCS file: /cvsroot/jruby/jruby/src/builtin/fcntl.rb,v
retrieving revision 1.1
diff -u -r1.1 fcntl.rb
--- src/builtin/fcntl.rb 23 Nov 2005 10:55:36 -0000 1.1
+++ src/builtin/fcntl.rb 13 Jun 2006 11:42:58 -0000
@@ -0,0 +1,12 @@
+class Fcntl
+ F_SETFL = 1
+ O_RDWR = File::RDWR
+ O_TRUNC = File::TRUNC
+ O_RDONLY = File::RDONLY
+ O_EXCL = File::EXCL
+ O_ACCMODE = File::NOCTTY
+ O_NONBLOCK = File::NONBLOCK
+ O_CREAT = File::CREAT
+ O_WRONLY = File::WRONLY
+ O_APPEND = File::APPEND
+end
_______________________________________________
Jruby-devel mailing list
Jruby-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jruby-devel