util/ProcessLogger.py
changeset 1649 3291024e00da
parent 1581 2295fdc5c271
child 1730 64d8f52bc8c8
equal deleted inserted replaced
1648:6431f26aa501 1649:3291024e00da
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 
     3 
     4 #This file is part of Beremiz, a Integrated Development Environment for
     4 # This file is part of Beremiz, a Integrated Development Environment for
     5 #programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
     5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
     6 #
     6 #
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     8 #
     8 #
     9 #See COPYING file for copyrights details.
     9 # See COPYING file for copyrights details.
    10 #
    10 #
    11 #This library is free software; you can redistribute it and/or
    11 # This program is free software; you can redistribute it and/or
    12 #modify it under the terms of the GNU General Public
    12 # modify it under the terms of the GNU General Public License
    13 #License as published by the Free Software Foundation; either
    13 # as published by the Free Software Foundation; either version 2
    14 #version 2.1 of the License, or (at your option) any later version.
    14 # of the License, or (at your option) any later version.
    15 #
    15 #
    16 #This library is distributed in the hope that it will be useful,
    16 # This program is distributed in the hope that it will be useful,
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
    17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19 #General Public License for more details.
    19 # GNU General Public License for more details.
    20 #
    20 #
    21 #You should have received a copy of the GNU General Public
    21 # You should have received a copy of the GNU General Public License
    22 #License along with this library; if not, write to the Free Software
    22 # along with this program; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
       
    25 
    24 
    26 import time
    25 import time
    27 import wx
    26 import wx
    28 import subprocess, ctypes
    27 import subprocess, ctypes
    29 from threading import Timer, Lock, Thread, Semaphore
    28 from threading import Timer, Lock, Thread, Semaphore
   107         self.exitcode = None
   106         self.exitcode = None
   108         self.outdata = []
   107         self.outdata = []
   109         self.errdata = []
   108         self.errdata = []
   110         self.keyword = keyword
   109         self.keyword = keyword
   111         self.kill_it = kill_it
   110         self.kill_it = kill_it
       
   111         self.startsem = Semaphore(0)        
   112         self.finishsem = Semaphore(0)
   112         self.finishsem = Semaphore(0)
   113         self.endlock = Lock()
   113         self.endlock = Lock()
   114 
   114 
   115         popenargs= {
   115         popenargs= {
   116                "cwd":os.getcwd() if cwd is None else cwd,
   116                "cwd":os.getcwd() if cwd is None else cwd,
   143         self.errt = outputThread(
   143         self.errt = outputThread(
   144                       self.Proc,
   144                       self.Proc,
   145                       self.Proc.stderr,
   145                       self.Proc.stderr,
   146                       self.errors)
   146                       self.errors)
   147         self.errt.start()
   147         self.errt.start()
       
   148         self.startsem.release()
   148 
   149 
   149 
   150 
   150     def output(self,v):
   151     def output(self,v):
   151         self.outdata.append(v)
   152         self.outdata.append(v)
   152         self.outlen += 1
   153         self.outlen += 1
   163         if self.errlimit and self.errlen > self.errlimit:
   164         if self.errlimit and self.errlen > self.errlimit:
   164             self.endlog()
   165             self.endlog()
   165 
   166 
   166     def log_the_end(self,ecode,pid):
   167     def log_the_end(self,ecode,pid):
   167         self.logger.write(self.Command_str + "\n")
   168         self.logger.write(self.Command_str + "\n")
   168         self.logger.write_warning(_("exited with status %s (pid %s)\n")%(str(ecode),str(pid)))
   169         self.logger.write_warning(_("exited with status {a1} (pid {a2})\n").format(a1 = str(ecode), a2 = str(pid)))
   169 
   170 
   170     def finish(self, pid,ecode):
   171     def finish(self, pid,ecode):
       
   172         # avoid running function before start is finished        
       
   173         self.startsem.acquire()
   171         if self.timeout:
   174         if self.timeout:
   172             self.timeout.cancel()
   175             self.timeout.cancel()
   173         self.exitcode = ecode
   176         self.exitcode = ecode
   174         if self.exitcode != 0:
   177         if self.exitcode != 0:
   175             self.log_the_end(ecode,pid)
   178             self.log_the_end(ecode,pid)
   177             self.finish_callback(self,ecode,pid)
   180             self.finish_callback(self,ecode,pid)
   178         self.errt.join()
   181         self.errt.join()
   179         self.finishsem.release()
   182         self.finishsem.release()
   180 
   183 
   181     def kill(self,gently=True):
   184     def kill(self,gently=True):
       
   185         # avoid running kill before start is finished
       
   186         self.startsem.acquire()
       
   187         self.startsem.release()
       
   188         
   182         self.outt.killed = True
   189         self.outt.killed = True
   183         self.errt.killed = True
   190         self.errt.killed = True
   184         if wx.Platform == '__WXMSW__':
   191         if wx.Platform == '__WXMSW__':
   185             PROCESS_TERMINATE = 1
   192             PROCESS_TERMINATE = 1
   186             handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.Proc.pid)
   193             handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.Proc.pid)