This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Zephyr MQTT poll()

In the Simple Mqtt example I noticed that the whole thing gets blocked by:

err = poll(&fds, 1, mqtt_keepalive_time_left(&client));

The keep alive is 60 seconds, this means that I cant to anything unless the keep alive is timed out or I receive an MQTT message.

I'm new to Zephyr and Linux so I wonder:

How is poll() intended to be used?

Tested to set the timeout to 1 it works better but is it safe to use? (will I miss packets?)

do I need to call some abort_poll function if I want for e.g. publish a message before the timeout?

/Cheers

Parents
  • Hi,

    What exactly is it that you want to do?

    You are correct that poll() will block the thread until something happens on the socket(s) or it times out. But you can run other tasks in other threads if you want to do something else while waiting for MQTT activity.

    do I need to call some abort_poll function if I want for e.g. publish a message before the timeout?

    If you want to send something, you can simply send it. E.g. in the mqtt_simple sample, the main thread (the thread that runs the main() function) will check for incoming MQTT messages and keep the connection alive (in the poll() loop).

    At the same time, the dk_buttons_and_leds library checks for button presses in the system workqueue. When a button press is detected, a message is sent to the broker (from the button_handler() function).

    Best regards,

    Didrik

  • Ok, I don't use the DK. I have my own interrupt that sets a flag, the flag is checked in the main loop, if flag is set then it publishes a message.

    What I want to understand is how the sockets/poll works. For instance if I have a short timeout and do other stuff in between does the connection drop? or does messages get lost? I suppose this could happen even if I run different threads as well?

    Regards

Reply
  • Ok, I don't use the DK. I have my own interrupt that sets a flag, the flag is checked in the main loop, if flag is set then it publishes a message.

    What I want to understand is how the sockets/poll works. For instance if I have a short timeout and do other stuff in between does the connection drop? or does messages get lost? I suppose this could happen even if I run different threads as well?

    Regards

Children
  • FZe said:
    What I want to understand is how the sockets/poll works.

    poll() takes a list of sockets, and a timeout. It will then block the thread until either something happens on one of the sockets or it times out.

    The way it is used in the mqtt_simple sample is to take the MQTT socket and the MQTT keepalive period as a timeout. This means that there are two possible reasons for why poll() returns: The keepalive period is up and we need to send a keepalive message, or something happened on the socket (we have received some data or the connection is closed). The code that follows the call to poll() checks which it is, and takes the appropiate action.

    If you shorten the timeout, the worst thing that will happen is that you wake up unnecessary, costing power. If there is any unread data on the socket when you call poll(), poll() will return immediatly, so there is no risk of missing data. You also don't have to call poll() to keep the connection alive (on a TCP level), but you must call mqtt_live() regularly to keep the MQTT connection alive if there are no other data being sent. Using the timeout in poll() is one way to ensure that you don't call mqtt_live() more often than you have to.

    FZe said:
    I have my own interrupt that sets a flag, the flag is checked in the main loop, if flag is set then it publishes a message.

    If I may come with a suggestion here: Rather than polling a flag in the main loop, which is normally blocked by poll() unless you move the MQTT handling to a different thread or shorten the timeout, you can use a workqueue.

    By using a workqueue, you don't have to poll a flag yourself, instead the work item will be executed the next time the workqueue runs (assuming it is the first item in the queue).

Related