Skip to content

Commit

Permalink
[Truffle] Fix the last failing Mutex spec.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Feb 4, 2015
1 parent af8e1c9 commit b2f4f39
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/mutex/locked_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyMutex;
import org.jruby.truffle.runtime.core.RubyThread;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;

import com.oracle.truffle.api.CompilerDirectives;
Expand Down Expand Up @@ -43,10 +44,13 @@ public RubyMutex lock(RubyMutex mutex) {
throw new RaiseException(getContext().getCoreLibrary().threadError("deadlock; recursive locking", this));
}

final RubyThread thread = getContext().getThreadManager().getCurrentThread();

getContext().getThreadManager().runUntilResult(new BlockingActionWithoutGlobalLock<Boolean>() {
@Override
public Boolean block() throws InterruptedException {
lock.lockInterruptibly();
thread.acquiredLock(lock);
return SUCCESS;
}
});
Expand Down Expand Up @@ -115,7 +119,13 @@ public boolean tryLock(RubyMutex mutex) {
return false;
}

return lock.tryLock();
if (lock.tryLock()) {
RubyThread thread = getContext().getThreadManager().getCurrentThread();
thread.acquiredLock(lock);
return true;
} else {
return false;
}
}

}
Expand All @@ -134,9 +144,11 @@ public UnlockNode(UnlockNode prev) {
@Specialization
public RubyMutex unlock(RubyMutex mutex) {
final ReentrantLock lock = mutex.getReentrantLock();
final RubyThread thread = getContext().getThreadManager().getCurrentThread();

try {
lock.unlock();
thread.releasedLock(lock);
} catch (IllegalMonitorStateException e) {
throw new RaiseException(getContext().getCoreLibrary().threadError("Attempt to unlock a mutex which is not locked", this));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
import org.jruby.truffle.runtime.subsystems.ThreadManager;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;

/**
* Represents the Ruby {@code Thread} class. Implemented using Java threads, but note that there is
Expand All @@ -42,6 +45,8 @@ public class RubyThread extends RubyBasicObject {

private RubyBasicObject threadLocals;

private List<Lock> ownedLocks = new ArrayList<Lock>();

public RubyThread(RubyClass rubyClass, ThreadManager manager) {
super(rubyClass);
this.manager = manager;
Expand Down Expand Up @@ -95,6 +100,7 @@ public void run() {
finalThread.finished.countDown();
status = Status.DEAD;
thread = null;
releaseOwnedLocks();
}
}

Expand Down Expand Up @@ -129,6 +135,23 @@ public void interrupt() {
}
}

public void acquiredLock(Lock lock) {
ownedLocks.add(lock);
}

public void releasedLock(Lock lock) {
RubyNode.notDesignedForCompilation();

// TODO: this is O(ownedLocks.length).
ownedLocks.remove(lock);
}

protected void releaseOwnedLocks() {
for (Lock lock : ownedLocks) {
lock.unlock();
}
}

public Status getStatus() {
return status;
}
Expand Down

0 comments on commit b2f4f39

Please sign in to comment.