def log (what):
logger.log(what)
+
+# Threaded callback class
+class ThreadFunction():
+ _CALL = 0
+ _TERM = 1
+
+ def __init__(self, f):
+ self._f = f
+ self._q = queue.Queue()
+ self._t = threading.Thread(target=self._thread_func)
+ self._t.start()
+
+ def _thread_func(self):
+ while True:
+ (cmd, data) = self._q.get()
+ # run command
+ if cmd == _CALL:
+ self._f(*data)
+ elif cmd == _TERM:
+ assert data is None
+ break
+ else:
+ raise NotImplementedError("Command %d does not exist" % cmd)
+
+ def __call__(self, *arg):
+ self._q.put((self._CALL, arg))
+
+ def stop(self):
+ self._q.put((_TERM, None))
+ self._t.join()
#!/usr/bin/python3
import time, socket, atexit
import queue, threading, select
-from libtuer import log
+from libtuer import log, ThreadFunction
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
atexit.register(GPIO.cleanup)
tuerSock = "/run/tuer.sock"
ringPin = 18
+
# Main classes
class PinWatcher():
def __init__(self, pin, histlen):
self._newstate = None # != None iff we are currently seeing a state change
self._newstatelen = 0 # only valid if newstate != None
# start state change handler thread
- self._q = queue.Queue()
- self._t = threading.Thread(target=self.queue_consumer)
- self._t.start()
-
- def queue_consumer(self):
- while True:
- el = self._q.get()
- if el is None: return # we are supposed to terminate
- # handle the state change
- (oldstate, newstate) = el
- self.callback(oldstate, newstate)
+ self._callback = ThreadFunction(self.callback)
+ self.stop = self._callback.stop
def read(self):
curstate = GPIO.input(self._pin)
# we already saw this new state
self._newstatelen += 1
if self._newstatelen >= self._histlen:
- self._q.put((self._state, curstate)) # send stuff to the other thread
+ self._callback(self._state, curstate) # send stuff to the other thread
self._state = curstate
self._newstate = None
else:
else:
# old state is preserved
self._newstate = None
-
- def quit(self):
- self._q.put(None)
- self._t.join()
class RingWatcher(PinWatcher):
def __init__(self):
time.sleep(0.02)
except KeyboardInterrupt:
for pin in pins:
- pin.quit()
+ pin.stop()