def readout(self, fifo, no_data_timeout=None):
logging.info('<STR_LIT>', fifo)<EOL>time_last_data = time()<EOL>time_wait = <NUM_LIT:0.0><EOL>empty_reads = <NUM_LIT:0><EOL>while not self.force_stop[fifo].wait(time_wait if time_wait >= <NUM_LIT:0.0> else <NUM_LIT:0.0>):<EOL><INDENT>time_read = time()<EOL>try:<EOL><INDENT>if no_data_timeout and time_last_data + no_data_timeout < get_float_time():<EOL><INDENT>raise NoDataTimeout('<STR_LIT>' % (no_data_timeout, fifo))<EOL><DEDENT>raw_data = self.read_raw_data_from_fifo(fifo)<EOL><DEDENT>except NoDataTimeout:<EOL><INDENT>no_data_timeout = None  <EOL>if self.errback:<EOL><INDENT>self.errback(sys.exc_info())<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>if self.errback:<EOL><INDENT>self.errback(sys.exc_info())<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT>if self.stop_readout.is_set():  <EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>n_data_words = raw_data.shape[<NUM_LIT:0>]<EOL>if n_data_words > <NUM_LIT:0>:<EOL><INDENT>time_last_data = time()<EOL>empty_reads = <NUM_LIT:0><EOL>time_start_read, time_stop_read = self.update_timestamp(fifo)<EOL>status = <NUM_LIT:0><EOL>self._fifo_data_deque[fifo].append((raw_data, time_start_read, time_stop_read, status))<EOL>with self._fifo_conditions[fifo]:<EOL><INDENT>self._fifo_conditions[fifo].notify_all()<EOL><DEDENT><DEDENT>elif self.stop_readout.is_set():<EOL><INDENT>if empty_reads == self._n_empty_reads:<EOL><INDENT>break<EOL><DEDENT>else:<EOL><INDENT>empty_reads += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>finally:<EOL><INDENT>time_wait = self.readout_interval - (time() - time_read)<EOL><DEDENT><DEDENT>self._fifo_data_deque[fifo].append(None)  <EOL>with self._fifo_conditions[fifo]:<EOL><INDENT>self._fifo_conditions[fifo].notify_all()<EOL><DEDENT>logging.info('<STR_LIT>', fifo)<EOL>
Readout thread continuously reading FIFO.

        Readout thread, which uses read_raw_data_from_fifo() and appends data to self._fifo_data_deque (collection.deque).