Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
More missing bits transplanted from DL.
  • Loading branch information
headius committed Jan 14, 2015
1 parent f129eab commit 0e8e197
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 20 deletions.
50 changes: 31 additions & 19 deletions core/src/main/java/org/jruby/RubyThread.java
Expand Up @@ -38,6 +38,7 @@
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Collections;
import java.util.Iterator;
import java.util.Queue;
import java.util.Vector;
Expand Down Expand Up @@ -104,32 +105,32 @@ public class RubyThread extends RubyObject implements ExecutionContext {
private static final Logger LOG = LoggerFactory.getLogger("RubyThread");

/** The thread-like think that is actually executing */
private ThreadLike threadImpl;
private volatile ThreadLike threadImpl;

/** Normal thread-local variables */
private transient Map<IRubyObject, IRubyObject> threadLocalVariables;
private volatile transient Map<IRubyObject, IRubyObject> threadLocalVariables;

/** Context-local variables, internal-ish thread locals */
private final Map<Object, IRubyObject> contextVariables = new WeakHashMap<Object, IRubyObject>();

/** Whether this thread should try to abort the program on exception */
private boolean abortOnException;
private volatile boolean abortOnException;

/** The final value resulting from the thread's execution */
private IRubyObject finalResult;
private volatile IRubyObject finalResult;

/**
* The exception currently being raised out of the thread. We reference
* it here to continue propagating it while handling thread shutdown
* logic and abort_on_exception.
*/
private RaiseException exitingException;
private volatile RaiseException exitingException;

/** The ThreadGroup to which this thread belongs */
private RubyThreadGroup threadGroup;
private volatile RubyThreadGroup threadGroup;

/** Per-thread "current exception" */
private IRubyObject errorInfo;
private volatile IRubyObject errorInfo;

/** Weak reference to the ThreadContext for this thread. */
private volatile WeakReference<ThreadContext> contextRef;
Expand All @@ -138,14 +139,14 @@ public class RubyThread extends RubyObject implements ExecutionContext {
private volatile boolean handleInterrupt = true;

/** Stack of interrupt masks active for this thread */
private final List<RubyHash> interruptMaskStack = new ArrayList<RubyHash>();
private final List<RubyHash> interruptMaskStack = Collections.synchronizedList(new ArrayList<RubyHash>());

/** Thread-local tuple used for sleeping (semaphore, millis, nanos) */
private final SleepTask2 sleepTask = new SleepTask2();

private static final boolean DEBUG = false;
private int RUBY_MIN_THREAD_PRIORITY = -3;
private int RUBY_MAX_THREAD_PRIORITY = 3;
private static final int RUBY_MIN_THREAD_PRIORITY = -3;
private static final int RUBY_MAX_THREAD_PRIORITY = 3;

/** Thread statuses */
public static enum Status {
Expand All @@ -165,10 +166,10 @@ public static enum Status {
private final Queue<IRubyObject> pendingInterruptQueue = new ConcurrentLinkedQueue();

/** A function to use to unblock this thread, if possible */
private Unblocker unblockFunc;
private volatile Unblocker unblockFunc;

/** Argument to pass to the unblocker */
private Object unblockArg;
private volatile Object unblockArg;

/** The list of locks this thread currently holds, so they can be released on exit */
private final List<Lock> heldLocks = new Vector<Lock>();
Expand Down Expand Up @@ -1247,22 +1248,33 @@ public void wakeup() {
}
}

/**
* A Task for sleeping.
*
* The Semaphore is immediately drained on construction, so that any subsequent acquire will block.
* The sleep is interrupted by releasing a permit. All permits are drained again on exit to ensure
* the next sleep blocks.
*/
private class SleepTask2 implements Task<Object, Long> {
final Semaphore semaphore = new Semaphore(1);
long millis;
{ try {semaphore.acquire();} catch (InterruptedException ie){} }
{semaphore.drainPermits();}

@Override
public Long run(ThreadContext context, Object data) throws InterruptedException {
long start = System.currentTimeMillis();

if (millis == 0) {
semaphore.acquire();
} else {
semaphore.tryAcquire(millis, TimeUnit.MILLISECONDS);
}
try {
if (millis == 0) {
semaphore.acquire();
} else {
semaphore.tryAcquire(millis, TimeUnit.MILLISECONDS);
}

return System.currentTimeMillis() - start;
return System.currentTimeMillis() - start;
} finally {
semaphore.drainPermits();
}
}

@Override
Expand Down
22 changes: 21 additions & 1 deletion lib/ruby/stdlib/fiddle.rb
Expand Up @@ -67,11 +67,13 @@ def dlopen library
end
module_function :dlopen

class DLError < StandardError; end

class Handle
RTLD_GLOBAL = FFI::DynamicLibrary::RTLD_GLOBAL
RTLD_LAZY = FFI::DynamicLibrary::RTLD_LAZY
RTLD_NOW = FFI::DynamicLibrary::RTLD_NOW

def initialize(libname = nil, flags = RTLD_LAZY | RTLD_GLOBAL)
@lib = FFI::DynamicLibrary.open(libname, flags)
raise RuntimeError, "Could not open #{libname}" unless @lib
Expand Down Expand Up @@ -124,6 +126,24 @@ def disable_close
end
end

ALIGN_VOIDP = Fiddle::JRuby::FFITypes[TYPE_VOIDP].alignment
ALIGN_CHAR = Fiddle::JRuby::FFITypes[TYPE_CHAR].alignment
ALIGN_SHORT = Fiddle::JRuby::FFITypes[TYPE_SHORT].alignment
ALIGN_INT = Fiddle::JRuby::FFITypes[TYPE_INT].alignment
ALIGN_LONG = Fiddle::JRuby::FFITypes[TYPE_LONG].alignment
ALIGN_LONG_LONG = Fiddle::JRuby::FFITypes[TYPE_LONG_LONG].alignment
ALIGN_FLOAT = Fiddle::JRuby::FFITypes[TYPE_FLOAT].alignment
ALIGN_DOUBLE = Fiddle::JRuby::FFITypes[TYPE_DOUBLE].alignment

SIZEOF_VOIDP = Fiddle::JRuby::FFITypes[TYPE_VOIDP].size
SIZEOF_CHAR = Fiddle::JRuby::FFITypes[TYPE_CHAR].size
SIZEOF_SHORT = Fiddle::JRuby::FFITypes[TYPE_SHORT].size
SIZEOF_INT = Fiddle::JRuby::FFITypes[TYPE_INT].size
SIZEOF_LONG = Fiddle::JRuby::FFITypes[TYPE_LONG].size
SIZEOF_LONG_LONG = Fiddle::JRuby::FFITypes[TYPE_LONG_LONG].size
SIZEOF_FLOAT = Fiddle::JRuby::FFITypes[TYPE_FLOAT].size
SIZEOF_DOUBLE = Fiddle::JRuby::FFITypes[TYPE_DOUBLE].size

# Add constants for backwards compat

RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc:
Expand Down

0 comments on commit 0e8e197

Please sign in to comment.