def __init__(self, path):

        """Initialise the class instance. This remembers the path identiy
        and sets up the object's 'action' queue."""

        # Always initialise the parent class instance...
        super().__init__()

        assert 0 < path <= Control.num_paths(), \
            "Invalid strobe ID (%s)" % path
        self.path = path

        # Create our 'action' queue.
        # STOP, START and QUIT commands are supplied to us through this queue.
        # The queue is a small, limited size. When full the queue will block.
        self.action_queue = queue.LifoQueue(_QUEUE_SIZE)

        # We operate a counter (pending count) that is incremented when
        # actions are placed in the queue and decremented after they have
        # been taken out and processed. This allows the 'wait()' method
        # to operate correctly - i.e. wait until a) the action queue
        # is empty and the event has also been processed. The value is
        # incremented for each put and decremented at the end of the run()
        # code.
        self.pending_count = 0
        self.pending_count_lock = threading.Lock()

        # Timestamp of last 'demand' input
        self.last_demand_time = None

        # Flag, cleared to exit the thread run() loop
        self.running = True
    def test_reset(self):

        Control.reset()
        # Validate...
        a, b, path = Control.get_last_set_data()
        self.assertFalse(a)
        self.assertFalse(b)
        self.assertEqual(Control.num_paths(), path)
    def test_invalid_path_controller(self):

        with self.assertRaises(AssertionError):
            PathController.PathController(Control.num_paths() + 1)