import time
from queue import Queue


class FifoQueue(Queue):
    def get_or_default(self, block=True, timeout=None, default=None):
        """Remove and return an item from the queue.

        This differs from get() in that it will return `default` instead of
        raising Empty exception.

        If optional args 'block' is true and 'timeout' is None (the default),
        block if necessary until an item is available. If 'timeout' is
        a non-negative number, it blocks at most 'timeout' seconds and raises
        the Empty exception if no item was available within that time.
        Otherwise ('block' is false), return an item if one is immediately
        available, else raise the Empty exception ('timeout' is ignored
        in that case).
        """
        with self.not_empty:
            if not block:
                if not self._qsize():
                    return default
            elif timeout is None:
                while not self._qsize():
                    self.not_empty.wait()
            elif timeout < 0:
                raise ValueError("'timeout' must be a non-negative number")
            else:
                endtime = time.time() + timeout
                while not self._qsize():
                    remaining = endtime - time.time()
                    if remaining <= 0.0:
                        return default
                    self.not_empty.wait(remaining)
            item = self._get()
            self.not_full.notify()
            return item
