@BIF public static EAtom exit(EProc proc, EObject p, EObject reason) throws Pausable { // System.err.println(proc.self_handle() + ":: erlang:exit(" + p + ", " + reason + ")"); EHandle pid = p.testHandle(); if (pid == null) throw ERT.badarg(p, reason); if (pid == proc.self_handle()) { throw new ErlangExit(reason, proc.self_handle()); } pid.exit_signal(proc.self_handle(), reason, true); return ERT.TRUE; }
@BIF public static EObject spawn(EProc proc, EObject mod, EObject fun, EObject args) { EAtom m = mod.testAtom(); EAtom f = fun.testAtom(); ESeq a = args.testSeq(); if (m == null || f == null || a == null) throw ERT.badarg(mod, fun, args); EProc p2 = new EProc(proc.group_leader(), m, f, a); ERT.run(p2); return p2.self_handle(); }
@BIF public static EObject exit(EProc self, EObject a1) { throw new ErlangExit(a1, self.self_handle()); }
@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); }
@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(); } }