Esempio n. 1
0
 public LinkProtocolState(Linker l, TransportAddress ta, Edge e)
 {
     _linker      = l;
     _node        = l.LocalNode;
     _contype     = l.ConType;
     _lm_reply    = new WriteOnce <LinkMessage>();
     _x           = new WriteOnce <Exception>();
     _con         = new WriteOnce <Connection>();
     _ta          = ta;
     _is_finished = 0;
     //Setup the edge:
     _e      = e;
     _result = Result.None;
 }
    /**
     * There are only four ways we can get here:
     * 
     * 1) We got some exception in Start and never made the first request
     * 2) There was some problem in LinkCloseHandler
     * 3) We either got a response or had a problem in StatusCloseHandler
     * 4) The Edge closed, and the CloseHandler was called.
     * 
     * The only possibility for a race is between the CloseHandler and
     * the others.
     *
     * When this state machine reaches an end point, it calls this method,
     * which fires the FinishEvent
     */
    protected void Finish(Result res) {
      /*
       * No matter what, we are done here:
       */
      if(ProtocolLog.LinkDebug.Enabled) {
        string message;
        Exception x;
        if (_x.TryGet(out x) ) {
          message = String.Format(
                      "LPS: {0} finished: {2}, with exception: {1}",
                      _node.Address, x, res);
        }
        else {
          message = String.Format("LPS: {0} finished: {1}",
                                  _node.Address, res);
        }
        ProtocolLog.Write(ProtocolLog.LinkDebug, message);
      }

      int already_finished = Interlocked.Exchange(ref _is_finished, 1);
      if(already_finished == 1) {
        //We already got here.
        //This is a barrier.  Only one Finish call will make
        //it past this point.  Only two could happen in a race:
        //Edge closing or some other failure/success.
        return;
      }
      //We don't care about close event's anymore
      _e.CloseEvent -= this.CloseHandler;

      //Set the result:
      _result = res;
      
      try {
        //Check to see if we need to close the edge
        if( _con.IsSet == false ) {
          /*
           * We didn't get a complete connection,
           * but we may have heard some response.  If so
           * close the edge gracefully.
           */
          if (LinkMessageReply != null) {
            //Let's be nice:
            _node.GracefullyClose(_e, "From LPS, did not complete a connection.");
          }
          else {
            /*
             * We never heard from the other side, so we will assume that further
             * packets will only waste bandwidth
             */
            _e.Close();
          }
          if(ProtocolLog.LinkDebug.Enabled) {
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
              "LPS: {0} got no connection", _node.Address));
          }
        }
        else {
          if(ProtocolLog.LinkDebug.Enabled) {
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
              "LPS: {0} got connection: {1}", _node.Address, _con.Value));
          }
        }
        //This could throw an exception, but make sure we unlock if it does.
        FireFinished();
      }
      finally {
        /**
         * We have to make sure the lock is eventually released:
         */
        this.Unlock();
      }
    }
 public LinkProtocolState(Linker l, TransportAddress ta, Edge e) {
   _linker = l;
   _node = l.LocalNode;
   _contype = l.ConType;
   _target_lock = null;
   _lm_reply = new WriteOnce<LinkMessage>();
   _x = new WriteOnce<Exception>();
   _con = new WriteOnce<Connection>();
   _ta = ta;
   _is_finished = 0;
   //Setup the edge:
   _e = e;
   _result = Result.None;
 }
Esempio n. 4
0
        /**
         * There are only four ways we can get here:
         *
         * 1) We got some exception in Start and never made the first request
         * 2) There was some problem in LinkCloseHandler
         * 3) We either got a response or had a problem in StatusCloseHandler
         * 4) The Edge closed, and the CloseHandler was called.
         *
         * The only possibility for a race is between the CloseHandler and
         * the others.
         *
         * When this state machine reaches an end point, it calls this method,
         * which fires the FinishEvent
         */
        protected void Finish(Result res)
        {
            /*
             * No matter what, we are done here:
             */
            if (ProtocolLog.LinkDebug.Enabled)
            {
                string    message;
                Exception x;
                if (_x.TryGet(out x))
                {
                    message = String.Format(
                        "LPS: {0} finished: {2}, with exception: {1}",
                        _node.Address, x, res);
                }
                else
                {
                    message = String.Format("LPS: {0} finished: {1}",
                                            _node.Address, res);
                }
                ProtocolLog.Write(ProtocolLog.LinkDebug, message);
            }

            int already_finished = Interlocked.Exchange(ref _is_finished, 1);

            if (already_finished == 1)
            {
                //We already got here.
                //This is a barrier.  Only one Finish call will make
                //it past this point.  Only two could happen in a race:
                //Edge closing or some other failure/success.
                return;
            }
            //We don't care about close event's anymore
            _e.CloseEvent -= this.CloseHandler;

            //Set the result:
            _result = res;

            try {
                //Check to see if we need to close the edge
                if (_con.IsSet == false)
                {
                    /*
                     * We didn't get a complete connection,
                     * but we may have heard some response.  If so
                     * close the edge gracefully.
                     */
                    if (LinkMessageReply != null)
                    {
                        //Let's be nice:
                        _node.GracefullyClose(_e, "From LPS, did not complete a connection.");
                    }
                    else
                    {
                        /*
                         * We never heard from the other side, so we will assume that further
                         * packets will only waste bandwidth
                         */
                        _e.Close();
                    }
                    if (ProtocolLog.LinkDebug.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                              "LPS: {0} got no connection", _node.Address));
                    }
                }
                else
                {
                    if (ProtocolLog.LinkDebug.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                              "LPS: {0} got connection: {1}", _node.Address, _con.Value));
                    }
                }
                //This could throw an exception, but make sure we unlock if it does.
                FireFinished();
            }
            finally {
                /**
                 * We have to make sure the lock is eventually released:
                 */
                this.Unlock();
            }
        }