< Summary

Information
Class: Ice.Internal.EndpointHostResolver
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/Internal/EndpointHostResolver.cs
Tag: 71_18251537082
Line coverage
89%
Covered lines: 105
Uncovered lines: 12
Coverable lines: 117
Total lines: 242
Line coverage: 89.7%
Branch coverage
83%
Covered branches: 35
Total branches: 42
Branch coverage: 83.3%
Method coverage
100%
Covered methods: 11
Total methods: 11
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
resolve(...)87.5%8.13887.5%
destroy()100%11100%
joinWithThread()50%22100%
run()87.5%24.912488.37%
updateObserver()100%44100%
.ctor(...)100%22100%
Join()100%11100%
Start(...)100%11100%
Run()0%2.75242.86%
getName()100%11100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/Internal/EndpointHostResolver.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4using System.Net;
 5
 6namespace Ice.Internal;
 7
 8public class EndpointHostResolver
 9{
 110    internal EndpointHostResolver(Instance instance)
 11    {
 112        _instance = instance;
 113        _protocol = instance.protocolSupport();
 114        _preferIPv6 = instance.preferIPv6();
 115        _thread = new HelperThread(this);
 116        updateObserver();
 117        _thread.Start(Util.stringToThreadPriority(
 118                instance.initializationData().properties.getIceProperty("Ice.ThreadPriority")));
 119    }
 20
 21    public void resolve(string host, int port, IPEndpointI endpoint, EndpointI_connectors callback)
 22    {
 23        //
 24        // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve
 25        // entry and the thread will take care of getting the endpoint addresses.
 26        //
 127        NetworkProxy networkProxy = _instance.networkProxy();
 128        if (networkProxy == null)
 29        {
 30            try
 31            {
 132                List<EndPoint> addrs = Network.getAddresses(host, port, _protocol, _preferIPv6, false);
 133                if (addrs.Count > 0)
 34                {
 135                    callback.connectors(endpoint.connectors(addrs, null));
 136                    return;
 37                }
 138            }
 039            catch (Ice.LocalException ex)
 40            {
 041                callback.exception(ex);
 042                return;
 43            }
 44        }
 45
 146        lock (_mutex)
 47        {
 48            Debug.Assert(!_destroyed);
 49
 150            var entry = new ResolveEntry();
 151            entry.host = host;
 152            entry.port = port;
 153            entry.endpoint = endpoint;
 154            entry.callback = callback;
 55
 156            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 157            if (obsv != null)
 58            {
 159                entry.observer = obsv.getEndpointLookupObserver(endpoint);
 160                entry.observer?.attach();
 61            }
 62
 163            _queue.AddLast(entry);
 164            Monitor.Pulse(_mutex);
 165        }
 166    }
 67
 68    public void destroy()
 69    {
 170        lock (_mutex)
 71        {
 72            Debug.Assert(!_destroyed);
 173            _destroyed = true;
 174            Monitor.Pulse(_mutex);
 175        }
 176    }
 77
 178    public void joinWithThread() => _thread?.Join();
 79
 80    public void run()
 81    {
 82        while (true)
 83        {
 84            ResolveEntry r;
 85            Ice.Instrumentation.ThreadObserver threadObserver;
 86
 187            lock (_mutex)
 88            {
 189                while (!_destroyed && _queue.Count == 0)
 90                {
 191                    Monitor.Wait(_mutex);
 92                }
 93
 194                if (_destroyed)
 95                {
 196                    break;
 97                }
 98
 199                r = _queue.First.Value;
 1100                _queue.RemoveFirst();
 1101                threadObserver = _observer;
 1102            }
 103
 1104            threadObserver?.stateChanged(
 1105                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 1106                    Ice.Instrumentation.ThreadState.ThreadStateInUseForOther);
 107
 108            try
 109            {
 1110                NetworkProxy networkProxy = _instance.networkProxy();
 1111                int protocol = _protocol;
 1112                if (networkProxy != null)
 113                {
 1114                    networkProxy = networkProxy.resolveHost(protocol);
 1115                    if (networkProxy != null)
 116                    {
 1117                        protocol = networkProxy.getProtocolSupport();
 118                    }
 119                }
 120
 1121                List<EndPoint> addrs = Network.getAddresses(r.host, r.port, protocol, _preferIPv6, true);
 1122                if (r.observer != null)
 123                {
 1124                    r.observer.detach();
 1125                    r.observer = null;
 126                }
 127
 1128                r.callback.connectors(r.endpoint.connectors(addrs, networkProxy));
 1129            }
 1130            catch (Ice.LocalException ex)
 131            {
 1132                if (r.observer != null)
 133                {
 1134                    r.observer.failed(ex.ice_id());
 1135                    r.observer.detach();
 136                }
 1137                r.callback.exception(ex);
 1138            }
 139            finally
 140            {
 1141                threadObserver?.stateChanged(
 1142                        Ice.Instrumentation.ThreadState.ThreadStateInUseForOther,
 1143                        Ice.Instrumentation.ThreadState.ThreadStateIdle);
 1144            }
 145        }
 146
 1147        foreach (ResolveEntry entry in _queue)
 148        {
 0149            var ex = new Ice.CommunicatorDestroyedException();
 0150            if (entry.observer != null)
 151            {
 0152                entry.observer.failed(ex.ice_id());
 0153                entry.observer.detach();
 154            }
 0155            entry.callback.exception(ex);
 156        }
 1157        _queue.Clear();
 158
 1159        _observer?.detach();
 1160    }
 161
 162    public void
 163    updateObserver()
 164    {
 1165        lock (_mutex)
 166        {
 1167            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 1168            if (obsv != null)
 169            {
 1170                _observer = obsv.getThreadObserver(
 1171                    "Communicator",
 1172                    _thread.getName(),
 1173                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 1174                    _observer);
 1175                _observer?.attach();
 176            }
 1177        }
 1178    }
 179
 180    private class ResolveEntry
 181    {
 182        internal string host;
 183        internal int port;
 184        internal IPEndpointI endpoint;
 185        internal EndpointI_connectors callback;
 186        internal Ice.Instrumentation.Observer observer;
 187    }
 188
 189    private readonly Instance _instance;
 190    private readonly int _protocol;
 191    private readonly bool _preferIPv6;
 192    private bool _destroyed;
 1193    private readonly LinkedList<ResolveEntry> _queue = new LinkedList<ResolveEntry>();
 194    private Ice.Instrumentation.ThreadObserver _observer;
 195
 196    private sealed class HelperThread
 197    {
 1198        internal HelperThread(EndpointHostResolver resolver)
 199        {
 1200            _resolver = resolver;
 1201            _name = _resolver._instance.initializationData().properties.getIceProperty("Ice.ProgramName");
 1202            if (_name.Length > 0)
 203            {
 1204                _name += "-";
 205            }
 1206            _name += "Ice.HostResolver";
 1207        }
 208
 1209        public void Join() => _thread.Join();
 210
 211        public void Start(ThreadPriority priority)
 212        {
 1213            _thread = new Thread(new ThreadStart(Run));
 1214            _thread.IsBackground = true;
 1215            _thread.Name = _name;
 1216            _thread.Priority = priority;
 1217            _thread.Start();
 1218        }
 219
 220        public void Run()
 221        {
 222            try
 223            {
 1224                _resolver.run();
 1225            }
 0226            catch (System.Exception ex)
 227            {
 0228                string s = "exception in endpoint host resolver thread " + _name + ":\n" + ex;
 0229                _resolver._instance.initializationData().logger.error(s);
 0230            }
 1231        }
 232
 1233        public string getName() => _name;
 234
 235        private readonly EndpointHostResolver _resolver;
 236        private readonly string _name;
 237        private Thread _thread;
 238    }
 239
 240    private readonly HelperThread _thread;
 1241    private readonly object _mutex = new();
 242}