BEGIN LICENSE BLOCK *****
Version: EPL 1.0/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Eclipse Public
License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.eclipse.org/legal/epl-v10.html
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
Copyright (C) 2002 Jason Voegele <jason@jvoegele.com>
Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
Alternatively, the contents of this file may be used under the terms of
either of the GNU General Public License Version 2 or later (the "GPL"),
or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the EPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the EPL, the GPL or the LGPL.
END LICENSE BLOCK ***
import static org.jruby.runtime.Visibility.*;
import static org.jruby.CompatVersion.*;
Implementation of Ruby's
Thread
class. Each Ruby thread is
mapped to an underlying Java Virtual Machine thread.
Thread encapsulates the behavior of a thread of execution, including the main
thread of the Ruby script. In the descriptions that follow, the parameter
aSymbol
refers to a symbol, which is either a quoted string or a
Symbol
(such as :name
).
Note: For CVS history, see ThreadClass.java.
The thread-like think that is actually executing
Normal thread-local variables
Context-local variables, internal-ish thread locals
Whether this thread should try to abort the program on exception
The final value resulting from the thread's execution
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.
The ThreadGroup to which this thread belongs
Per-thread "current exception"
Weak reference to the ThreadContext for this thread.
private static final boolean DEBUG = false;
RUN, SLEEP, ABORTING, DEAD;
Current status in an atomic reference
Mail slot for cross-thread events
The current task blocking a thread, to allow interrupting it in an appropriate way
The list of locks this thread currently holds, so they can be released on exit
Whether or not this thread has been disposed of
private volatile boolean disposed = false;
The thread's initial priority, for use in thread pooled mode
Perform pre-execution tasks once the native thread is running, but we
have not yet called the Ruby code for the thread.
Dispose of the current thread by tidying up connections to other stuff
Thread.new
Thread.new( [ arg ]* ) {| args | block } -> aThread
Creates a new thread to execute the instructions given in block, and
begins running it. Any arguments passed to Thread.new are passed into the
block.
x = Thread.new { sleep .1; print "x"; print "y"; print "z" }
a = Thread.new { print "a"; print "b"; sleep .2; print "c" }
x.join # Let the threads finish before
a.join # main thread exits...
produces: abxyzc
@JRubyMethod(name = {"new", "fork"}, rest = true, meta = true)
Basically the same as Thread.new . However, if class Thread is
subclassed, then calling start in that subclass will not invoke the
subclass's initialize method.
public synchronized void beDead() {
Returns the status of the global ``abort on exception'' condition. The
default is false. When set to true, will cause all threads to abort (the
process will exit(0)) if an exception is raised in any thread. See also
Thread.abort_on_exception= .
@JRubyMethod(name = "abort_on_exception=", required = 1, meta = true)
@JRubyMethod(name = "abort_on_exception=", required = 1)
if (args.length > 0 && !args[0].isNil()) {
if (timeoutMillis <= 0) {
final long timeToWait = Math.min(timeoutMillis, 200);
synchronized (rubyThread) {
synchronized (rubyThread) {
rubyThread.mail.set(null);
int iPriority = RubyNumeric.fix2int(priority);
d = 1.5 * Math.sqrt(8.0*javaPriority + 41) - 13.5;
return Math.round((float) d);
d = Math.pow(rubyPriority, 2.0)/18.0 + 1.5 * rubyPriority + 5;
return Math.round((float) d);
Simplified utility method for just raising an existing exception in this
thread.
- Parameters:
exception
the exception to raise- Returns:
- this thread
debug(this, "before raising");
This is intended to be used to raise exceptions in Ruby threads from non-
Ruby threads like Timeout's thread.
- Parameters:
args
Same args as for Thread#raiseblock
Same as for Thread#raise
if(lastException.isNil()) {
exception = args[0].callMethod(context, "exception");
exception = args[0].callMethod(context, "exception", args[1]);
We can never be sure if a wait will finish because of a Java "spurious wakeup". So if we
explicitly wakeup and we wait less than requested amount we will return false. We will
return true if we sleep right amount or less than right amount via spurious wakeup.
return status(context.runtime);
debug(this, "trying to kill");
debug(this, "succeeded with kill");
Used for finalizers that need to kill a Ruby thread. Finalizers run in
a VM thread to which we do not want to attach a ThreadContext and within
which we do not want to check for Ruby thread events. This mechanism goes
directly to mail delivery, bypassing all Ruby Thread-related steps.
@JRubyMethod(name = {"kill!", "exit!", "terminate!"}, compat =