Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * To change this template, choose Tools | Templates
   * and open the template in the editor.
   */
  package org.jruby.ext.fiber;
  
  import  java.dyn.Coroutine;
  import org.jruby.Ruby;

Author(s):
headius
 
 @JRubyClass(name = "Fiber")
 public class CoroutineFiber extends Fiber {
     private volatile IRubyObject slot;
     private CoroutineFiberState state;
     private CoroutineFiber lastFiber;
     private Coroutine coro;
     private ThreadContext context;
     private JumpException coroException;
 
     public CoroutineFiber(Ruby runtimeRubyClass type, Coroutine coro) {
         super(runtimetype);
         this. = coro != null;
         this. = coro;
         assert  ^ runtime.getCurrentContext().getFiber() != null;
     }
     
     protected void initFiber(ThreadContext context) {
         final Ruby runtime = context.runtime;
         
         this. = runtime.getNil();
         this. =  ? context : ThreadContext.newContext(runtime);
         this..setFiber(this);
         this..setThread(context.getThread());
 
         this. = .;
         if ( == null) {
              = new Coroutine() {
 
                 @Override
                 protected void run() {
                     try {
                         // first resume, dive into the block
                          = .yieldArray(CoroutineFiber.this.nullnull);
                     } catch (JumpException t) {
                          = t;
                     } finally {
                          = .;
                     }
                 }
             };
         }
     }
 
     protected IRubyObject resumeOrTransfer(ThreadContext contextIRubyObject argboolean transfer) {
         CoroutineFiber current = (CoroutineFiber)context.getFiber();
         Ruby runtime = context.runtime;
          = arg;
 
         if (context.getThread() != ) {
             throw context.runtime.newFiberError("resuming fiber from different thread: " + this);
         }
 
         switch () {
             case :
                 if (transfer) {
                     current.state = .;
                 } else {
                     current.state = .;
                      = (CoroutineFiber)context.getFiber();
                 }
                  = .;
                 runtime.getThreadService().setCurrentContext(context);
                 context.setThread(context.getThread());
                 Coroutine.yieldTo();
                 break;
             case :
                 if (!transfer) {
                     throw runtime.newFiberError("double resume");
                 }
                 current.state = .;
                  = .;
                 runtime.getThreadService().setCurrentContext(context);
                 context.setThread(context.getThread());
                 Coroutine.yieldTo();
                 break;
             case :
                 throw runtime.newFiberError("dead fiber called");
             default:
                throw runtime.newFiberError("fiber in an invalid state: " + );
        }
        try {
            if ( != null) {
                throw ;
            }
        } catch (JumpException.RetryJump rtry) {
            // FIXME: technically this should happen before the block is executed
            context.getThread().raise(new IRubyObject[]{runtime.newSyntaxError("Invalid retry").getException()}, .);
        } catch (JumpException.BreakJump brk) {
            context.getThread().raise(new IRubyObject[]{runtime.newLocalJumpError(.runtime.getNil(), "break from proc-closure").getException()}, .);
        } catch (JumpException.ReturnJump ret) {
            context.getThread().raise(new IRubyObject[]{runtime.newLocalJumpError(.runtime.getNil(), "unexpected return").getException()}, .);
        }
        // back from fiber, poll events and proceed out of resume
        context.pollThreadEvents();
        return ;
    }
    public IRubyObject yield(ThreadContext contextIRubyObject arg) {
        assert !;
            if (. == .) {
                throw context.runtime.newFiberError("a Fiber that was transferred to cannot yield");
            }
            throw context.runtime.newFiberError("invalid state of last Fiber at yield: " + .);
        }
         = arg;
        context.runtime.getThreadService().setCurrentContext(.);
        Object o = .;
        ..setThread(context.getThread());
        Coroutine.yieldTo(.);
        // back from fiber, poll events and proceed out of resume
        context.pollThreadEvents();
        return ;
    }
    
    public boolean isAlive() {
        return  != .;
    }
    
New to GrepCode? Check out our FAQ X