A thread-safe single-assignment reference cell.
A fresh BlockingCell holds no value (is empty). Any thread reading the Value property when the cell is empty will block until a value is made available by some other thread. The Value property can only be set once - on the first call, the BlockingCell is considered full, and made immutable. Further attempts to set Value result in a thrown InvalidOperationException.
 public static void SetAfter(int delayMs, BlockingCell k, object v)
 {
     DelayedSetter ds = new DelayedSetter();
     ds.m_k = k;
     ds.m_delayMs = delayMs;
     ds.m_v = v;
     new Thread(new ThreadStart(ds.Run)).Start();
 }
        public void TestGetValueWhichDoesNotTimeOut()
        {
            BlockingCell k = new BlockingCell();
            k.Value = 123;

            ResetTimer();
            var v = k.GetValue(TimingInterval);
            Assert.Greater(SafetyMargin, ElapsedMs());
            Assert.AreEqual(123, v);
        }
        public void TestBackgroundUpdateFails()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(TimingInterval * 2, k, 123);

            ResetTimer();
            Assert.Throws<TimeoutException>(() => k.GetValue(TimingInterval));
        }
        public void TestTimeoutLong()
        {
            BlockingCell k = new BlockingCell();

            ResetTimer();
            object v;
            bool r = k.GetValue((int) TimingInterval.TotalMilliseconds, out v);
            Assert.Less((int)TimingInterval.Subtract(SafetyMargin).TotalMilliseconds, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
 public void TestSetBeforeGet()
 {
     BlockingCell k = new BlockingCell();
     k.Value = 123;
     Assert.AreEqual(123, k.Value);
 }
        public void TestBgLong()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(TimingInterval * 2, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(TimingInterval, out v);
            Assert.Greater(TimingInterval + SafetyMargin, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
        public void TestTimeoutNegative()
        {
            BlockingCell k = new BlockingCell();

            ResetTimer();
            object v;
            bool r = k.GetValue(-10000, out v);
            Assert.Greater(SafetyMargin, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
 public void HandleConnectionStart(byte versionMajor,
                                   byte versionMinor,
                                   IDictionary<string, object> serverProperties,
                                   byte[] mechanisms,
                                   byte[] locales)
 {
     if (m_connectionStartCell == null)
     {
         ShutdownEventArgs reason =
             new ShutdownEventArgs(ShutdownInitiator.Library,
                                   CommonFraming.Constants.CommandInvalid,
                                   "Unexpected Connection.Start");
         ((ConnectionBase)m_session.Connection).Close(reason);
     }
     ConnectionStartDetails details = new ConnectionStartDetails();
     details.m_versionMajor = versionMajor;
     details.m_versionMinor = versionMinor;
     details.m_serverProperties = serverProperties;
     details.m_mechanisms = mechanisms;
     details.m_locales = locales;
     m_connectionStartCell.Value = details;
     m_connectionStartCell = null;
 }
        public void TestTimeoutLong()
        {
            BlockingCell k = new BlockingCell();

            ResetTimer();
            object v;
            bool r = k.GetValue(250, out v);
            Assert.Greater(ElapsedMs(), 200);
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
        public void TestTimeoutInfinite()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(250, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(Timeout.Infinite, out v);
            Assert.Greater(ElapsedMs(), 200);
            Assert.IsTrue(r);
            Assert.AreEqual(123, v);
        }
        public void TestBgShort()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(50, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(100, out v);
            Assert.Greater(ElapsedMs(), 40);
            Assert.IsTrue(r);
            Assert.AreEqual(123, v);
        }
        public void Open(bool insist)
        {
            BlockingCell connectionStartCell = new BlockingCell();
            m_model0.m_connectionStartCell = connectionStartCell;
            m_frameHandler.Timeout = HandshakeTimeout;
            m_frameHandler.SendHeader();

            ConnectionStartDetails connectionStart = (ConnectionStartDetails)
                connectionStartCell.Value;

            AmqpVersion serverVersion = new AmqpVersion(connectionStart.m_versionMajor,
                                                        connectionStart.m_versionMinor);
            if (!serverVersion.Equals(Protocol.Version))
            {
                TerminateMainloop();
                FinishClose();
                throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
                                                           Protocol.MinorVersion,
                                                           serverVersion.Major,
                                                           serverVersion.Minor);
            }

            // FIXME: check that PLAIN is supported.
            // FIXME: parse out locales properly!
            ConnectionTuneDetails connectionTune =
                m_model0.ConnectionStartOk(BuildClientPropertiesTable(),
                                           "PLAIN",
                                           Encoding.UTF8.GetBytes("\0" + m_parameters.UserName +
                                                                  "\0" + m_parameters.Password),
                                           "en_US");

            ushort channelMax = (ushort) NegotiatedMaxValue(m_parameters.RequestedChannelMax,
                                                            connectionTune.m_channelMax);
            ChannelMax = channelMax;

            uint frameMax = NegotiatedMaxValue(m_parameters.RequestedFrameMax,
                                               connectionTune.m_frameMax);
            FrameMax = frameMax;

            ushort heartbeat = (ushort) NegotiatedMaxValue(m_parameters.RequestedHeartbeat,
                                                           connectionTune.m_heartbeat);
            Heartbeat = heartbeat;

            m_model0.ConnectionTuneOk(channelMax,
                                      frameMax,
                                      heartbeat);

            string knownHosts = m_model0.ConnectionOpen(m_parameters.VirtualHost,
                                                        "", // FIXME: make configurable?
                                                        insist);
            KnownHosts = AmqpTcpEndpoint.ParseMultiple(Protocol, knownHosts);
        }
示例#13
0
        public void Open(bool insist)
        {
            BlockingCell connectionStartCell = new BlockingCell();
            m_model0.m_connectionStartCell = connectionStartCell;
            m_frameHandler.Timeout = HandshakeTimeout;
            m_frameHandler.SendHeader();

            ConnectionStartDetails connectionStart = (ConnectionStartDetails)
                connectionStartCell.Value;

            ServerProperties = connectionStart.m_serverProperties;

            AmqpVersion serverVersion = new AmqpVersion(connectionStart.m_versionMajor,
                                                        connectionStart.m_versionMinor);
            if (!serverVersion.Equals(Protocol.Version))
            {
                TerminateMainloop();
                FinishClose();
                throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
                                                           Protocol.MinorVersion,
                                                           serverVersion.Major,
                                                           serverVersion.Minor);
            }

            m_clientProperties = new Hashtable(m_factory.ClientProperties);

            // FIXME: check that PLAIN is supported.
            // FIXME: parse out locales properly!
            ConnectionTuneDetails connectionTune = default(ConnectionTuneDetails);
            try
            {
                connectionTune = 
                m_model0.ConnectionStartOk(m_clientProperties,
                                           "PLAIN",
                                           Encoding.UTF8.GetBytes(
                                               "\0" + m_factory.UserName +
                                               "\0" + m_factory.Password),
                                           "en_US");
            }
            catch (OperationInterruptedException e)
            {
                throw new PossibleAuthenticationFailureException(
                    "Possibly caused by authentication failure", e);
            }

            ushort channelMax = (ushort) NegotiatedMaxValue(m_factory.RequestedChannelMax,
                                                            connectionTune.m_channelMax);
            m_sessionManager = new SessionManager(this, channelMax);

            uint frameMax = NegotiatedMaxValue(m_factory.RequestedFrameMax,
                                               connectionTune.m_frameMax);
            FrameMax = frameMax;

            ushort heartbeat = (ushort) NegotiatedMaxValue(m_factory.RequestedHeartbeat,
                                                           connectionTune.m_heartbeat);
            Heartbeat = heartbeat;

            m_model0.ConnectionTuneOk(channelMax,
                                      frameMax,
                                      heartbeat);

            string knownHosts = m_model0.ConnectionOpen(m_factory.VirtualHost,
                                                        "", // FIXME: make configurable?
                                                        insist);
            KnownHosts = AmqpTcpEndpoint.ParseMultiple(Protocol, knownHosts);
        }
        public void TestBgLong()
        {
            BlockingCell k = new BlockingCell();
            SetAfter((int) TimingInterval.TotalMilliseconds * 2, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue((int) TimingInterval.TotalMilliseconds, out v);
            Assert.Greater((int)TimingInterval.Add(SafetyMargin).TotalMilliseconds, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
        protected void StartAndTune()
        {
            var connectionStartCell = new BlockingCell();
            m_model0.m_connectionStartCell = connectionStartCell;
            m_model0.HandshakeContinuationTimeout = m_factory.HandshakeContinuationTimeout;
            m_frameHandler.ReadTimeout = m_factory.HandshakeContinuationTimeout.Milliseconds;
            m_frameHandler.SendHeader();

            var connectionStart = (ConnectionStartDetails)
                connectionStartCell.Value;

            if (connectionStart == null)
            {
                throw new IOException("connection.start was never received, likely due to a network timeout");
            }

            ServerProperties = connectionStart.m_serverProperties;

            var serverVersion = new AmqpVersion(connectionStart.m_versionMajor,
                connectionStart.m_versionMinor);
            if (!serverVersion.Equals(Protocol.Version))
            {
                TerminateMainloop();
                FinishClose();
                throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
                    Protocol.MinorVersion,
                    serverVersion.Major,
                    serverVersion.Minor);
            }

            m_clientProperties = new Dictionary<string, object>(m_factory.ClientProperties);
            m_clientProperties["capabilities"] = Protocol.Capabilities;
            m_clientProperties["connection_name"] = this.ClientProvidedName;

            // FIXME: parse out locales properly!
            ConnectionTuneDetails connectionTune = default(ConnectionTuneDetails);
            bool tuned = false;
            try
            {
                string mechanismsString = Encoding.UTF8.GetString(connectionStart.m_mechanisms, 0, connectionStart.m_mechanisms.Length);
                string[] mechanisms = mechanismsString.Split(' ');
                AuthMechanismFactory mechanismFactory = m_factory.AuthMechanismFactory(mechanisms);
                if (mechanismFactory == null)
                {
                    throw new IOException("No compatible authentication mechanism found - " +
                                          "server offered [" + mechanismsString + "]");
                }
                AuthMechanism mechanism = mechanismFactory.GetInstance();
                byte[] challenge = null;
                do
                {
                    byte[] response = mechanism.handleChallenge(challenge, m_factory);
                    ConnectionSecureOrTune res;
                    if (challenge == null)
                    {
                        res = m_model0.ConnectionStartOk(m_clientProperties,
                            mechanismFactory.Name,
                            response,
                            "en_US");
                    }
                    else
                    {
                        res = m_model0.ConnectionSecureOk(response);
                    }

                    if (res.m_challenge == null)
                    {
                        connectionTune = res.m_tuneDetails;
                        tuned = true;
                    }
                    else
                    {
                        challenge = res.m_challenge;
                    }
                }
                while (!tuned);
            }
            catch (OperationInterruptedException e)
            {
                if (e.ShutdownReason != null && e.ShutdownReason.ReplyCode == Constants.AccessRefused)
                {
                    throw new AuthenticationFailureException(e.ShutdownReason.ReplyText);
                }
                throw new PossibleAuthenticationFailureException(
                    "Possibly caused by authentication failure", e);
            }

            var channelMax = (ushort)NegotiatedMaxValue(m_factory.RequestedChannelMax,
                connectionTune.m_channelMax);
            m_sessionManager = new SessionManager(this, channelMax);

            uint frameMax = NegotiatedMaxValue(m_factory.RequestedFrameMax,
                connectionTune.m_frameMax);
            FrameMax = frameMax;

            var heartbeat = (ushort)NegotiatedMaxValue(m_factory.RequestedHeartbeat,
                connectionTune.m_heartbeat);
            Heartbeat = heartbeat;

            m_model0.ConnectionTuneOk(channelMax,
                frameMax,
                heartbeat);

            // now we can start heartbeat timers
            MaybeStartHeartbeatTimers();
        }
        protected void StartAndTune()
        {
            BlockingCell connectionStartCell = new BlockingCell();
            m_model0.m_connectionStartCell = connectionStartCell;
            m_frameHandler.Timeout = HandshakeTimeout;
            m_frameHandler.SendHeader();

            ConnectionStartDetails connectionStart = (ConnectionStartDetails)
                connectionStartCell.Value;

            if (connectionStart == null){
                throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
                                                           Protocol.MinorVersion,
                                                           -1, -1);
            }

            ServerProperties = connectionStart.m_serverProperties;

            AmqpVersion serverVersion = new AmqpVersion(connectionStart.m_versionMajor,
                                                        connectionStart.m_versionMinor);
            if (!serverVersion.Equals(Protocol.Version))
            {
                TerminateMainloop();
                FinishClose();
                throw new ProtocolVersionMismatchException(Protocol.MajorVersion,
                                                           Protocol.MinorVersion,
                                                           serverVersion.Major,
                                                           serverVersion.Minor);
            }

            m_clientProperties = new Hashtable(m_factory.ClientProperties);
            m_clientProperties["capabilities"] = Protocol.Capabilities;

            // FIXME: parse out locales properly!
            ConnectionTuneDetails connectionTune = default(ConnectionTuneDetails);
            bool tuned = false;
            try
            {
                string mechanismsString = Encoding.UTF8.GetString(connectionStart.m_mechanisms);
                string[] mechanisms = mechanismsString.Split(' ');
                AuthMechanismFactory mechanismFactory = m_factory.AuthMechanismFactory(mechanisms);
                if (mechanismFactory == null) {
                    throw new IOException("No compatible authentication mechanism found - " +
                                          "server offered [" + mechanismsString + "]");
                }
                AuthMechanism mechanism = mechanismFactory.GetInstance();
                byte[] challenge = null;
                do {
                    byte[] response = mechanism.handleChallenge(challenge, m_factory);
                    ConnectionSecureOrTune res;
                    if (challenge == null) {
                        res = m_model0.ConnectionStartOk(m_clientProperties,
                                                         mechanismFactory.Name,
                                                         response,
                                                         "en_US");
                    }
                    else {
                        res = m_model0.ConnectionSecureOk(response);
                    }

                    if (res.m_challenge == null) {
                        connectionTune = res.m_tuneDetails;
                        tuned = true;
                    } else {
                        challenge = res.m_challenge;
                    }
                } while (!tuned);
            }
            catch (OperationInterruptedException e)
            {
                throw new PossibleAuthenticationFailureException(
                    "Possibly caused by authentication failure", e);
            }

            ushort channelMax = (ushort) NegotiatedMaxValue(m_factory.RequestedChannelMax,
                                                            connectionTune.m_channelMax);
            m_sessionManager = new SessionManager(this, channelMax);

            uint frameMax = NegotiatedMaxValue(m_factory.RequestedFrameMax,
                                               connectionTune.m_frameMax);
            FrameMax = frameMax;

            ushort heartbeat = (ushort) NegotiatedMaxValue(m_factory.RequestedHeartbeat,
                                                           connectionTune.m_heartbeat);
            Heartbeat = heartbeat;

            m_model0.ConnectionTuneOk(channelMax,
                                      frameMax,
                                      heartbeat);
        }
        public void TestBgLong()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(150, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(100, out v);
            Assert.Greater(110, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
        public void TestTimeoutLong()
        {
            BlockingCell k = new BlockingCell();

            ResetTimer();
            object v;
            bool r = k.GetValue(TimingInterval, out v);
            Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
            Assert.IsTrue(!r);
            Assert.AreEqual(null, v);
        }
 public void TestGetValueWhichDoesTimeOut()
 {
     BlockingCell k = new BlockingCell();
     ResetTimer();
     Assert.Throws<TimeoutException>(() => k.GetValue(TimingInterval));
 }
        public void TestBgShort()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(TimingInterval, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(TimingInterval * 2, out v);
            Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
            Assert.IsTrue(r);
            Assert.AreEqual(123, v);
        }
 public void TestGetValueWhichDoesTimeOutWithTimeSpan()
 {
     BlockingCell k = new BlockingCell();
     ResetTimer();
     Assert.Throws<TimeoutException>(() => k.GetValue(TimeSpan.FromMilliseconds(TimingInterval)));
 }
        public void TestGetValueWithTimeoutInfinite()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(TimingInterval, k, 123);

            ResetTimer();
            var v = k.GetValue(Timeout.Infinite);
            Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
            Assert.AreEqual(123, v);
        }
        public void TestBackgroundUpdateSucceedsWithInfiniteTimeoutTimeSpan()
        {
            BlockingCell k = new BlockingCell();
            SetAfter(TimingInterval, k, 123);

            ResetTimer();
            var v = k.GetValue(Timeout.InfiniteTimeSpan);
            Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
            Assert.AreEqual(123, v);
        }
        public void TestTimeoutShort()
        {
            BlockingCell k = new BlockingCell();
            k.Value = 123;

            ResetTimer();
            object v;
            bool r = k.GetValue(TimingInterval, out v);
            Assert.Greater(SafetyMargin, ElapsedMs());
            Assert.IsTrue(r);
            Assert.AreEqual(123, v);
        }
        public void TestTimeoutInfinite()
        {
            BlockingCell k = new BlockingCell();
            SetAfter((int) TimingInterval.TotalMilliseconds, k, 123);

            ResetTimer();
            object v;
            bool r = k.GetValue(Timeout.Infinite, out v);
            Assert.Less((int)TimingInterval.Subtract(SafetyMargin).TotalMilliseconds, ElapsedMs());
            Assert.IsTrue(r);
            Assert.AreEqual(123, v);
        }