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);
  }