Esempio n. 1
0
  @BIF
  public static EObject monitor(EProc self, EObject how, EObject object) throws Pausable {
    if (how != am_process) throw ERT.badarg(how, object);

    // case 1: object is a PID
    EHandle h = EHandle.cast(object);
    if (h != null) {
      ERef ref = ERT.getLocalNode().createRef();
      if (!self.monitor(h, h, ref)) {
        self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc));
      }
      return ref;
    }

    // case 2: object is a name
    EAtom name;
    if (h == null && (name = object.testAtom()) != null) {
      ERef ref = ERT.getLocalNode().createRef();
      boolean success = false;

      object = new ETuple2(name, ErlDist.node());

      if ((h = ERT.whereis(name).testHandle()) != null) {
        success = self.monitor(h, object, ref);
      }

      if (!success) {
        self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc));
      }

      return ref;
    }

    // case 3: object is {name, node}
    ETuple tup;
    EAtom node;
    if ((tup = object.testTuple()) != null
        && tup.arity() == 2
        && (name = tup.elm(1).testAtom()) != null
        && (node = tup.elm(2).testAtom()) != null) {
      if (node == ErlDist.node()) {

        ERef ref = ERT.getLocalNode().createRef();
        boolean success = false;

        if ((h = ERT.whereis(name).testHandle()) != null) {
          success = self.monitor(h, object, ref);
        }

        if (!success) {
          self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc));
        }

        return ref;

      } else {

        EPeer peer = (EPeer) EPeer.get(node);
        if (peer != null) {
          ERef ref = ERT.getLocalNode().createRef();
          self.monitor(tup, ref);
          peer.dsig_monitor(self.self_handle(), name, ref);
          return ref;
        }

        return ErlDist.dmonitor_p2_trap.invoke(self, new EObject[] {how, object});
      }
    }

    throw ERT.badarg(how, object);
  }
Esempio n. 2
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();
    }
  }