runtime/PLCObject.py
changeset 352 81777d4e379c
parent 350 a3a5561bde1d
child 353 c68fc75ebb06
equal deleted inserted replaced
351:89eca146bee0 352:81777d4e379c
    21 #You should have received a copy of the GNU General Public
    21 #You should have received a copy of the GNU General Public
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import Pyro.core as pyro
    25 import Pyro.core as pyro
    26 from threading import Timer, Thread
    26 from threading import Timer, Thread, Lock
    27 import ctypes, os, commands, types, sys
    27 import ctypes, os, commands, types, sys
    28 import time
    28 import time
    29 
    29 
    30 if os.name in ("nt", "ce"):
    30 if os.name in ("nt", "ce"):
    31     from _ctypes import LoadLibrary as dlopen
    31     from _ctypes import LoadLibrary as dlopen
    51         self.evaluator = evaluator
    51         self.evaluator = evaluator
    52         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    52         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    53         self.workingdir = workingdir
    53         self.workingdir = workingdir
    54         self.PLCStatus = "Stopped"
    54         self.PLCStatus = "Stopped"
    55         self.PLClibraryHandle = None
    55         self.PLClibraryHandle = None
       
    56         self.PLClibraryLock = Lock()
    56         # Creates fake C funcs proxies
    57         # Creates fake C funcs proxies
    57         self._FreePLC()
    58         self._FreePLC()
    58         self.daemon = daemon
    59         self.daemon = daemon
    59         self.statuschange = statuschange
    60         self.statuschange = statuschange
    60         self.hmi_frame = None
    61         self.hmi_frame = None
    91     
    92     
    92             self._startPLC = self.PLClibraryHandle.startPLC
    93             self._startPLC = self.PLClibraryHandle.startPLC
    93             self._startPLC.restype = ctypes.c_int
    94             self._startPLC.restype = ctypes.c_int
    94             self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
    95             self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
    95             
    96             
    96             self._stopPLC = self.PLClibraryHandle.stopPLC
    97             def StopPLCLock():
       
    98                 self.PLClibraryLock.acquire()
       
    99                 self.PLClibraryHandle.stopPLC()
       
   100                 self.PLClibraryLock.release()
       
   101             
       
   102             self._stopPLC = StopPLCLock
    97             self._stopPLC.restype = None
   103             self._stopPLC.restype = None
    98     
   104     
    99             self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
   105             self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
   100             self._ResetDebugVariables.restype = None
   106             self._ResetDebugVariables.restype = None
   101     
   107     
   131     def _FreePLC(self):
   137     def _FreePLC(self):
   132         """
   138         """
   133         Unload PLC library.
   139         Unload PLC library.
   134         This is also called by __init__ to create dummy C func proxies
   140         This is also called by __init__ to create dummy C func proxies
   135         """
   141         """
       
   142         self.PLClibraryLock.acquire()
   136         # Forget all refs to library
   143         # Forget all refs to library
   137         self._startPLC = lambda:None
   144         self._startPLC = lambda:None
   138         self._stopPLC = lambda:None
   145         self._stopPLC = lambda:None
   139         self._ResetDebugVariables = lambda:None
   146         self._ResetDebugVariables = lambda:None
   140         self._RegisterDebugVariable = lambda x:None
   147         self._RegisterDebugVariable = lambda x:None
   152             res = self._DetectDirtyLibs()
   159             res = self._DetectDirtyLibs()
   153         else:
   160         else:
   154             res = False
   161             res = False
   155 
   162 
   156         self._PLClibraryHandle = None
   163         self._PLClibraryHandle = None
   157 
   164         self.PLClibraryLock.release()
   158         return res
   165         return res
   159 
   166 
   160     def _DetectDirtyLibs(self):
   167     def _DetectDirtyLibs(self):
   161         # Detect dirty libs
   168         # Detect dirty libs
   162         # Get lib dependencies (for dirty lib detection)
   169         # Get lib dependencies (for dirty lib detection)
   249                     self._resumeDebug()
   256                     self._resumeDebug()
   250                 self.PLCStatus = "Started"
   257                 self.PLCStatus = "Started"
   251                 self.StatusChange()
   258                 self.StatusChange()
   252                 self.evaluator(self.PrepareRuntimePy)
   259                 self.evaluator(self.PrepareRuntimePy)
   253                 res,cmd = "None","None"
   260                 res,cmd = "None","None"
   254                 while self.PLCStatus == "Started":
   261                 while True:
   255                     #print "_PythonIterator(", res, ")",
   262                     #print "_PythonIterator(", res, ")",
   256                     cmd = self._PythonIterator(res)
   263                     cmd = self._PythonIterator(res)
   257                     #print " -> ", cmd
   264                     #print " -> ", cmd
   258                     if cmd is None:
   265                     if cmd is None:
   259                         break
   266                         break
   270         else:
   277         else:
   271             error = "loading"
   278             error = "loading"
   272         if error is not None:
   279         if error is not None:
   273             PLCprint("Problem %s PLC"%error)
   280             PLCprint("Problem %s PLC"%error)
   274             self.PLCStatus = "Broken"
   281             self.PLCStatus = "Broken"
   275         self._DoStopPLC()
       
   276         self._FreePLC()
   282         self._FreePLC()
   277         PLCprint("PythonThreadProc interrupted")
   283         PLCprint("PythonThreadProc interrupted")
   278     
   284     
   279     def StartPLC(self, debug=False):
   285     def StartPLC(self, debug=False):
   280         PLCprint("StartPLC")
   286         PLCprint("StartPLC")
   281         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
   287         if self.CurrentPLCFilename is not None:
   282             self.PythonThread = Thread(target=self.PythonThreadProc, args=[debug])
   288             self.PythonThread = Thread(target=self.PythonThreadProc, args=[debug])
   283             self.PythonThread.start()
   289             self.PythonThread.start()
   284 
   290             
   285     def _DoStopPLC(self):
       
   286         self.StatusChange()
       
   287         self._stopPLC()
       
   288         self.StatusChange()
       
   289         return True
       
   290 
       
   291     def StopPLC(self):
   291     def StopPLC(self):
   292         PLCprint("StopPLC")
   292         PLCprint("StopPLC")
   293         if self.PLCStatus == "Started":
   293         if self.PLCStatus == "Started":
   294             self._DoStopPLC()
   294             self._stopPLC()
   295             self.PLCStatus = "Stopped"
       
   296             return True
   295             return True
   297         return False
   296         return False
   298 
   297 
   299     def _Reload(self):
   298     def _Reload(self):
   300         self.daemon.shutdown(True)
   299         self.daemon.shutdown(True)