Page 1 of 1

[libmpdclient] detect lost connection to MPD daemon

Posted: January 13th, 2015, 9:28 pm
by jlk
I'm writing a plugin for my statusbar to print MPD state, currently using the libmpdclient library. It has to be robust to properly handle lost connections in case MPD is restarted, but simple checking with mpd_connection_get_error on existing mpd_connection object does not work – it can detect the error only when the initial mpd_connection_new fails and segfaults when MPD is restarted. So the question is: how should I check that the connection is still alive?

I've asked about this at http://stackoverflow.com/questions/2780 ... mpd-daemon, but since nobody answered, I thought I should ask upstream...

Re: [libmpdclient] detect lost connection to MPD daemon

Posted: January 14th, 2015, 2:30 pm
by jlk
The simplified code I'm working with is the following:

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <mpd/client.h>

int main(void) {
    struct mpd_connection* m_connection = NULL;
    struct mpd_status* m_status = NULL;
    char* m_state_str;

    m_connection = mpd_connection_new(NULL, 0, 30000);

    while (1) {
        // this check works only on start up (i.e. when mpd_connection_new failed),
        // not when the connection is lost later
        if (mpd_connection_get_error(m_connection) != MPD_ERROR_SUCCESS) {
            fprintf(stderr, "Could not connect to MPD: %s\n", mpd_connection_get_error_message(m_connection));
            mpd_connection_free(m_connection);
            m_connection = NULL;
            break;
        }

        m_status = mpd_run_status(m_connection);
        if (mpd_status_get_state(m_status) == MPD_STATE_PLAY) {
            m_state_str = "playing";
        } else if (mpd_status_get_state(m_status) == MPD_STATE_STOP) {
            m_state_str = "stopped";
        } else if (mpd_status_get_state(m_status) == MPD_STATE_PAUSE) {
            m_state_str = "paused";
        } else {
            m_state_str = "unknown";
        }
        printf("MPD state: %s\n", m_state_str);
        sleep(1);
    }
}
When MPD is stopped during the execution of the above program, it segfaults with:

Code: Select all

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fb2fd9557e0 in mpd_status_get_state () from /usr/lib/libmpdclient.so.2
The only way I can think of to make my program safe enough is to create new connection in every iteration, which I was hoping to avoid. But as far as I understand, the same problem would be when MPD is stopped between the calls to libmpdclient functions, regardless of the timeout, still leading to segfault. So the second question is, how often should I check if the connection is still alive, or is this the bug I should have reported?

Re: [libmpdclient] detect lost connection to MPD daemon

Posted: March 7th, 2015, 6:26 pm
by max
jlk wrote:I'm writing a plugin for my statusbar to print MPD state, currently using the libmpdclient library. It has to be robust to properly handle lost connections in case MPD is restarted, but simple checking with mpd_connection_get_error on existing mpd_connection object does not work – it can detect the error only when the initial mpd_connection_new fails and segfaults when MPD is restarted.
Write a bug report for the segfault.

When a connection is lost, this can only be detected by writing or reading from the socket. To help you further, I need to know how your code looks like. Are you using idle events, or are you polling with a timer? Are you using the asynchronous API?