소스 검색

fix network methods not shutting down

Luke Pulverenti 8 년 전
부모
커밋
5759ba8656
1개의 변경된 파일107개의 추가작업 그리고 82개의 파일을 삭제
  1. 107 82
      Mono.Nat/NatUtility.cs

+ 107 - 82
Mono.Nat/NatUtility.cs

@@ -41,26 +41,25 @@ using MediaBrowser.Model.Logging;
 
 namespace Mono.Nat
 {
-	public static class NatUtility
-	{
-        private static ManualResetEvent searching;
-		public static event EventHandler<DeviceEventArgs> DeviceFound;
-		public static event EventHandler<DeviceEventArgs> DeviceLost;
-        
-		private static List<ISearcher> controllers;
-		private static bool verbose;
+    public static class NatUtility
+    {
+        public static event EventHandler<DeviceEventArgs> DeviceFound;
+        public static event EventHandler<DeviceEventArgs> DeviceLost;
+
+        private static List<ISearcher> controllers;
+        private static bool verbose;
 
         public static List<NatProtocol> EnabledProtocols { get; set; }
 
-	    public static ILogger Logger { get; set; }
+        public static ILogger Logger { get; set; }
         public static IHttpClient HttpClient { get; set; }
 
         public static bool Verbose
-		{
-			get { return verbose; }
-			set { verbose = value; }
-		}
-		
+        {
+            get { return verbose; }
+            set { verbose = value; }
+        }
+
         static NatUtility()
         {
             EnabledProtocols = new List<NatProtocol>
@@ -68,8 +67,6 @@ namespace Mono.Nat
                 NatProtocol.Pmp
             };
 
-            searching = new ManualResetEvent(false);
-
             controllers = new List<ISearcher>();
             controllers.Add(PmpSearcher.Instance);
 
@@ -86,23 +83,19 @@ namespace Mono.Nat
                             DeviceLost(sender, args);
                     };
                 });
-
-            Task.Factory.StartNew(SearchAndListen, TaskCreationOptions.LongRunning);
         }
 
-		internal static void Log(string format, params object[] args)
-		{
-			var logger = Logger;
-		    if (logger != null)
-		        logger.Debug(format, args);
-		}
+        internal static void Log(string format, params object[] args)
+        {
+            var logger = Logger;
+            if (logger != null)
+                logger.Debug(format, args);
+        }
 
-        private static async Task SearchAndListen()
+        private static async Task SearchAndListen(CancellationToken cancellationToken)
         {
-            while (true)
+            while (!cancellationToken.IsCancellationRequested)
             {
-                searching.WaitOne();
-
                 try
                 {
                     var enabledProtocols = EnabledProtocols.ToList();
@@ -123,67 +116,99 @@ namespace Mono.Nat
                 }
                 catch (Exception e)
                 {
-                    
+
                 }
                 await Task.Delay(100).ConfigureAwait(false);
             }
-		}
-
-		static async Task Receive (ISearcher searcher, List<UdpClient> clients)
-		{
-			foreach (UdpClient client in clients)
-			{
-				if (client.Available > 0)
-				{
-				    IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
-				    var result = await client.ReceiveAsync().ConfigureAwait(false);
-				    var data = result.Buffer;
-				    var received = result.RemoteEndPoint;
-					searcher.Handle(localAddress, data, received);
-				}
+        }
+
+        static async Task Receive(ISearcher searcher, List<UdpClient> clients)
+        {
+            foreach (UdpClient client in clients)
+            {
+                if (client.Available > 0)
+                {
+                    IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
+                    var result = await client.ReceiveAsync().ConfigureAwait(false);
+                    var data = result.Buffer;
+                    var received = result.RemoteEndPoint;
+                    searcher.Handle(localAddress, data, received);
+                }
+            }
+        }
+
+        private static CancellationTokenSource _currentCancellationTokenSource;
+        private static object _runSyncLock = new object();
+        public static void StartDiscovery()
+        {
+            lock (_runSyncLock)
+            {
+                if (_currentCancellationTokenSource == null)
+                {
+                    return;
+                }
+
+                var tokenSource = new CancellationTokenSource();
+
+                _currentCancellationTokenSource = tokenSource;
+                //Task.Factory.StartNew(() => SearchAndListen(tokenSource.Token), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
             }
         }
-		
-		public static void StartDiscovery ()
-		{
-            searching.Set();
-		}
-
-		public static void StopDiscovery ()
-		{
-            searching.Reset();
-		}
-		
-		//checks if an IP address is a private address space as defined by RFC 1918
-		public static bool IsPrivateAddressSpace (IPAddress address)
-		{
-			byte[] ba = address.GetAddressBytes ();
-
-			switch ((int)ba[0]) {
-			case 10:
-				return true; //10.x.x.x
-			case 172:
-				return ((int)ba[1] & 16) != 0; //172.16-31.x.x
-			case 192:
-				return (int)ba[1] == 168; //192.168.x.x
-			default:
-				return false;
-			}
-		}
-
-	    public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
-	    {
-	        switch (protocol)
-	        {
+
+        public static void StopDiscovery()
+        {
+            lock (_runSyncLock)
+            {
+                var tokenSource = _currentCancellationTokenSource;
+
+                if (tokenSource != null)
+                {
+                    try
+                    {
+                        tokenSource.Cancel();
+                        tokenSource.Dispose();
+                    }
+                    catch
+                    {
+
+                    }
+
+                    _currentCancellationTokenSource = null;
+                }
+            }
+        }
+
+        //checks if an IP address is a private address space as defined by RFC 1918
+        public static bool IsPrivateAddressSpace(IPAddress address)
+        {
+            byte[] ba = address.GetAddressBytes();
+
+            switch ((int)ba[0])
+            {
+                case 10:
+                    return true; //10.x.x.x
+                case 172:
+                    return ((int)ba[1] & 16) != 0; //172.16-31.x.x
+                case 192:
+                    return (int)ba[1] == 168; //192.168.x.x
+                default:
+                    return false;
+            }
+        }
+
+        public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
+        {
+            switch (protocol)
+            {
                 case NatProtocol.Upnp:
-	                //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
-	                break;
+                    //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
+                    break;
                 case NatProtocol.Pmp:
-	                PmpSearcher.Instance.Handle(localAddress, response, endpoint);
-	                break;
-	            default:
-	                throw new ArgumentException("Unexpected protocol: " + protocol);
-	        }
+                    PmpSearcher.Instance.Handle(localAddress, response, endpoint);
+                    break;
+                default:
+                    throw new ArgumentException("Unexpected protocol: " + protocol);
+            }
         }
 
         public static void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)