/* * <p> 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. </p> * * <p> 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 Exit Exit} * exception to be raised. Similarly, if the sending mailbox is * closed, the linked mailbox or process will receive an exit * signal. </p> * * <p> If the remote process cannot be reached in order to set the * link, the exception is raised immediately. </p> * * @param to the {@link Pid pid} representing the object to * link to. * * @exception Exit if the {@link Pid pid} referred * to does not exist or could not be reached. * **/ public virtual void link(Erlang.Pid to) { try { System.String node = to.node(); if (node.Equals(home.node())) { if (!home.deliver(new OtpMsg(OtpMsg.Tag.linkTag, _self, to))) { throw new Erlang.Exit("noproc", to); } } else { OtpCookedConnection conn = home.connection(node); if (conn != null) { conn.link(_self, to); } else { throw new Erlang.Exit("noproc", to); } } } catch (Erlang.Exit e) { throw e; } catch (System.Exception) { } links.addLink(_self, to); }
/* * pass the 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.Tag.linkTag: if (delivered) { links.addLink(msg.getRecipientPid(), msg.getSenderPid()); } else { try { // no such pid - send exit to sender base.sendExit(msg.getRecipientPid(), msg.getSenderPid(), "noproc"); } catch (System.IO.IOException) { } } break; case OtpMsg.Tag.monitorPTag: if (delivered) { monitors[msg.getSenderPid()] = msg.getMsg(); } else { try { base.sendExit(msg.getRecipientPid(), msg.getSenderPid(), "noproc"); } catch (System.IO.IOException) { } } break; case OtpMsg.Tag.demonitorPTag: case OtpMsg.Tag.monitorPexitTag: monitors.Remove(msg.getSenderPid()); break; case OtpMsg.Tag.unlinkTag: case OtpMsg.Tag.exitTag: links.removeLink(msg.getRecipientPid(), msg.getSenderPid()); break; case OtpMsg.Tag.exit2Tag: break; } return; }