# Buggy code
def _ZeroMQResponder(self, source_queue, socket, terminate_event):
    """Listens for requests and replies to clients.

    Args:
      source_queue: The queue to uses to pull items from.
      socket: The socket to listen to, and send responses to.
      terminate_event: The event that signals that the queue should terminate.

    Raises:
      zmq.error.ZMQError: If an error is encountered by ZeroMQ.
    """
    logging.debug("ZeroMQ responder thread started")
    while not terminate_event.isSet():
        try:
            item = socket.recv_pyobj()
        except zmq.error.Again:
            # No item received within timeout.
            item = plaso_queue.QueueAbort()
        except zmq.error.ZMQError as exception:
            if exception.errno == errno.EINTR:
                logging.error("ZMQ syscall interrupted in {0:s}.".format(self.name))
                break
            else:
                raise

        retries = 0
        while retries < self._DOWNSTREAM_QUEUE_MAX_TRIES:
            try:
                self._queue.put(item, timeout=self._buffer_timeout_seconds)
                break
            except Queue.Full:
                logging.debug("Queue {0:s} buffer limit hit.".format(self.name))
                retries += 1
                if retries >= self._DOWNSTREAM_QUEUE_MAX_TRIES:
                    logging.error(
                        "Queue {0:s} unserved for too long, aborting".format(self.name)
                    )
                    break
                else:
                    time.sleep(self._DOWNSTREAM_QUEUE_SLEEP_TIME)
                    continue
    logging.info("Queue {0:s} responder exiting.".format(self.name))


# Traceback (exceptions.AttributeError)
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "./plaso/engine/zeromq_queue.py", line 651, in _ZeroMQResponder
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'Empty'
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "./plaso/engine/zeromq_queue.py", line 752, in _ZeroMQResponder
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'Empty'
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 763, in run
File "./plaso/engine/zeromq_queue.py", line 752, in _ZeroMQResponder
<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'Empty'
/home/travis/build.sh: line 45:  4478 Segmentation fault      (core dumped) coverage run --source=plaso --omit="*_test*,*__init__*,*test_lib*" ./run_tests.py

# Fixed code
def _ZeroMQResponder(self, source_queue):
    """Listens for requests and replies to clients.

    Args:
      source_queue (Queue.queue): queue to use to pull items from.

    Raises:
      QueueFull: if it was not possible to put an item into the buffer queue.
    """
    logging.debug("{0:s} responder thread started".format(self.name))
    while not self._terminate_event.isSet() and not self._closed_event.isSet():
        try:
            item = self._ReceiveItemOnActivity(self._zmq_socket)

        except errors.QueueEmpty:
            # Timeout receiving an item, we just retry until the terminate event
            # is set.
            continue

        retries = 0
        while retries < self._DOWNSTREAM_QUEUE_MAX_TRIES:
            try:
                self._queue.put(item, timeout=self._buffer_timeout_seconds)
                break
            except Queue.Full:
                logging.debug("Queue {0:s} buffer limit hit.".format(self.name))
                retries += 1
                if retries >= self._DOWNSTREAM_QUEUE_MAX_TRIES:
                    logging.error(
                        "{0:s} buffer queue full for too long, aborting".format(
                            self.name
                        )
                    )
                    raise errors.QueueFull
                else:
                    time.sleep(self._DOWNSTREAM_QUEUE_SLEEP_TIME)
                    continue

    logging.info("Queue {0:s} responder exiting.".format(self.name))
    self._zmq_socket.close(self._linger_seconds)