HTTPS calls block other threads

During testing of the sitcore performance on the SCM20260D dev board i was unable to drive a blinking LED reliable while during HTTPS calls…

I’ve added my mock up code for the test. Remember to change mac address and add the Google Certificate

using System;
using System.Diagnostics;
using System.Threading;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Pins;
using GHIElectronics.TinyCLR.Devices.Network;

namespace DevboardExplorer
{
    internal class Program
    {
        
        static void Main()
        {
            Thread t = new Thread(LedRun);
            t.Start();
            EthernetTest();
            while (true)
            {

                HttpsTest();
                Thread.Sleep(1000);
            }
        }

        static void LedRun()
        {
            var LED = GpioController.GetDefault().OpenPin(SC20260.GpioPin.PB0);
            LED.SetDriveMode(GpioPinDriveMode.Output);
            while (true)
            {
                LED.Write(GpioPinValue.High);
                Thread.Sleep(200);

                LED.Write(GpioPinValue.Low);
                Thread.Sleep(200);
            }
        }

        static void HttpsTest()
        {
            var url = "https://www.google.com";

            var certificates = Resources.GetBytes(Resources.BinaryResources.googleCert);

            X509Certificate[] certx509 = new X509Certificate[] { new X509Certificate(certificates) };
            int read = 0, total = 0;
            byte[] result = new byte[512];

            try
            {
                using (var req = HttpWebRequest.Create(url) as HttpWebRequest)
                {
                    req.KeepAlive = false;
                    req.HttpsAuthentCerts = certx509;
                    req.ReadWriteTimeout = 2000;
              

                    using (var res = req.GetResponse() as HttpWebResponse)
                    {
                        using (var stream = res.GetResponseStream())
                        {
                            do
                            {
                                read = stream.Read(result, 0, result.Length);
                                total += read;

                                System.Diagnostics.Debug.WriteLine("read : " + read);
                                System.Diagnostics.Debug.WriteLine("total : " + total);

                                var page = new String(System.Text.Encoding.UTF8.
                                    GetChars(result, 0, read));

                                System.Diagnostics.Debug.WriteLine("Response : " + page);
                                Thread.Sleep(0);
                            }
                            while (read != 0);
                        }
                    }
                }
            }
            catch
            {
            }
        }

        static bool linkReady = false;

        static void EthernetTest()
        {
            //Reset external phy.
            var gpioController = GpioController.GetDefault();
            var resetPin = gpioController.OpenPin(SC20260.GpioPin.PG3);

            resetPin.SetDriveMode(GpioPinDriveMode.Output);

            resetPin.Write(GpioPinValue.Low);
            Thread.Sleep(100);

            resetPin.Write(GpioPinValue.High);
            Thread.Sleep(100);

            var networkController = NetworkController.FromName(SC20260.NetworkController.EthernetEmac);

            var networkInterfaceSetting = new EthernetNetworkInterfaceSettings();

            var networkCommunicationInterfaceSettings = new BuiltInNetworkCommunicationInterfaceSettings();

            //   networkInterfaceSetting.Address = new IPAddress(new byte[] { 192, 168, 1, 122 });
            //   networkInterfaceSetting.SubnetMask = new IPAddress(new byte[] { 255, 255, 255, 0 });
            //   networkInterfaceSetting.GatewayAddress = new IPAddress(new byte[] { 192, 168, 1, 1 });

            networkInterfaceSetting.DnsAddresses = new IPAddress[]
                {new IPAddress(new byte[] { 8, 8, 8, 8 })};
            networkInterfaceSetting.MacAddress = new byte[] { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
            networkInterfaceSetting.DhcpEnable = true;
            networkInterfaceSetting.DynamicDnsEnable = false;

            networkController.SetInterfaceSettings(networkInterfaceSetting);
            networkController.SetCommunicationInterfaceSettings(networkCommunicationInterfaceSettings);

            networkController.SetAsDefaultController();

            networkController.NetworkAddressChanged += NetworkController_NetworkAddressChanged;
            networkController.NetworkLinkConnectedChanged += NetworkController_NetworkLinkConnectedChanged;
            networkInterfaceSetting.TlsEntropy = new byte[] { 0, 1, 2, 3 };
            networkController.Enable();

            while (linkReady == false) ;
            Debug.WriteLine("Network is ready to use");
            //Thread.Sleep(Timeout.Infinite);
        }

        private static void NetworkController_NetworkLinkConnectedChanged
            (NetworkController sender, NetworkLinkConnectedChangedEventArgs e)
        {
            //Raise connect/disconnect event.
        }

        private static void NetworkController_NetworkAddressChanged
            (NetworkController sender, NetworkAddressChangedEventArgs e)
        {

            var ipProperties = sender.GetIPProperties();
            var address = ipProperties.Address.GetAddressBytes();

            linkReady = address[0] != 0;
            Debug.WriteLine("IP: " + address[0] + "." + address[1] + "." + address[2] + "." + address[3]);
        }
    }
}

Not sure what you mean by “reliable” but it is normal that during system busy times, other threads will slow down, meaning LED blinking will have a lower rate. TinyCLR is not real time.

Hey

Didin’t expect TinyCLR to be real time but been able to blink with a LED on a 400ms 50% on/off cycle without seen the threads freeze for 1-5 seconds was not expected.

It might run fine for a number of HTTPS calls without freezing the the LED thread but at times the LED thread freezes for multiple seconds. I also did some testing with HTTP and the problem also occours here but only 1/10 of a time compared to HTTPS.

I didn’t think it will be multiple seconds. Let me check with the team.

yeah that might have helped in the first post so people’s expectations were managed :wink:

I’d agree, it’s not expected that a HTTPS would be that expensive, but it’s also not something I tried to measure how much the impact was… if i want to read a website, i want to read a website…

we could reproduce it and added issue.

hppts block other thread · Issue #1115 · ghi-electronics/TinyCLR-Libraries (github.com)