15 from signal
import getsignal, signal, SIGKILL, SIGINT, SIGTERM, \
16 SIG_DFL, default_int_handler, SIG_IGN
30 Capture and replace a signal handler with a user supplied function. 31 The user supplied function is always called first then the previous 32 handler, if it exists, will be called. It is possible to chain several 33 signal handlers together by creating multiply instances of objects of 34 this class, providing a different user functions for each instance. All 35 provided user functions will be called in LIFO order. 45 Create an instance of the signal handler class. 47 sig_value: The ID value of the signal to be captured. 48 func: User supplied function that will act as the new signal handler. 51 self.__sig_value = sig_value
52 self.__user_func = func
53 self.__previous_func = signal(sig_value, self)
54 self.__previous_func = {
55 SIG_DFL: default_int_handler,
56 SIG_IGN:
lambda a, b:
None 57 }.
get(self.__previous_func, self.__previous_func)
63 Allows the instance of this class to be called as a function. 64 When called it runs the user supplied signal handler than 65 checks to see if there is a previously defined handler. If 66 there is a previously defined handler call it. 69 self.__previous_func(signame, sf)
75 Class destructor. Called during garbage collection. 76 Resets the signal handler to the previous function. 78 signal(self.__sig_value, self.__previous_func)
93 Create and maintains the PID lock file for this application process. 94 The PID lock file is located in /tmp/mycroft/*.pid. If another process 95 of the same type is started, this class will 'attempt' to stop the 96 previously running process and then change the process ID in the lock file. 101 DIRECTORY =
'/tmp/mycroft' 108 Builds the instance of this object. Holds the lock until the 109 object is garbage collected. 111 service: Text string. The name of the service application 112 to be locked (ie: skills, voice) 115 self.__pid = os.getpid()
116 self.path = Lock.DIRECTORY + Lock.FILE.format(service)
124 Trap both SIGINT and SIGTERM to gracefully clean up PID files 126 self.__handlers = {SIGINT:
Signal(SIGINT, self.delete),
127 SIGTERM:
Signal(SIGTERM, self.delete)}
136 Check to see if the PID lock file currently exists. If it does 137 than send a SIGTERM signal to the process defined by the value 138 in the lock file. Catch the keyboard interrupt exception to 139 prevent propagation if stopped by use of Ctrl-C. 141 if not os.path.isfile(self.path):
143 with open(self.path,
'r') as L: 145 os.kill(int(L.read()), SIGKILL)
146 except Exception
as E:
153 If needed, create the '/tmp/mycroft' directory than open the 154 lock file for writting and store the current process ID (PID) 157 if not os.path.exists(Lock.DIRECTORY):
158 os.makedirs(Lock.DIRECTORY)
159 with open(self.path,
'w')
as L:
160 L.write(
'{}'.format(self.__pid))
166 Checks to see if a lock file for this service already exists, 167 if so have it killed. In either case write the process ID of 168 the current service process to to the existing or newly created 169 lock file in /tmp/mycroft/ 179 If the PID lock file contains the PID of this process delete it. 181 *args: Ignored. Required as this fuction is called as a signel 185 with open(self.path,
'r') as L: 187 if self.__pid == pid:
def __call__(self, signame, sf)
def __init__(self, sig_value, func)
def get(phrase, lang=None, context=None)