Skip to content

Commit

Permalink
Make sleep interrupts more robust by using Semaphore.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Dec 11, 2014
1 parent 540b635 commit 39996ef
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions core/src/main/java/org/jruby/RubyThread.java
Expand Up @@ -63,9 +63,12 @@

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;

import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.ClassIndex;
Expand Down Expand Up @@ -1152,7 +1155,9 @@ public synchronized IRubyObject run() {
*/
public boolean sleep(long millis) throws InterruptedException {
assert this == getRuntime().getCurrentContext().getThread();
if (executeTask(getContext(), new Object[]{this, millis, 0}, SLEEP_TASK2) >= millis) {
Semaphore sem = new Semaphore(1);
sem.acquire();
if (executeTask(getContext(), new Object[]{sem, millis, 0}, SLEEP_TASK2) >= millis) {
return true;
} else {
return false;
Expand Down Expand Up @@ -1221,20 +1226,22 @@ public void wakeup() {
private static final class SleepTask2 implements Task<Object[], Long> {
@Override
public Long run(ThreadContext context, Object[] data) throws InterruptedException {
Object syncObj = data[0];
long millis = (Long)data[1];
int nanos = (Integer)data[2];
synchronized (syncObj) {
long start = System.currentTimeMillis();
syncObj.wait(millis, nanos);
// TODO: nano handling?
return System.currentTimeMillis() - start;

long start = System.currentTimeMillis();
// TODO: nano handling?
if (millis == 0) {
((Semaphore) data[0]).acquire();
} else {
((Semaphore) data[0]).tryAcquire(millis, TimeUnit.MILLISECONDS);
}
return System.currentTimeMillis() - start;
}

@Override
public void wakeup(RubyThread thread, Object[] data) {
thread.getNativeThread().interrupt();
((Semaphore)data[0]).release();
}
}

Expand Down

0 comments on commit 39996ef

Please sign in to comment.