/* * Pass a message to the node for final delivery. Note that the connection * itself needs to know about links (in case of connection failure), so we * snoop for link/unlink too here. */ public override void Deliver(OtpMsg msg) { bool delivered = self.Deliver(msg); switch (msg.Type) { case OtpMsg.linkTag: if (delivered) { lock (lockObj) links.AddLink(msg.ToPid, msg.FromPid); break; } // no such pid - send exit to sender try { SendExit(msg.ToPid, msg.FromPid, new OtpErlangAtom("noproc")); } catch (IOException) { } break; case OtpMsg.unlinkTag: case OtpMsg.exitTag: lock (lockObj) links.RemoveLink(msg.ToPid, msg.FromPid); break; case OtpMsg.exit2Tag: break; } }
/** * Link to a remote mailbox or Erlang process. Links are idempotent, calling * this method multiple times will not result in more than one link being * created. * * If the remote process subsequently exits or the mailbox is closed, a * subsequent attempt to retrieve a message through this mailbox will cause * an {@link OtpErlangExit OtpErlangExit} exception to be raised. Similarly, * if the sending mailbox is closed, the linked mailbox or process will * receive an exit signal. * * If the remote process cannot be reached in order to set the link, the * exception is raised immediately. */ public void Link(OtpErlangPid to) { try { string node = to.Node; if (node.Equals(home.Node)) { if (!home.Deliver(new OtpMsg(OtpMsg.linkTag, Self, to))) { throw new OtpExit("noproc", to); } } else { OtpCookedConnection conn = home.GetConnection(node); if (conn == null) { throw new OtpExit("noproc", to); } conn.Link(Self, to); } } catch (Exception) { } links.AddLink(Self, to); }