This function call loop() for you in an infinite blocking loop. It
        is useful for the case where you only want to run the MQTT client loop
        in your program.

        loop_forever() will handle reconnecting for you. If you call
        disconnect() in a callback it will return.


        timeout: The time in seconds to wait for incoming/outgoing network
          traffic before timing out and returning.
        max_packets: Not currently used.
        retry_first_connection: Should the first connection attempt be retried on failure.

        Raises socket.error on first connection failures unless retry_first_connection=True

def loop_forever(self, timeout=1.0, max_packets=1, retry_first_connection=False):
        """This function call loop() for you in an infinite blocking loop. It
        is useful for the case where you only want to run the MQTT client loop
        in your program.

        loop_forever() will handle reconnecting for you. If you call
        disconnect() in a callback it will return.


        timeout: The time in seconds to wait for incoming/outgoing network
          traffic before timing out and returning.
        max_packets: Not currently used.
        retry_first_connection: Should the first connection attempt be retried on failure.

        Raises socket.error on first connection failures unless retry_first_connection=True
        """

        run = True

        while run:
            if self._state == mqtt_cs_connect_async:
                try:
                    self.reconnect()
                except socket.error:
                    if not retry_first_connection:
                        raise
                    self._easy_log(MQTT_LOG_DEBUG, "Connection failed, retrying")
                    self._backoffCore.backOff()
                    # time.sleep(1)
            else:
                break

        while run:
            rc = MQTT_ERR_SUCCESS
            while rc == MQTT_ERR_SUCCESS:
                rc = self.loop(timeout, max_packets)
                # We don't need to worry about locking here, because we've
                # either called loop_forever() when in single threaded mode, or
                # in multi threaded mode when loop_stop() has been called and
                # so no other threads can access _current_out_packet,
                # _out_packet or _messages.
                if (self._thread_terminate is True
                        and self._current_out_packet is None
                        and len(self._out_packet) == 0
                        and len(self._out_messages) == 0):

                    rc = 1
                    run = False

            self._state_mutex.acquire()
            if self._state == mqtt_cs_disconnecting or run is False or self._thread_terminate is True:
                run = False
                self._state_mutex.release()
            else:
                self._state_mutex.release()
                self._backoffCore.backOff()
                # time.sleep(1)

                self._state_mutex.acquire()
                if self._state == mqtt_cs_disconnecting or run is False or self._thread_terminate is True:
                    run = False
                    self._state_mutex.release()
                else:
                    self._state_mutex.release()
                    try:
                        self.reconnect()
                    except socket.error as err:
                        pass

        return rc