@JRubyMethod(rest = true, visibility = PRIVATE)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
    Ruby runtime = getRuntime();
    if (!block.isGiven()) throw runtime.newThreadError("must be called with a block");
    if (threadImpl != null) throw runtime.newThreadError("already initialized thread");

    RubyRunnable runnable = new RubyRunnable(this, args, block);

    return startWith(runnable);
  }
Exemplo n.º 2
0
  @JRubyMethod(rest = true, visibility = PRIVATE)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) {
    Ruby runtime = getRuntime();
    if (!block.isGiven()) throw runtime.newThreadError("must be called with a block");

    try {
      RubyRunnable runnable = new RubyRunnable(this, args, context.getFrames(0), block);
      if (RubyInstanceConfig.POOLING_ENABLED) {
        FutureThread futureThread = new FutureThread(this, runnable);
        threadImpl = futureThread;

        addToCorrectThreadGroup(context);

        threadImpl.start();

        // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(futureThread.getFuture(), this);
      } else {
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);
        thread.setName(
            "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1));
        threadImpl = new NativeThread(this, thread);

        addToCorrectThreadGroup(context);

        // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(thread, this);

        threadImpl.start();
      }

      // We yield here to hopefully permit the target thread to schedule
      // MRI immediately schedules it, so this is close but not exact
      Thread.yield();

      return this;
    } catch (OutOfMemoryError oome) {
      if (oome.getMessage().equals("unable to create new native thread")) {
        throw runtime.newThreadError(oome.getMessage());
      }
      throw oome;
    } catch (SecurityException ex) {
      throw runtime.newThreadError(ex.getMessage());
    }
  }
  private IRubyObject startWith(ThreadedRunnable runnable) throws RaiseException, OutOfMemoryError {
    Ruby runtime = getRuntime();
    ThreadContext context = runtime.getCurrentContext();

    try {
      if (RubyInstanceConfig.POOLING_ENABLED) {
        FutureThread futureThread = new FutureThread(this, runnable);
        threadImpl = futureThread;

        addToCorrectThreadGroup(context);

        threadImpl.start();

        // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(futureThread.getFuture(), this);
      } else {
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);
        thread.setName(
            "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1));
        threadImpl = new NativeThread(this, thread);

        addToCorrectThreadGroup(context);

        // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it
        // doesn't run immediately
        runtime.getThreadService().associateThread(thread, this);

        threadImpl.start();
      }

      // We yield here to hopefully permit the target thread to schedule
      // MRI immediately schedules it, so this is close but not exact
      Thread.yield();

      return this;
    } catch (OutOfMemoryError oome) {
      if (oome.getMessage().equals("unable to create new native thread")) {
        throw runtime.newThreadError(oome.getMessage());
      }
      throw oome;
    } catch (SecurityException ex) {
      throw runtime.newThreadError(ex.getMessage());
    }
  }