Added watchdog for hanging apps
This commit is contained in:
		@@ -6,6 +6,9 @@ ScreenY = 40
 | 
			
		||||
 | 
			
		||||
Serial = "/dev/ttyACM0"
 | 
			
		||||
 | 
			
		||||
# kills app after some seconds if it sends no data
 | 
			
		||||
NoDataTimeout = 10
 | 
			
		||||
 | 
			
		||||
# first app is always running in IDLE    
 | 
			
		||||
Apps = [
 | 
			
		||||
    {"name": "pixelflut", "cmd": "apps/idle.py", "permanent": True},
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								main.py
									
									
									
									
									
								
							@@ -16,7 +16,6 @@ class SerialWriter(threading.Thread):
 | 
			
		||||
    def setData(self, data):
 | 
			
		||||
        with self.lock:
 | 
			
		||||
            self.data = data
 | 
			
		||||
        pass
 | 
			
		||||
    
 | 
			
		||||
    def run(self):
 | 
			
		||||
        should_connect = True
 | 
			
		||||
@@ -38,6 +37,16 @@ class SerialWriter(threading.Thread):
 | 
			
		||||
                time.sleep(0.1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WatchDog(threading.Thread):
 | 
			
		||||
    def __init__(self, check, action):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.check = check
 | 
			
		||||
        self.action = action
 | 
			
		||||
    def run(self):
 | 
			
		||||
        while True:
 | 
			
		||||
            if self.check():
 | 
			
		||||
                self.action()
 | 
			
		||||
            time.sleep(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AppRunner(threading.Thread):
 | 
			
		||||
@@ -50,17 +59,32 @@ class AppRunner(threading.Thread):
 | 
			
		||||
        self.param = ""
 | 
			
		||||
        self.serial = SerialWriter()
 | 
			
		||||
        self.serial.start()
 | 
			
		||||
        self.last_update = time.time()
 | 
			
		||||
        self.watchdog = WatchDog(lambda: self.appTimedOut(), lambda: self.terminateApp())
 | 
			
		||||
        self.watchdog.start()
 | 
			
		||||
 | 
			
		||||
    def requestApp(self, app, param=""):
 | 
			
		||||
        with self.lock:
 | 
			
		||||
            self.requestedApp = app
 | 
			
		||||
            self.param = param
 | 
			
		||||
 | 
			
		||||
    def terminateApp(self):
 | 
			
		||||
        if self.app != None:
 | 
			
		||||
            # don't ask
 | 
			
		||||
            self.app.terminate()
 | 
			
		||||
            self.app.kill()
 | 
			
		||||
            self.app.stdout.close()
 | 
			
		||||
            self.last_update = time.time()
 | 
			
		||||
        self.requestApp = 0
 | 
			
		||||
 | 
			
		||||
    def appTimedOut(self):
 | 
			
		||||
        return time.time()-self.last_update > config.NoDataTimeout
 | 
			
		||||
 | 
			
		||||
    def updateApp(self):
 | 
			
		||||
        if self.app != None:
 | 
			
		||||
            self.app.terminate()
 | 
			
		||||
        args = [os.getcwd()+"/"+config.Apps[self.requestedApp]["cmd"], str(config.ScreenX), str(config.ScreenY), self.param]
 | 
			
		||||
        self.app = subprocess.Popen(args, stdout=subprocess.PIPE)
 | 
			
		||||
        self.app = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        while True:
 | 
			
		||||
@@ -73,8 +97,12 @@ class AppRunner(threading.Thread):
 | 
			
		||||
                    self.requestedApp = None
 | 
			
		||||
            d = self.app.stdout
 | 
			
		||||
            oshandle = d.fileno()
 | 
			
		||||
            data = os.read(oshandle, config.ScreenX*config.ScreenY*3)
 | 
			
		||||
            self.serial.setData(data)
 | 
			
		||||
            try:
 | 
			
		||||
                data = os.read(oshandle, config.ScreenX*config.ScreenY*3)
 | 
			
		||||
                self.last_update = time.time()
 | 
			
		||||
                self.serial.setData(data)
 | 
			
		||||
            except:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
runner = AppRunner()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user