From 8d2900af0b4d26e447246c82e2296b08cd59ebf3 Mon Sep 17 00:00:00 2001 From: Generoso Martello Date: Thu, 5 Nov 2015 00:20:03 +0100 Subject: [PATCH] reverted to using Thread instead of Task --- XTenLib/Drivers/CM15.cs | 3 +- XTenLib/XTenManager.cs | 134 ++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 67 deletions(-) diff --git a/XTenLib/Drivers/CM15.cs b/XTenLib/Drivers/CM15.cs index 378b716..4aaad06 100644 --- a/XTenLib/Drivers/CM15.cs +++ b/XTenLib/Drivers/CM15.cs @@ -129,7 +129,6 @@ public bool Open() /// public void Close() { - this.Dispose(); if (myUsbDevice != null) { if (myUsbDevice.DriverMode == UsbDevice.DriverModeType.MonoLibUsb) @@ -144,6 +143,8 @@ public void Close() } } myUsbDevice = null; + UsbDevice.Exit(); + this.Dispose(); } } diff --git a/XTenLib/XTenManager.cs b/XTenLib/XTenManager.cs index fc8422b..6066245 100644 --- a/XTenLib/XTenManager.cs +++ b/XTenLib/XTenManager.cs @@ -82,12 +82,13 @@ public class XTenManager private bool gotReadWriteError = true; // X10 interface reader Task - private Task readerTask; - private CancellationTokenSource readerTokenSource; + private Thread reader; // X10 interface connection watcher - private Task connectionWatcher; - private CancellationTokenSource watcherTokenSource; + private Thread connectionWatcher; + + private object accessLock = new object(); + private bool disconnectRequested = false; // This is used on Linux/Mono for detecting when the link gets disconnected private int zeroChecksumCount = 0; @@ -195,12 +196,16 @@ public XTenManager() /// public bool Connect() { - Disconnect(); - bool returnValue = Open(); - gotReadWriteError = !returnValue; - watcherTokenSource = new CancellationTokenSource(); - connectionWatcher = Task.Factory.StartNew(() => ConnectionWatcherTask(watcherTokenSource.Token), watcherTokenSource.Token); - return returnValue; + if (disconnectRequested) + return false; + lock (accessLock) + { + Disconnect(); + Open(); + connectionWatcher = new Thread(ConnectionWatcherTask); + connectionWatcher.Start(); + } + return IsConnected; } /// @@ -208,23 +213,20 @@ public bool Connect() /// public void Disconnect() { - if (connectionWatcher != null) + if (disconnectRequested) + return; + disconnectRequested = true; + Close(); + lock (accessLock) { - watcherTokenSource.Cancel(); - try - { - connectionWatcher.Wait(5000); - } - catch (AggregateException e) + if (connectionWatcher != null) { - logger.Error(e); + if (!connectionWatcher.Join(5000)) + connectionWatcher.Abort(); + connectionWatcher = null; } - if (connectionWatcher != null) - connectionWatcher.Dispose(); - connectionWatcher = null; - watcherTokenSource = null; + disconnectRequested = false; } - Close(); } /// @@ -233,7 +235,7 @@ public void Disconnect() /// true if connected; otherwise, false. public bool IsConnected { - get { return isInterfaceReady || (!gotReadWriteError && x10interface.GetType().Equals(typeof(CM15))); } + get { return (x10interface != null && !disconnectRequested && (isInterfaceReady || (!gotReadWriteError && x10interface.GetType().Equals(typeof(CM15))))); } } /// @@ -248,8 +250,10 @@ public string PortName { if (portName != value) { + // set to erro so that the connection watcher will reconnect + // using the new port Close(); - + // instantiate the requested interface if (value.ToUpper() == "USB") { x10interface = new CM15(); @@ -258,8 +262,6 @@ public string PortName { x10interface = new CM11(value); } - - gotReadWriteError = true; } portName = value; } @@ -724,52 +726,54 @@ private void Module_PropertyChanged(object sender, PropertyChangedEventArgs args private bool Open() { - Close(); - bool success = (x10interface != null && x10interface.Open()); - if (success) + bool success = false; + lock (accessLock) { - if (x10interface.GetType().Equals(typeof(CM15))) + Close(); + success = (x10interface != null && x10interface.Open()); + if (success) { - // Set transceived house codes for CM15 X10 RF-->PLC - InitializeCm15(); - OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs(true)); + if (x10interface.GetType().Equals(typeof(CM15))) + { + // Set transceived house codes for CM15 X10 RF-->PLC + InitializeCm15(); + // For CM15 we do not need to receive ACK message to claim status as connected + OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs(true)); + } + // Start the Reader task + gotReadWriteError = false; + // Start the Reader task + reader = new Thread(ReaderTask); + reader.Start(); } - // Start the Reader task - readerTokenSource = new CancellationTokenSource(); - readerTask = Task.Factory.StartNew(() => ReaderTask(readerTokenSource.Token), readerTokenSource.Token); } return success; } private void Close() { - // Stop the Reader task - if (readerTask != null) + UnselectModules(); + lock (accessLock) { - readerTokenSource.Cancel(); + // Dispose the X10 interface try { - readerTask.Wait(5000); + x10interface.Close(); } - catch (AggregateException e) + catch (Exception e) { logger.Error(e); } - if (readerTask != null) - readerTask.Dispose(); - readerTask = null; - readerTokenSource = null; - } - // Dispose the X10 interface - try - { - x10interface.Close(); - } - catch (Exception e) - { - logger.Error(e); + gotReadWriteError = true; + // Stop the Reader task + if (reader != null) + { + if (!reader.Join(5000)) + reader.Abort(); + reader = null; + } + OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs(false)); } - OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs(false)); } private void SendMessage(byte[] message) @@ -846,9 +850,9 @@ private void SendMessage(byte[] message) } } - private void ReaderTask(CancellationToken readerToken) + private void ReaderTask() { - while (!readerToken.IsCancellationRequested) + while (IsConnected) { try { @@ -1133,7 +1137,6 @@ private void ReaderTask(CancellationToken readerToken) { zeroChecksumCount = 0; gotReadWriteError = true; - Close(); } else { @@ -1156,26 +1159,24 @@ private void ReaderTask(CancellationToken readerToken) } } - private void ConnectionWatcherTask(CancellationToken watcherToken) + private void ConnectionWatcherTask() { // This task takes care of automatically reconnecting the interface // when the connection is drop or if an I/O error occurs - while (!watcherToken.IsCancellationRequested) + while (!disconnectRequested) { if (gotReadWriteError) { - OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs(false)); try { - UnselectModules(); Close(); // wait 3 secs before reconnecting Thread.Sleep(3000); - if (!watcherToken.IsCancellationRequested) + if (!disconnectRequested) { try { - gotReadWriteError = !Open(); + Open(); } catch (Exception e) { @@ -1188,7 +1189,8 @@ private void ConnectionWatcherTask(CancellationToken watcherToken) logger.Error(e); } } - Thread.Sleep(1000); + if (!disconnectRequested) + Thread.Sleep(1000); } }