< Summary

Information
Class: Ice.Internal.EndpointHostResolver.HelperThread
Assembly: Ice
File(s): /_/csharp/src/Ice/Internal/EndpointHostResolver.cs
Tag: 91_21789722663
Line coverage
81%
Covered lines: 18
Uncovered lines: 4
Coverable lines: 22
Total lines: 239
Line coverage: 81.8%
Branch coverage
50%
Covered branches: 2
Total branches: 4
Branch coverage: 50%
Method coverage
100%
Covered methods: 5
Total methods: 5
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
Join()100%11100%
Start(...)100%11100%
Run()0%2.75242.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{
 10    internal EndpointHostResolver(Instance instance)
 11    {
 12        _instance = instance;
 13        _protocol = instance.protocolSupport();
 14        _preferIPv6 = instance.preferIPv6();
 15        _thread = new HelperThread(this);
 16        updateObserver();
 17        _thread.Start(Util.stringToThreadPriority(
 18                instance.initializationData().properties.getIceProperty("Ice.ThreadPriority")));
 19    }
 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        //
 27        NetworkProxy networkProxy = _instance.networkProxy();
 28        if (networkProxy == null)
 29        {
 30            try
 31            {
 32                List<EndPoint> addrs = Network.getAddresses(host, port, _protocol, _preferIPv6, false);
 33                if (addrs.Count > 0)
 34                {
 35                    callback.connectors(endpoint.connectors(addrs, null));
 36                    return;
 37                }
 38            }
 39            catch (Ice.LocalException ex)
 40            {
 41                callback.exception(ex);
 42                return;
 43            }
 44        }
 45
 46        lock (_mutex)
 47        {
 48            Debug.Assert(!_destroyed);
 49
 50            var entry = new ResolveEntry();
 51            entry.host = host;
 52            entry.port = port;
 53            entry.endpoint = endpoint;
 54            entry.callback = callback;
 55
 56            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 57            if (obsv != null)
 58            {
 59                entry.observer = obsv.getEndpointLookupObserver(endpoint);
 60                entry.observer?.attach();
 61            }
 62
 63            _queue.AddLast(entry);
 64            Monitor.Pulse(_mutex);
 65        }
 66    }
 67
 68    public void destroy()
 69    {
 70        lock (_mutex)
 71        {
 72            Debug.Assert(!_destroyed);
 73            _destroyed = true;
 74            Monitor.Pulse(_mutex);
 75        }
 76    }
 77
 78    public void joinWithThread() => _thread?.Join();
 79
 80    public void run()
 81    {
 82        while (true)
 83        {
 84            ResolveEntry r;
 85            Ice.Instrumentation.ThreadObserver threadObserver;
 86
 87            lock (_mutex)
 88            {
 89                while (!_destroyed && _queue.Count == 0)
 90                {
 91                    Monitor.Wait(_mutex);
 92                }
 93
 94                if (_destroyed)
 95                {
 96                    break;
 97                }
 98
 99                r = _queue.First.Value;
 100                _queue.RemoveFirst();
 101                threadObserver = _observer;
 102            }
 103
 104            threadObserver?.stateChanged(
 105                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 106                    Ice.Instrumentation.ThreadState.ThreadStateInUseForOther);
 107
 108            try
 109            {
 110                NetworkProxy networkProxy = _instance.networkProxy();
 111                int protocol = _protocol;
 112                if (networkProxy != null)
 113                {
 114                    networkProxy = networkProxy.resolveHost(protocol);
 115                    if (networkProxy != null)
 116                    {
 117                        protocol = networkProxy.getProtocolSupport();
 118                    }
 119                }
 120
 121                List<EndPoint> addrs = Network.getAddresses(r.host, r.port, protocol, _preferIPv6, true);
 122                r.observer?.detach();
 123                r.observer = null;
 124
 125                r.callback.connectors(r.endpoint.connectors(addrs, networkProxy));
 126            }
 127            catch (Ice.LocalException ex)
 128            {
 129                if (r.observer != null)
 130                {
 131                    r.observer.failed(ex.ice_id());
 132                    r.observer.detach();
 133                }
 134                r.callback.exception(ex);
 135            }
 136            finally
 137            {
 138                threadObserver?.stateChanged(
 139                        Ice.Instrumentation.ThreadState.ThreadStateInUseForOther,
 140                        Ice.Instrumentation.ThreadState.ThreadStateIdle);
 141            }
 142        }
 143
 144        foreach (ResolveEntry entry in _queue)
 145        {
 146            var ex = new Ice.CommunicatorDestroyedException();
 147            if (entry.observer != null)
 148            {
 149                entry.observer.failed(ex.ice_id());
 150                entry.observer.detach();
 151            }
 152            entry.callback.exception(ex);
 153        }
 154        _queue.Clear();
 155
 156        _observer?.detach();
 157    }
 158
 159    public void
 160    updateObserver()
 161    {
 162        lock (_mutex)
 163        {
 164            Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
 165            if (obsv != null)
 166            {
 167                _observer = obsv.getThreadObserver(
 168                    "Communicator",
 169                    _thread.getName(),
 170                    Ice.Instrumentation.ThreadState.ThreadStateIdle,
 171                    _observer);
 172                _observer?.attach();
 173            }
 174        }
 175    }
 176
 177    private class ResolveEntry
 178    {
 179        internal string host;
 180        internal int port;
 181        internal IPEndpointI endpoint;
 182        internal EndpointI_connectors callback;
 183        internal Ice.Instrumentation.Observer observer;
 184    }
 185
 186    private readonly Instance _instance;
 187    private readonly int _protocol;
 188    private readonly bool _preferIPv6;
 189    private bool _destroyed;
 190    private readonly LinkedList<ResolveEntry> _queue = new LinkedList<ResolveEntry>();
 191    private Ice.Instrumentation.ThreadObserver _observer;
 192
 193    private sealed class HelperThread
 194    {
 1195        internal HelperThread(EndpointHostResolver resolver)
 196        {
 1197            _resolver = resolver;
 1198            _name = _resolver._instance.initializationData().properties.getIceProperty("Ice.ProgramName");
 1199            if (_name.Length > 0)
 200            {
 1201                _name += "-";
 202            }
 1203            _name += "Ice.HostResolver";
 1204        }
 205
 1206        public void Join() => _thread.Join();
 207
 208        public void Start(ThreadPriority priority)
 209        {
 1210            _thread = new Thread(new ThreadStart(Run));
 1211            _thread.IsBackground = true;
 1212            _thread.Name = _name;
 1213            _thread.Priority = priority;
 1214            _thread.Start();
 1215        }
 216
 217        public void Run()
 218        {
 219            try
 220            {
 1221                _resolver.run();
 1222            }
 0223            catch (System.Exception ex)
 224            {
 0225                string s = "exception in endpoint host resolver thread " + _name + ":\n" + ex;
 0226                _resolver._instance.initializationData().logger.error(s);
 0227            }
 1228        }
 229
 1230        public string getName() => _name;
 231
 232        private readonly EndpointHostResolver _resolver;
 233        private readonly string _name;
 234        private Thread _thread;
 235    }
 236
 237    private readonly HelperThread _thread;
 238    private readonly object _mutex = new();
 239}