Moved serial transaction lock in order to encompass serial port teardown in case of error, to avoid deadlocks and multiple close in some cases
authorEdouard Tisserant
Mon, 29 Apr 2013 17:31:24 +0900
changeset 45 786b12887e91
parent 44 a6577420a27b
child 46 c6b7d4c176c2
Moved serial transaction lock in order to encompass serial port teardown in case of error, to avoid deadlocks and multiple close in some cases
LPCconnector/LPCAppProto.py
LPCconnector/LPCBootProto.py
LPCconnector/LPCObject.py
LPCconnector/LPCProto.py
--- a/LPCconnector/LPCAppProto.py	Mon Apr 29 17:29:59 2013 +0900
+++ b/LPCconnector/LPCAppProto.py	Mon Apr 29 17:31:24 2013 +0900
@@ -6,7 +6,6 @@
 
 class LPCAppProto(LPCProto):
     def HandleTransaction(self, transaction):
-        self.TransactionLock.acquire()
         try:
             transaction.SetPseudoFile(self.serialPort)
             # send command, wait ack (timeout)
@@ -18,8 +17,6 @@
                 raise LPCProtoError("controller did not answer as expected")
         except Exception, e:
             raise LPCProtoError("application mode transaction error : "+str(e))
-        finally:
-            self.TransactionLock.release()
         return LPC_STATUS.get(current_plc_status,"Broken"), res
     
 class LPCAppTransaction:
--- a/LPCconnector/LPCBootProto.py	Mon Apr 29 17:29:59 2013 +0900
+++ b/LPCconnector/LPCBootProto.py	Mon Apr 29 17:31:24 2013 +0900
@@ -2,12 +2,12 @@
 
 class LPCBootProto(LPCProto):
     def HandleTransaction(self, transaction):
-        self.TransactionLock.acquire()
+        res = None
         try:
             transaction.SetPseudoFile(self.serialPort)
             res = transaction.ExchangeData()
-        finally:
-            self.TransactionLock.release()
+        except:
+            pass
         return "Stopped", res
     
 class LPCBootTransaction:
--- a/LPCconnector/LPCObject.py	Mon Apr 29 17:29:59 2013 +0900
+++ b/LPCconnector/LPCObject.py	Mon Apr 29 17:31:24 2013 +0900
@@ -24,15 +24,13 @@
 
 from LPCProto import *
 
-
-
 class LPCObject():
     def __init__(self, confnodesroot, comportstr):
+        self.TransactionLock = Lock()
         self.PLCStatus = "Disconnected"
         self.confnodesroot = confnodesroot
         self.PLCprint = confnodesroot.logger.writeyield
         self._Idxs = []
-        comport = int(comportstr[3:]) - 1
         try:
             self.connect(comportstr)
         except Exception,e:
@@ -41,19 +39,28 @@
             self.PLCStatus = "Disconnected"
 
     def HandleSerialTransaction(self, transaction):
+        res = None
+        disconnected=False
+        failure=None
+        self.TransactionLock.acquire()
         if self.SerialConnection is not None:
             try:
-                self.PLCStatus, res = self.SerialConnection.HandleTransaction(transaction)
-                return res
+                self.PLCStatus, res = \
+                    self.SerialConnection.HandleTransaction(transaction)
             except LPCProtoError,e:
-                self.confnodesroot.logger.write(_("PLC disconnected\n"))
+                disconnected=True
                 if self.SerialConnection is not None:
                     self.SerialConnection.close()
                     self.SerialConnection = None
                 self.PLCStatus = "Disconnected"
-                return None
             except Exception,e:
-                self.confnodesroot.logger.write_warning(str(e)+"\n")
+                failure = str(e)
+        self.TransactionLock.release()
+        if disconnected:
+            self.confnodesroot.logger.write(_("PLC disconnected\n"))
+        if failure is not None:
+            self.confnodesroot.logger.write_warning(failure+"\n")
+        return res
         
     def StartPLC(self, debug=False):
         raise LPCProtoError("Not implemented")
--- a/LPCconnector/LPCProto.py	Mon Apr 29 17:29:59 2013 +0900
+++ b/LPCconnector/LPCProto.py	Mon Apr 29 17:31:24 2013 +0900
@@ -14,7 +14,6 @@
 class LPCProto:
     def __init__(self, port, rate, timeout):
         # serialize access lock
-        self.TransactionLock = Lock()
         if BMZ_DBG:
             # Debugging serial stuff
             self._serialPort = serial.Serial( port, rate, timeout = timeout, writeTimeout = timeout )