[libmpdclient] detect lost connection to MPD daemon

Discuss client development (or even MPD development if you feel so inclined), ask questions about the client libs, MPD feature requests from client developers, etc...
Post Reply
jlk
Posts: 2
Joined: January 13th, 2015, 9:19 pm

[libmpdclient] detect lost connection to MPD daemon

Post by jlk » January 13th, 2015, 9:28 pm

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...

jlk
Posts: 2
Joined: January 13th, 2015, 9:19 pm

Re: [libmpdclient] detect lost connection to MPD daemon

Post by jlk » January 14th, 2015, 2:30 pm

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?

max
Forum team
Posts: 940
Joined: January 15th, 2013, 3:43 pm

Re: [libmpdclient] detect lost connection to MPD daemon

Post by max » March 7th, 2015, 6:26 pm

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?

Post Reply