< Summary

Information
Class: Ice.Internal.EndpointHostResolver
Assembly: Ice
File(s): /_/csharp/src/Ice/Internal/EndpointHostResolver.cs
Tag: 125_37167941578
Line coverage
89%
Covered lines: 103
Uncovered lines: 12
Coverable lines: 115
Total lines: 238
Line coverage: 89.5%
Branch coverage
83%
Covered branches: 35
Total branches: 42
Branch coverage: 83.3%
Method coverage
100%
Covered methods: 11
Fully covered methods: 7
Total methods: 11
Method coverage: 100%
Full method coverage: 63.6%

Metrics

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

File(s)

/_/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.getThreadPriorityProperty(instance.initializationData().properties, "Ice"));
 118    }
 19
 20    public void resolve(string host, int port, IPEndpointI endpoint, EndpointI_connectors callback)
 21    {
 22        //
 23        // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve
 24        // entry and the thread will take care of getting the endpoint addresses.
 25        //
 126        NetworkProxy networkProxy = _instance.networkProxy();
 127        if (networkProxy == null)
 28        {
 29            try
 30            {
 131                List<EndPoint> addrs = Network.getAddresses(host, port, _protocol, _preferIPv6, false);
 132                if (addrs.Count > 0)
 33                {
 134                    callback.connectors(endpoint.connectors(addrs, null));
 135                    return;
 36                }
 137            }
 038            catch (Ice.LocalException ex)
 39            {
 040                callback.exception(ex);
 041                return;
 42            }
 43        }
 44
 145        lock (_mutex)
 46        {
 47            Debug.Assert(!_destroyed);
 48
 149            var entry = new ResolveEntry();
 150            entry.host = host;
 151            entry.port = port;
 152            entry.endpoint = endpoint;
 153            entry.callback = callback;
 54
 155            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 156            if (obsv != null)
 57            {
 158                entry.observer = obsv.getEndpointLookupObserver(endpoint);
 159                entry.observer?.attach();
 60            }
 61
 162            _queue.AddLast(entry);
 163            Monitor.Pulse(_mutex);
 164        }
 165    }
 66
 67    public void destroy()
 68    {
 169        lock (_mutex)
 70        {
 71            Debug.Assert(!_destroyed);
 172            _destroyed = true;
 173            Monitor.Pulse(_mutex);
 174        }
 175    }
 76
 177    public void joinWithThread() => _thread?.Join();
 78
 79    public void run()
 80    {
 81        while (true)
 82        {
 83            ResolveEntry r;
 84            Ice.Instrumentation.ThreadObserver threadObserver;
 85
 186            lock (_mutex)
 87            {
 188                while (!_destroyed && _queue.Count == 0)
 89                {
 190                    Monitor.Wait(_mutex);
 91                }
 92
 193                if (_destroyed)
 94                {
 195                    break;
 96                }
 97
 198                r = _queue.First.Value;
 199                _queue.RemoveFirst();
 1100                threadObserver = _observer;
 1101            }
 102
 1103            threadObserver?.stateChanged(
 1104                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 1105                    Ice.Instrumentation.ThreadState.ThreadStateInUseForOther);
 106
 107            try
 108            {
 1109                NetworkProxy networkProxy = _instance.networkProxy();
 1110                int protocol = _protocol;
 1111                if (networkProxy != null)
 112                {
 1113                    networkProxy = networkProxy.resolveHost(protocol);
 1114                    if (networkProxy != null)
 115                    {
 1116                        protocol = networkProxy.getProtocolSupport();
 117                    }
 118                }
 119
 1120                List<EndPoint> addrs = Network.getAddresses(r.host, r.port, protocol, _preferIPv6, true);
 1121                r.observer?.detach();
 1122                r.observer = null;
 123
 1124                r.callback.connectors(r.endpoint.connectors(addrs, networkProxy));
 1125            }
 1126            catch (Ice.LocalException ex)
 127            {
 1128                if (r.observer != null)
 129                {
 1130                    r.observer.failed(ex.ice_id());
 1131                    r.observer.detach();
 132                }
 1133                r.callback.exception(ex);
 1134            }
 135            finally
 136            {
 1137                threadObserver?.stateChanged(
 1138                        Ice.Instrumentation.ThreadState.ThreadStateInUseForOther,
 1139                        Ice.Instrumentation.ThreadState.ThreadStateIdle);
 1140            }
 141        }
 142
 1143        foreach (ResolveEntry entry in _queue)
 144        {
 0145            var ex = new Ice.CommunicatorDestroyedException();
 0146            if (entry.observer != null)
 147            {
 0148                entry.observer.failed(ex.ice_id());
 0149                entry.observer.detach();
 150            }
 0151            entry.callback.exception(ex);
 152        }
 1153        _queue.Clear();
 154
 1155        _observer?.detach();
 1156    }
 157
 158    public void
 159    updateObserver()
 160    {
 1161        lock (_mutex)
 162        {
 1163            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 1164            if (obsv != null)
 165            {
 1166                _observer = obsv.getThreadObserver(
 1167                    "Communicator",
 1168                    _thread.getName(),
 1169                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 1170                    _observer);
 1171                _observer?.attach();
 172            }
 1173        }
 1174    }
 175
 176    private class ResolveEntry
 177    {
 178        internal string host;
 179        internal int port;
 180        internal IPEndpointI endpoint;
 181        internal EndpointI_connectors callback;
 182        internal Ice.Instrumentation.Observer observer;
 183    }
 184
 185    private readonly Instance _instance;
 186    private readonly int _protocol;
 187    private readonly bool _preferIPv6;
 188    private bool _destroyed;
 1189    private readonly LinkedList<ResolveEntry> _queue = new LinkedList<ResolveEntry>();
 190    private Ice.Instrumentation.ThreadObserver _observer;
 191
 192    private sealed class HelperThread
 193    {
 1194        internal HelperThread(EndpointHostResolver resolver)
 195        {
 1196            _resolver = resolver;
 1197            _name = _resolver._instance.initializationData().properties.getIceProperty("Ice.ProgramName");
 1198            if (_name.Length > 0)
 199            {
 1200                _name += "-";
 201            }
 1202            _name += "Ice.HostResolver";
 1203        }
 204
 1205        public void Join() => _thread.Join();
 206
 207        public void Start(ThreadPriority priority)
 208        {
 1209            _thread = new Thread(new ThreadStart(Run));
 1210            _thread.IsBackground = true;
 1211            _thread.Name = _name;
 1212            _thread.Priority = priority;
 1213            _thread.Start();
 1214        }
 215
 216        public void Run()
 217        {
 218            try
 219            {
 1220                _resolver.run();
 1221            }
 0222            catch (System.Exception ex)
 223            {
 0224                string s = "exception in endpoint host resolver thread " + _name + ":\n" + ex;
 0225                _resolver._instance.initializationData().logger.error(s);
 0226            }
 1227        }
 228
 1229        public string getName() => _name;
 230
 231        private readonly EndpointHostResolver _resolver;
 232        private readonly string _name;
 233        private Thread _thread;
 234    }
 235
 236    private readonly HelperThread _thread;
 1237    private readonly object _mutex = new();
 238}