boolean alive() {
return thread != null && thread.isAlive() && !data.queue.isShutdown();
}
static RubyThread createThread(final Ruby runtime, final FiberData data, final SizedQueue queue, final Block block) {
final AtomicReference<RubyThread> fiberThread = new AtomicReference();
runtime.getFiberExecutor().execute(new Runnable() {
public void run() {
ThreadContext context = runtime.getCurrentContext();
context.setFiber(data.fiber.get());
context.setRootThread(data.parent);
fiberThread.set(context.getThread());
IRubyObject init = data.queue.pop(context);
try {
try {
IRubyObject result;
if (init == NEVER) {
result = block.yieldSpecific(context);
} else {
result = block.yieldArray(context, init, null);
}
data.prev.data.queue.push(context, new IRubyObject[] { result });
} finally {
data.queue.shutdown();
runtime.getThreadService().disposeCurrentThread();
}
} catch (JumpException.FlowControlException fce) {
if (data.prev != null) {
data.prev.thread.raise(fce.buildException(runtime).getException());
}
} catch (IRBreakJump bj) {
// This is one of the rare cases where IR flow-control jumps
// leaks into the runtime impl.
if (data.prev != null) {
data.prev.thread.raise(((RaiseException)IRException.BREAK_LocalJumpError.getException(runtime)).getException());
}
} catch (IRReturnJump rj) {
// This is one of the rare cases where IR flow-control jumps
// leaks into the runtime impl.
if (data.prev != null) {
data.prev.thread.raise(((RaiseException)IRException.RETURN_LocalJumpError.getException(runtime)).getException());
}
} catch (RaiseException re) {
if (data.prev != null) {
data.prev.thread.raise(re.getException());
}
} catch (Throwable t) {
if (data.prev != null) {
data.prev.thread.raise(JavaUtil.convertJavaToUsableRubyObject(runtime, t));
}
} finally {
// clear reference to the fiber's thread
ThreadFiber tf = data.fiber.get();
if (tf != null) tf.thread = null;
}
}
});
while (fiberThread.get() == null) {Thread.yield();}
return fiberThread.get();
}