Esempio n. 1
0
  @BIF
  public static EObject spawn_opt(EProc self, EObject tup) throws Pausable {
    ETuple t;
    EAtom m;
    EAtom f;
    ESeq a;
    ESeq o;
    if ((t = tup.testTuple()) == null
        || t.arity() != 4
        || (m = t.elm(1).testAtom()) == null
        || (f = t.elm(2).testAtom()) == null
        || (a = t.elm(3).testSeq()) == null
        || (o = t.elm(4).testSeq()) == null) throw ERT.badarg(tup);

    boolean link = false;
    boolean monitor = false;
    EAtom priority = null;

    for (; !o.isNil(); o = o.tail()) {
      EObject val = o.head();

      ETuple2 t2;
      if (val == am_link) {
        link = true;
      } else if (val == am_monitor) {
        monitor = true;
      } else if ((t2 = ETuple2.cast(val)) != null) {

        if (t2.elm(1) == am_priority) {
          EAtom am = t2.elm(2).testAtom();
          if (am != null) priority = am;
        }

        // ignore full_sweep_after and min_heap_size
      }
    }

    EProc p2 = new EProc(self.group_leader(), m, f, a);

    if (link) {
      self.link_to(p2);
    }

    if (priority != null) {
      // may throw badarg!
      p2.process_flag(am_priority, priority);
    }

    ERef ref = null;
    if (monitor) {
      ref = ERT.getLocalNode().createRef();

      if (!self.monitor(p2.self_handle(), p2.self_handle(), ref)) {
        throw new InternalError("cannot monitor new process?");
        // self.mbox_send(ETuple.make(ERT.am_DOWN, ref, p2.self_handle(), ERT.am_noproc));
      }
    }

    ERT.run(p2);

    if (monitor) {
      return new ETuple2(p2.self_handle(), ref);
    } else {
      return p2.self_handle();
    }
  }