Пример #1
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected override void Deliver(ErlMsg msg)
 {
     if (!m_Home.Deliver(msg))
     {
         m_Home.OnUnhandledMsg(this, msg);
     }
 }
Пример #2
0
 internal void UnhandledMsg(ErlConnection conn, ErlMsg msg)
 {
     if (m_OnUnhandledMsg != null)
     {
         m_OnUnhandledMsg(conn, msg);
     }
 }
Пример #3
0
        /// <summary>
        /// Send an RPC cast request to the remote Erlang node
        /// </summary>
        public void SendRPCcast(ErlPid from, string mod, string fun, ErlList args)
        {
            IErlObject rpc = Internal.ErlRpcServer.EncodeRPCcast(from, mod, fun, args, ConstAtoms.User);
            var        msg = ErlMsg.RegSend(from, ConstAtoms.Rex, rpc);

            Send(msg);
        }
Пример #4
0
        internal bool Deliver(ErlMsg msg)
        {
            if (msg.Recipient is ErlPid)
            {
                var node = msg.RecipientPid.Node;
                if (node != NodeName)
                {
                    return(Deliver(node, msg));
                }
            }

            var mbox = msg.Type == ErlMsg.Tag.RegSend || msg.Type == ErlMsg.Tag.RegSendTT
        ? m_Mailboxes[msg.RecipientName]
        : m_Mailboxes[msg.RecipientPid];

            if (mbox == null)
            {
                return(false);
            }

            OnTrace(ErlTraceLevel.Send, Direction.Inbound, () =>
                    "{0}{1} got: {2}".Args(
                        mbox.Self,
                        mbox.Name.Empty
                                                           ? string.Empty
                                                           : " ({0})".Args(
                            mbox.Name.ToString()),
                        msg.Msg));

            mbox.Deliver(msg);

            return(true);
        }
Пример #5
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected override void Deliver(ErlMsg msg, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
 {
     if (!m_Home.Deliver(msg, file, line))
     {
         m_Home.OnUnhandledMsg(this, msg, file, line);
     }
 }
Пример #6
0
 /// <summary>
 /// Used to break all known links to this mbox
 /// </summary>
 internal void BreakLinks(ErlAtom reason)
 {
     foreach (var l in m_Links.Clear())
     {
         m_Node.Deliver(ErlMsg.Exit(m_Self, l.Pid, reason));
     }
 }
Пример #7
0
 /// <summary>
 /// 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
 /// </summary>
 /// <remarks>
 /// 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.
 ///
 /// If the remote process cannot be reached in order to set the
 /// link, the exception is raised immediately.
 /// </remarks>
 public void Link(ErlPid to)
 {
     Debug.Assert(to != m_Self);
     if (m_Node.Deliver(ErlMsg.Link(m_Self, to)))
     {
         m_Links.Add(to);
     }
 }
Пример #8
0
 /// <summary>
 /// Close this mailbox
 /// </summary>
 /// <remarks>
 /// After this operation, the mailbox will no longer be able to
 /// receive messages. Any delivered but as yet unretrieved messages
 /// can still be retrieved however.
 ///
 /// If there are links from this mailbox to other <see cref="ErlPid"/>
 /// pids they will be broken when this method is
 /// called and exit signals will be sent.
 /// </remarks>
 internal void Close()
 {
     // Notify all registered monitors that this pid is closing
     foreach (var monitor in m_Monitors)
     {
         var msg = ErlMsg.MonitorPexit(m_Self, monitor.Value, monitor.Key, ErlAtom.Normal);
         m_Node.Deliver(monitor.Value.Node, msg);
     }
     m_Node.CloseMbox(this);
     m_RegName = ErlAtom.Null;
 }
Пример #9
0
        /// <summary>
        /// Called to deliver message to this mailbox
        /// </summary>
        internal void Deliver(ErlMsg m)
        {
            Debug.Assert((m.Recipient is ErlPid && m.RecipientPid == m_Self) ||
                         (m.Recipient is ErlAtom && m.RecipientName == m_RegName));

            switch (m.Type)
            {
            case ErlMsg.Tag.Link:
                m_Links.Add(m.SenderPid);
                break;

            case ErlMsg.Tag.Unlink:
                m_Links.Remove(m.SenderPid);
                break;

            case ErlMsg.Tag.Exit:
            case ErlMsg.Tag.Exit2:
            {
                m_Monitors.Remove(m.Ref);
                if (m_Links.Remove(m.SenderPid))
                {
                    Enqueue(m);
                }
                break;
            }

            case ErlMsg.Tag.MonitorP:
                m_Monitors.Add(m.Ref, m.SenderPid);
                break;

            case ErlMsg.Tag.DemonitorP:
            {
                m_Monitors.Remove(m.Ref);
                break;
            }

            case ErlMsg.Tag.MonitorPexit:
            {
                m_Links.Remove(m.SenderPid);
                if (m_Monitors.Remove(m.Ref))
                {
                    Enqueue(new ErlDown(m.Ref, m.SenderPid, m.Reason));
                }
                break;
            }

            default:
                Enqueue(m);
                break;
            }
        }
Пример #10
0
 protected internal virtual void OnUnhandledMsg(ErlConnection conn, ErlMsg msg, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
 {
     if (UnhandledMsg != null)
     {
         UnhandledMsg(this, conn, msg);
     }
     if (LogUnhandledMsgs)
     {
         Log(MessageType.TraceErl,
             "OnUnhandledMsg",
             "Connection {0} couldn't find mbox for: {1}".Args(conn.Name, msg),
             file: file, line: line);
     }
 }
Пример #11
0
 protected internal virtual void OnUnhandledMsg(ErlConnection conn, ErlMsg msg)
 {
     if (UnhandledMsg != null)
     {
         UnhandledMsg(this, conn, msg);
     }
     if (LogUnhandledMsgs)
     {
         App.Log.Write(new NFX.Log.Message
         {
             Type  = Log.MessageType.TraceErl,
             Topic = CoreConsts.ERLANG_TOPIC,
             From  = this.ToString(),
             Text  = "Connection {0} couldn't find mbox for: {1}".Args(conn.Name, msg)
         });
     }
 }
Пример #12
0
        internal bool Deliver(ErlAtom node, ErlMsg msg)
        {
            if (node == NodeName)
            {
                return(Deliver(msg));
            }

            var conn = Connection(node);

            if (conn == null)
            {
                return(false);
            }

            try     { conn.Send(msg); }
            catch   { return(false); }
            return(true);
        }
Пример #13
0
        /// <summary>
        /// Used to break all known links to this mbox
        /// </summary>
        internal void BreakLinks(ErlAtom fromNode, IErlObject reason)
        {
            var links = m_Links.Remove(fromNode);

            foreach (var link in links)
            {
                if (link.HasPid)
                {
                    m_Node.Deliver(ErlMsg.Exit(m_Self, link.Pid, reason));
                }
                else
                {
                    m_Node.Deliver(new ErlConnectionException(fromNode, reason));
                }
            }

            foreach (var m in m_Monitors.Where(o => o.Value.Node == fromNode)
                     .Where(m => m_Monitors.Remove(m.Key)))
            {
                Deliver(new ErlConnectionException(fromNode, reason));
            }
        }
Пример #14
0
        internal void Send(ErlMsg msg)
        {
            var ctrl = msg.ToCtrlTuple(SendCookie);

            sendBuf(ctrl, msg.Payload == null ? null : new ErlOutputStream(msg.Payload));
        }
Пример #15
0
 protected internal virtual void OnUnhandledMsg(ErlConnection conn, ErlMsg msg,
     [CallerFilePath]  string file = null,
     [CallerLineNumber]int    line = 0)
 {
     if (UnhandledMsg != null) UnhandledMsg(this, conn, msg);
       if (LogUnhandledMsgs)
     App.Log.Write(new NFX.Log.Message(null, file, line)
     {
       Type = Log.MessageType.TraceErl,
       Topic = CoreConsts.ERLANG_TOPIC,
       From = this.ToString(),
       Text = "Connection {0} couldn't find mbox for: {1}".Args(conn.Name, msg)
     });
 }
Пример #16
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected abstract void Deliver(ErlMsg msg, string file, int line);
Пример #17
0
 /// <summary>
 /// Send an Erlang term to a Pid on a local or remote node
 /// </summary>
 public void Send(ErlPid dest, IErlObject msg)
 {
     base.Send(ErlMsg.Send(dest, msg, SendCookie));
 }
Пример #18
0
 /// <summary>
 /// Remove a link to a remote mailbox or Erlang process. This
 /// method removes a link created with <see cref="ErlLink"/>
 /// Links are idempotent; calling this method once will remove all
 /// links between this mailbox and the remote <see cref="ErlPid"/>
 /// </summary>
 public void Unlink(ErlPid to)
 {
     m_Links.Remove(to);
     m_Node.Deliver(ErlMsg.Unlink(m_Self, to));
 }
Пример #19
0
 /// <summary>
 /// Send a message to a remote <see cref="ErlPid"/>, representing
 /// either another <see cref="ErlMbox"/> or an Erlang process
 /// </summary>
 /// <returns>true if message was sent successfully</returns>
 public bool Send(ErlPid to, IErlObject msg)
 {
     return(Deliver(ErlMsg.Send(to, msg)));
 }
Пример #20
0
 /// <summary>
 /// Send a message to a named mailbox created from another node
 /// </summary>
 public bool Send(ErlAtom node, ErlAtom name, IErlObject msg)
 {
     return(m_Node.Deliver(node, ErlMsg.RegSend(m_Self, name, msg)));
 }
Пример #21
0
 internal static ErlTuple ToCtrlTuple(ErlMsg msg)
 {
     return(msg.ToCtrlTuple());
 }
Пример #22
0
        private void threadSpinCore()
        {
            if (!m_Connected)
            {
                Deliver(new ErlConnectionException(Name, StringConsts.ERL_CONN_NOT_CONNECTED_ERROR));
                return;
            }

            int len;

            byte[] header     = new byte[4];
            byte[] tock       = new byte[] { 0, 0, 0, 0 };
            byte[] payloadBuf = new byte[1024 * 1024];

            try
            {
                while (m_Home.Running && !this.DisposeStarted && !m_Done)
                {
                    // don't return until we get a real message
                    // or a failure of some kind (e.g. EXIT)
                    // read length and read buffer must be atomic!
                    do
                    {
                        // read 4 bytes - get length of incoming packet
                        // socket.getInputStream().read(lbuf);
                        int n;
                        if ((n = ReadSock(header, header.Length, false)) < header.Length)
                        {
                            throw new ErlException(StringConsts.ERL_CONN_READ_TOO_SHORT_ERROR, n, header.Length);
                        }

                        len = header.ReadBEInt32();

                        //  received tick? send tock!
                        if (len == 0)
                        {
                            lock (this)
                            {
                                if (m_Transport != null)
                                {
                                    (m_Transport.GetStream()).Write(tock, 0, tock.Length);
                                }
                            }
                        }
                    }while (len == 0); // tick_loop

                    if (len > DEFAULT_MAX_PAYLOAD_LENGTH)
                    {
                        throw new ErlException(
                                  StringConsts.ERL_CONN_MSG_SIZE_TOO_LONG_ERROR, DEFAULT_MAX_PAYLOAD_LENGTH, len);
                    }

                    // got a real message (maybe) - read len bytes
                    byte[] tmpbuf = new byte[len]; // len > payloadBuf.Length ? new byte[len] : payloadBuf;
                                                   // i = socket.getInputStream().read(tmpbuf);
                    int m = ReadSock(tmpbuf, len, true);
                    if (m != len)
                    {
                        throw new ErlException(StringConsts.ERL_CONN_READ_TOO_SHORT_ERROR, m, len);
                    }

                    var ibuf = new ErlInputStream(tmpbuf, 0, len, checkVersion: false);

                    if (ibuf.Read1() != PASS_THROUGH)
                    {
                        goto receive_loop_brk;
                    }

                    try
                    {
                        // decode the header
                        var tmp = ibuf.Read(true);
                        if (!(tmp is ErlTuple))
                        {
                            goto receive_loop_brk;
                        }

                        var head = (ErlTuple)tmp;
                        if (!(head[0] is ErlByte))
                        {
                            goto receive_loop_brk;
                        }

                        // lets see what kind of message this is
                        ErlMsg.Tag tag = (ErlMsg.Tag)head[0].ValueAsInt;

                        switch (tag)
                        {
                        case ErlMsg.Tag.Send:
                        case ErlMsg.Tag.SendTT:
                        {
                            // { SEND, Cookie, ToPid, TraceToken }
                            if (!m_CookieOk)
                            {
                                // we only check this once, he can send us bad cookies later if he likes
                                if (!(head[1] is ErlAtom))
                                {
                                    goto receive_loop_brk;
                                }
                                var cookie = (ErlAtom)head[1];
                                if (m_ShouldSendCookie)
                                {
                                    if (!cookie.Equals(m_Cookie))
                                    {
                                        cookieError(m_Home, cookie);
                                    }
                                }
                                else if (!cookie.Empty)
                                {
                                    cookieError(m_Home, cookie);
                                }
                                m_CookieOk = true;
                            }

                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                {
                                    long mark     = ibuf.Position;
                                    var traceobj  = ibuf.Read(true);
                                    ibuf.Position = mark;
                                    return("{0} {1} trace: {2}".Args(
                                               HeaderType(head), head.ToString(),
                                               traceobj == null ? "(null)" : traceobj.ToString()));
                                });

                            var to = (ErlPid)head[2];

                            Deliver(new ErlMsg(tag, ErlPid.Null, to, paybuf: ibuf));
                            break;
                        }

                        case ErlMsg.Tag.RegSend:
                        case ErlMsg.Tag.RegSendTT:
                        {
                            // { REG_SEND, FromPid, Cookie, ToName, TraceToken }
                            if (!m_CookieOk)
                            {
                                // we only check this once, he can send us bad cookies later if he likes
                                if (!(head[2] is ErlAtom))
                                {
                                    goto receive_loop_brk;
                                }
                                var cookie = (ErlAtom)head[2];
                                if (m_ShouldSendCookie)
                                {
                                    if (!cookie.Equals(m_Cookie))
                                    {
                                        cookieError(m_Home, cookie);
                                    }
                                }
                                else if (!cookie.Empty)
                                {
                                    cookieError(m_Home, cookie);
                                }
                                m_CookieOk = true;
                            }

                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                {
                                    long mark     = ibuf.Position;
                                    var traceobj  = ibuf.Read(true);
                                    ibuf.Position = mark;
                                    return("{0} {1} trace: {2}".Args(
                                               HeaderType(head), head.ToString(),
                                               traceobj == null ? "(null)" : traceobj.ToString()));
                                });

                            var from   = (ErlPid)head[1];
                            var toName = (ErlAtom)head[3];

                            Deliver(new ErlMsg(tag, from, toName, paybuf: ibuf));
                            break;
                        }

                        case ErlMsg.Tag.Exit:
                        case ErlMsg.Tag.Exit2:
                        {
                            // { EXIT2, FromPid, ToPid, Reason }
                            if (!(head[3] is ErlAtom))
                            {
                                goto receive_loop_brk;
                            }

                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));

                            var from   = (ErlPid)head[1];
                            var to     = (ErlPid)head[2];
                            var reason = (ErlAtom)head[3];

                            Deliver(new ErlMsg(tag, from, to, reason: reason));
                            break;
                        }

                        case ErlMsg.Tag.ExitTT:
                        case ErlMsg.Tag.Exit2TT:
                        {
                            // { EXIT2, FromPid, ToPid, TraceToken, Reason }
                            // as above, but bifferent element number
                            if (!(head[4] is ErlAtom))
                            {
                                goto receive_loop_brk;
                            }

                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));
                            // TODO: print TraceToken

                            var from   = (ErlPid)head[1];
                            var to     = (ErlPid)head[2];
                            var trace  = (ErlTrace)head[3];
                            var reason = (ErlAtom)head[4];

                            Deliver(new ErlMsg(tag, from, to, reason: reason, trace: trace));
                            break;
                        }

                        case ErlMsg.Tag.Link:
                        case ErlMsg.Tag.Unlink:
                        {
                            // {UNLINK, FromPid, ToPid}
                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));

                            var from = (ErlPid)head[1];
                            var to   = (ErlPid)head[2];

                            Deliver(new ErlMsg(tag, from, to));
                            break;
                        }

                        case ErlMsg.Tag.GroupLeader:
                        case ErlMsg.Tag.NodeLink:
                        {
                            // No idea what to do with these, so we ignore them...
                            // {GROUP_LEADER, FromPid, ToPid},  { NODELINK }
                            // (just show trace)
                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));
                            break;
                        }

                        case ErlMsg.Tag.MonitorP:
                        case ErlMsg.Tag.DemonitorP:
                        {
                            // {MONITOR_P, FromPid, ToProc, Ref}
                            // {DEMONITOR_P, FromPid, ToProc, Ref}
                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));
                            var from = (ErlPid)head[1];
                            var to   = (ErlPid)head[2];
                            var eref = (ErlRef)head[3];

                            Deliver(new ErlMsg(tag, from, to, eref));
                            break;
                        }

                        case ErlMsg.Tag.MonitorPexit:
                        {
                            // {MONITOR_P_EXIT, FromPid, ToProc, Ref, Reason}
                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           "{0} {1}".Args(HeaderType(head), head.ToString()));
                            var from   = (ErlPid)head[1];
                            var to     = (ErlPid)head[2];
                            var eref   = (ErlRef)head[3];
                            var reason = head[4];

                            Deliver(ErlMsg.MonitorPexit(from, to, eref, reason));
                            break;
                        }

                        default:
                            // garbage?
                            m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                                           StringConsts.ERL_CONN_UNKNOWN_TAG_ERROR.Args(
                                               HeaderType(head), head.ToString()));
                            goto receive_loop_brk;
                        }
                    }
                    catch (Exception e)
                    {
                        // we have received garbage
                        m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, e.ToString());
                        Deliver(new ErlBadDataException(
                                    Name, /* "Remote has closed connection or sending garbage: " + */
                                    e.Message));
                    }
                }

receive_loop_brk:
                // end receive_loop

                // this section reachable only with break
                // connection went down or we have received garbage from peer
                Deliver(new ErlConnectionException(Name, StringConsts.ERL_CONN_INVALID_DATA_FROM_PEER_ERROR));
            }
            catch (ErlAuthException e)
            {
                m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () => e.ToString());
                Deliver(e);
            }
            catch (Exception e)
            {
                m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () => e.ToString());
                Deliver(new ErlConnectionException(
                            Name, /* "Remote has closed connection or sending garbage: " + */
                            e.Message));
            }
            finally
            {
                m_Thread = null;
                Close();
                m_Home.OnTrace(ErlTraceLevel.Ctrl, Direction.Inbound, () =>
                               "Exiting connection (thread {0})".Args(Thread.CurrentThread.Name));
            }
        }
Пример #23
0
 internal void UnhandledMsg(ErlConnection conn, ErlMsg msg)
 {
     if (m_OnUnhandledMsg != null)
         m_OnUnhandledMsg(conn, msg);
 }
Пример #24
0
            internal bool Deliver(ErlMsg msg)
            {
                if (msg.Recipient is ErlPid)
                {
                    var node = msg.RecipientPid.Node;
                    if (node != NodeName)
                        return Deliver(node, msg);
                }

                var mbox = msg.Type == ErlMsg.Tag.RegSend || msg.Type == ErlMsg.Tag.RegSendTT
                    ? m_Mailboxes[msg.RecipientName]
                    : m_Mailboxes[msg.RecipientPid];

                if (mbox == null)
                    return false;

                Trace(ErlTraceLevel.Send, Direction.Inbound, () =>
                    "{0}{1} got: {2}".Args(
                        mbox.Self, mbox.Name.Empty ? string.Empty : " ({0})".Args(mbox.Name.ToString()),
                        msg.Msg));

                mbox.Deliver(msg);
                return true;
            }
Пример #25
0
            internal bool Deliver(ErlAtom node, ErlMsg msg)
            {
                if (node == NodeName)
                    return Deliver(msg);

                var conn = Connection(node);
                if (conn == null)
                    return false;
                
                try     { conn.Send(msg); }
                catch   { return false; }
                return true;
            }
Пример #26
0
 internal void Send(ErlMsg msg)
 {
     var ctrl = msg.ToCtrlTuple(SendCookie);
       sendBuf(ctrl, msg.Payload==null ? null : new ErlOutputStream(msg.Payload));
 }
Пример #27
0
 /// <summary>
 /// Send a message to a named mailbox on local node
 /// </summary>
 public bool Send(ErlPid from, ErlAtom toName, IErlObject msg)
 {
     return(Deliver(ErlMsg.RegSend(from, toName, msg)));
 }
Пример #28
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected abstract void Deliver(ErlMsg msg);
Пример #29
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected abstract void Deliver(ErlMsg msg);
Пример #30
0
 protected internal virtual void OnUnhandledMsg(ErlConnection conn, ErlMsg msg, [CallerFilePath]string file = "", [CallerLineNumber]int line = 0)
 {
   if (UnhandledMsg != null) UnhandledMsg(this, conn, msg);
   if (LogUnhandledMsgs)
     Log(MessageType.TraceErl,
         "OnUnhandledMsg",
         "Connection {0} couldn't find mbox for: {1}".Args(conn.Name, msg), 
         file:file, line:line);
 }
Пример #31
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected override void Deliver(ErlMsg msg)
 {
   if (!m_Home.Deliver(msg))
     m_Home.OnUnhandledMsg(this, msg);
 }
Пример #32
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected override void Deliver(ErlMsg msg, [CallerFilePath]string file = "", [CallerLineNumber]int line = 0)
 {
   if (!m_Home.Deliver(msg, file, line))
     m_Home.OnUnhandledMsg(this, msg, file, line);
 }
Пример #33
0
    /// <summary>
    /// Called to deliver message to this mailbox
    /// </summary>
    internal void Deliver(ErlMsg m)
    {
      Debug.Assert((m.Recipient is ErlPid  && m.RecipientPid == m_Self)
                || (m.Recipient is ErlAtom && m.RecipientName == m_RegName));

      switch (m.Type)
      {
        case ErlMsg.Tag.Link:
          m_Links.Add(m.SenderPid);
          break;

        case ErlMsg.Tag.Unlink:
          m_Links.Remove(m.SenderPid);
          break;

        case ErlMsg.Tag.Exit:
        case ErlMsg.Tag.Exit2:
          m_Monitors.Remove(m.Ref);
          if (m_Links.Remove(m.SenderPid))
            Enqueue(m);
          break;

        case ErlMsg.Tag.MonitorP:
          m_Monitors.Add(m.Ref, m.SenderPid);
          break;

        case ErlMsg.Tag.DemonitorP:
          m_Monitors.Remove(m.Ref);
          break;

        case ErlMsg.Tag.MonitorPexit:
          m_Links.Remove(m.SenderPid);
          if (m_Monitors.Remove(m.Ref))
            Enqueue(new ErlDown(m.Ref, m.SenderPid, m.Reason));
          break;

        case ErlMsg.Tag.Undefined:
          break;

        default:
          Enqueue(m);
          break;
      }

    }
Пример #34
0
 /// <summary>
 /// Deliver messages to the recipient
 /// </summary>
 protected abstract void Deliver(ErlMsg msg, string file, int line);
Пример #35
0
 /*
  * send to remote name
  * dest is recipient's registered name, the nodename is implied by
  * the choice of connection.
  */
 public void Send(ErlPid from, ErlAtom dest, IErlObject msg)
 {
     // encode and send the message
     base.Send(ErlMsg.RegSend(from, dest, msg, SendCookie));
 }