safeThread.py (5398B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\util\safeThread.py 2 from __future__ import print_function 3 import sys 4 import traceback 5 import blue 6 import uthread 7 from carbon.common.script.util import debug, timerstuff 8 from carbon.common.lib import const 9 from eveprefs import prefs 10 from carbon.common.script.util import logUtil as log 11 12 class SafeThread(object): 13 KILL_ME = 145686248 14 MAX_REPAIR_ATTEMPTS = 10 15 16 def init(self, uniqueIDstring): 17 args = blue.pyos.GetArg()[1:] 18 if ('/debug' in args or '/jessica' in args) and not prefs.GetValue('neverDebug', False): 19 self.__debugging = False 20 self.MAX_REPAIR_ATTEMPTS = 1000 21 else: 22 self.__debugging = False 23 self.uniqueIDstring = uniqueIDstring 24 self.__killLoop = True 25 self.__thread = None 26 self.__active = False 27 self.rep = True 28 self.repairCount = 0 29 self.__sleepTime = None 30 31 def __MainLoop(self): 32 blue.pyos.synchro.Yield() 33 try: 34 while self.__killLoop == False: 35 now = blue.os.GetWallclockTime() 36 if self.__debugging: 37 try: 38 if timerstuff.ClockThis(self.uniqueIDstring + '::SafeThreadLoop', self.SafeThreadLoop, now) == self.KILL_ME: 39 self.__killLoop = True 40 except SystemExit: 41 raise 42 except TaskletExit: 43 self.__killLoop = True 44 except Exception as inst: 45 self.__killLoop = True 46 print('SafeThread.__MainLoop - Unhandled Exception: ' + self.uniqueIDstring) 47 print('Repair attempts remaining:', self.MAX_REPAIR_ATTEMPTS - self.repairCount - 1, '\n') 48 log.LogException() 49 print(traceback.print_tb(sys.exc_info()[2])) 50 print(inst) 51 print(inst.__doc__) 52 debug.startDebugging() 53 uthread.new(self.__RestoreSafeThreadLoop) 54 55 else: 56 try: 57 if timerstuff.ClockThis(self.uniqueIDstring + '::SafeThreadLoop', self.SafeThreadLoop, now) == self.KILL_ME: 58 self.__killLoop = True 59 except SystemExit: 60 raise 61 except TaskletExit: 62 self.__killLoop = True 63 except Exception as e: 64 self.__killLoop = True 65 print('SafeThread.__MainLoop - Unhandled Exception: ' + self.uniqueIDstring, '\n Debug mode is off, skipping straight to repair') 66 print('Repair attempts remaining:', self.MAX_REPAIR_ATTEMPTS - self.repairCount - 1, '\n') 67 print(traceback.print_tb(sys.exc_info()[2])) 68 log.LogException() 69 uthread.new(self.__RestoreSafeThreadLoop) 70 self.__thread = None 71 self.__active = False 72 self.__killLoop = True 73 raise e 74 75 blue.pyos.synchro.SleepWallclock(self.__sleepTime) 76 77 self.__thread = None 78 self.__active = False 79 except AttributeError: 80 sys.exc_clear() 81 82 def SafeThreadLoop(self, now): 83 print('ERROR: Please implement the virtual SafeThreadLoop function') 84 return self.KILL_ME 85 86 def KillLoop(self): 87 self.__killLoop = True 88 89 def Disabledebugging(self): 90 self.__debugging = False 91 92 def Enabledebugging(self): 93 self.__debugging = True 94 95 def LaunchSafeThreadLoop_MS(self, sleepTime = 16): 96 if self.__active == False: 97 self.__sleepTime = sleepTime 98 self.__active = True 99 self.__killLoop = False 100 self.__thread = uthread.new(self.__MainLoop) 101 self.__thread.context = self.uniqueIDstring 102 else: 103 log.LogError('ERROR: This class is already looping SafeThreadLoop function', self) 104 105 def LaunchSafeThreadLoop_BlueTime(self, sleepTime = const.ONE_TICK): 106 self.LaunchSafeThreadLoop_MS(sleepTime / const.MSEC) 107 108 def __RestoreSafeThreadLoop(self): 109 if self.repairCount < self.MAX_REPAIR_ATTEMPTS: 110 self.repairCount += 1 111 self.__WaitForRestart() 112 if self.rep: 113 self.RepairMe() 114 self.LaunchSafeThreadLoop_MS(self.__sleepTime) 115 116 def __WaitForRestart(self): 117 while self.__active == True or self.__killLoop == False or self.__thread is not None: 118 blue.pyos.synchro.SleepUntilWallclock(blue.os.GetWallclockTimeNow() + 100 * const.MSEC) 119 120 def RepairMe(self): 121 pass 122 123 124 def SleepAndCallAtTime(launchTime, function, *args, **kwargs): 125 if blue.os.GetWallclockTimeNow() < launchTime: 126 blue.pyos.synchro.SleepUntilWallclock(launchTime) 127 else: 128 blue.pyos.synchro.Yield() 129 function(*args, **kwargs) 130 131 132 def DoMethodLater(waitDuration, launchFunction, *args, **kwargs): 133 launchTime = blue.os.GetWallclockTime() + waitDuration 134 uthread.worker(('doMethodLater-' + launchFunction.__name__), SleepAndCallAtTime, launchTime, launchFunction, *args, **kwargs)