/* * <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); }
// this function used internally when "process" dies // since Erlang discerns between exit and exit/2. private void exit(int arity, Erlang.Pid to, System.String reason) { try { System.String node = to.node(); if (node.Equals(home.node())) { home.deliver(new OtpMsg(OtpMsg.Tag.exitTag, _self, to, reason)); } else { OtpCookedConnection conn = home.connection(node); if (conn == null) { return; } switch (arity) { case 1: conn.exit(_self, to, reason); break; case 2: conn.exit2(_self, to, reason); break; } } } catch (System.Exception) { } }
/* * Create an Erlang PID from a stream containing a PID encoded in * Erlang external format. * * @param buf the stream containing the encoded PID. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang PID. **/ public Pid(OtpInputStream buf) { Pid p = buf.read_pid(); this._node = p.node(); this._id = p.id(); this._serial = p.serial(); this._creation = p.creation(); }
/* * Send a message to a remote {@link Pid pid}, representing * either another {@link OtpMbox mailbox} or an Erlang process. * * @param to the {@link Pid pid} identifying the intended * recipient of the message. * * @param msg the body of the message to send. * **/ public void send(Erlang.Pid to, Erlang.Object msg) { try { System.String node = to.node(); if (node.Equals(home.node())) { home.deliver(new OtpMsg(to, (Erlang.Object)(msg.clone()))); } else { OtpCookedConnection conn = home.connection(node); if (conn == null) { return; } conn.send(_self, to, msg); } } catch (System.Exception) { } }
/* * <p> Remove a link to a remote mailbox or Erlang process. This * method removes a link created with {@link #link link()}. * Links are idempotent; calling this method once will remove all * links between this mailbox and the remote {@link Pid * pid}. </p> * * @param to the {@link Pid pid} representing the object to * unlink from. * **/ public virtual void unlink(Erlang.Pid to) { links.removeLink(_self, to); try { System.String node = to.node(); if (node.Equals(home.node())) { home.deliver(new OtpMsg(OtpMsg.Tag.unlinkTag, _self, to)); } else { OtpCookedConnection conn = home.connection(node); if (conn != null) { conn.unlink(_self, to); } } } catch (System.Exception) { } }
public int encode_size(Erlang.Object o) { if (o is Erlang.Atom) { return(1 + 2 + o.atomValue().Length); } else if (o is Erlang.Boolean) { return(1 + 2 + (o.boolValue() ? Erlang.Boolean.s_true.atomValue().Length : Erlang.Boolean.s_false.atomValue().Length)); } else if (o is Erlang.Binary) { return(5 + o.binaryValue().Length); } else if (o is Erlang.Long) { long l = o.longValue(); if ((l & 0xff) == l) { return(2); } else if ((l <= OtpExternal.erlMax) && (l >= OtpExternal.erlMin)) { return(5); } return(long_arity(l)); } else if (o is Erlang.Byte) { return(1 + 1); } else if (o is Erlang.Double) { return(9); } else if (o is Erlang.String) { string l = o.stringValue(); if (l.Length == 0) { return(1); } if (l.Length < 0xffff) { return(2 + l.Length); } return(1 + 4 + 2 * l.Length); } else if (o is Erlang.List) { Erlang.List l = o.listValue(); if (l.arity() == 0) { return(1); } int sz = 5; for (int i = 0; i < l.arity(); i++) { sz += encode_size(l[i]); } return(sz); } else if (o is Erlang.Tuple) { Erlang.Tuple l = o.tupleValue(); int sz = 1 + (l.arity() < 0xff ? 1 : 4); for (int i = 0; i < l.arity(); i++) { sz += encode_size(l[i]); } return(sz); } else if (o is Erlang.Pid) { Erlang.Pid p = o.pidValue(); return(1 + (1 + 2 + p.node().Length) + 4 + 4 + 1); } else if (o is Erlang.Ref) { Erlang.Ref p = o.refValue(); int[] ids = p.ids(); return(1 + (1 + 2 + p.node().Length) + 1 + 4 * ids.Length); } else if (o is Erlang.Port) { Erlang.Port p = o.portValue(); return(1 + (1 + 2 + p.node().Length) + 4 + 1); } else { throw new Erlang.Exception("Unknown encode size for object: " + o.ToString()); } }