Skip to content

Instantly share code, notes, and snippets.

@headius
Created April 16, 2013 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/5393700 to your computer and use it in GitHub Desktop.
Save headius/5393700 to your computer and use it in GitHub Desktop.
Switching Kernel#sleep to use java.lang.Thread.sleep; does not pass tests yet.
diff --git a/src/org/jruby/RubyKernel.java b/src/org/jruby/RubyKernel.java
index e34e625..5a48e28 100644
--- a/src/org/jruby/RubyKernel.java
+++ b/src/org/jruby/RubyKernel.java
@@ -772,7 +772,7 @@ public class RubyKernel {
}
@JRubyMethod(optional = 1, module = true, visibility = PRIVATE)
- public static IRubyObject sleep(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
+ public static IRubyObject sleep(ThreadContext context, IRubyObject recv, IRubyObject[] args) throws InterruptedException {
long milliseconds;
if (args.length == 0) {
@@ -794,16 +794,7 @@ public class RubyKernel {
RubyThread rubyThread = context.getThread();
- // Spurious wakeup-loop
- do {
- long loopStartTime = System.currentTimeMillis();
- try {
- // We break if we know this sleep was explicitly woken up/interrupted
- if (!rubyThread.sleep(milliseconds)) break;
- } catch (InterruptedException iExcptn) {
- }
- milliseconds -= (System.currentTimeMillis() - loopStartTime);
- } while (milliseconds > 0);
+ rubyThread.sleep(milliseconds);
return context.runtime.newFixnum(Math.round((System.currentTimeMillis() - startTime) / 1000.0));
}
diff --git a/src/org/jruby/RubyThread.java b/src/org/jruby/RubyThread.java
index bd27b34..6e800bf 100644
--- a/src/org/jruby/RubyThread.java
+++ b/src/org/jruby/RubyThread.java
@@ -930,21 +930,9 @@ public class RubyThread extends RubyObject implements ExecutionContext {
assert this == getRuntime().getCurrentContext().getThread();
boolean result = true;
- synchronized (this) {
- pollThreadEvents();
- try {
- status.set(Status.SLEEP);
- if (millis == -1) {
- wait();
- } else {
- wait(millis);
- }
- } finally {
- result = (status.get() != Status.RUN);
- pollThreadEvents();
- status.set(Status.RUN);
- }
- }
+ if (millis == -1) millis = Long.MAX_VALUE;
+
+ executeBlockingTask(new ThreadSleepTask(Thread.currentThread(), millis, 0));
return result;
}
@@ -996,6 +984,26 @@ public class RubyThread extends RubyObject implements ExecutionContext {
}
}
+ public static final class ThreadSleepTask implements BlockingTask {
+ private final Thread thread;
+ private final long millis;
+ private final int nanos;
+
+ public ThreadSleepTask(Thread thread, long millis, int nanos) {
+ this.thread = thread;
+ this.millis = millis;
+ this.nanos = nanos;
+ }
+
+ public void run() throws InterruptedException {
+ Thread.sleep(millis, nanos);
+ }
+
+ public void wakeup() {
+ thread.interrupt();
+ }
+ }
+
public void executeBlockingTask(BlockingTask task) throws InterruptedException {
enterSleep();
try {
diff --git a/test/externals/ruby1.9/ruby/test_signal.rb b/test/externals/ruby1.9/ruby/test_signal.rb
index c226fdd..501614e 100644
--- a/test/externals/ruby1.9/ruby/test_signal.rb
+++ b/test/externals/ruby1.9/ruby/test_signal.rb
@@ -17,7 +17,7 @@ class TestSignal < Test::Unit::TestCase
return unless Process.respond_to?(:kill)
begin
x = 0
- oldtrap = Signal.trap(:INT) {|sig| x = 2 }
+ oldtrap = Signal.trap(:INT) {|sig| p 'here'; x = 2 }
Process.kill :INT, Process.pid
10.times do
break if 2 == x
@@ -25,11 +25,14 @@ class TestSignal < Test::Unit::TestCase
end
assert_equal 2, x
- Signal.trap(:INT) { raise "Interrupt" }
+ Signal.trap(:INT) { p 'there'; raise "Interrupt" }
ex = assert_raise(RuntimeError) {
+ p 'in'
Process.kill :INT, Process.pid
sleep 0.1
+ p 'leaving'
}
+ p 'out'
assert_kind_of Exception, ex
assert_match(/Interrupt/, ex.message)
ensure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment