2015-01-06 4 views
1

현재 상태 저장소에 libmpdclient 라이브러리를 사용하는 MPD 상태를 인쇄하기위한 플러그인을 작성하고 있습니다. MPD가 다시 시작될 경우 손실 된 연결을 올바르게 처리하려면 견고해야하지만 기존 mpd_connection 개체에 대한 mpd_connection_get_error의 간단한 검사는 작동하지 않습니다. – mpd_connection_new이 실패 할 때만 오류를 감지 할 수 있습니다. libmpdclient : MPD 데몬과의 연결이 끊어 졌음을 감지하십시오.

나는과 단순화 된 코드 일하고있다 :

#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; 
     } 

     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); 
    } 
} 
MPD는 위의 프로그램을 실행하는 동안 중지되면, 그것은과 세그먼테이션 폴트 (segfault)

: 내가 할 수있는

Program terminated with signal SIGSEGV, Segmentation fault. 
#0 0x00007fb2fd9557e0 in mpd_status_get_state() from /usr/lib/libmpdclient.so.2 

유일한 방법 프로그램을 안전하게 만드는 것이 모든 반복에서 새로운 연결을 설정하는 것이라고 생각합니다. 그렇다면 libmpdclient 함수에 대한 개별 호출간에 연결이 끊어지면 어떻게해야합니까? 얼마나 자주, 그리고 더 중요한 것은 정확히 어떻게, 내가 연결이 아직 살아 있는지 확인해야합니까?

답변

0

내가 실제로 작동하는 것을 찾을 수있는 유일한 방법은 각 실행마다 연결을 다시 설정하는 것보다 idle command을 사용하는 것입니다. mpd_recv_idle (또는 mpd_run_idle)이 0을 반환하면 오류 조건이 발생하므로 연결을 해제하고 거기에서부터 실행하라는 메시지를 가져올 수 있습니다. 완벽한 솔루션은 아니지만 실행간에 실시간 연결을 유지할 수 있으며 segfaults를 피할 수 있습니다 (명령을 보내고 mpd가 죽기 전에 완전히 피할 수는 없다고 생각합니다. recv it, 나는 라이브러리가 여전히 segfaults라고 확신한다.) 더 나은 솔루션이 있는지 확실하지 않습니다. API를 통해 연결이 아직 살아 있는지 감지 할 수있는 확실한 방법이 있다면 환상적인 일이지만, 그런 종류의 것을 찾을 수는 없습니다. libmpdclient는 시간이 지남에 따라 위아래로 이동하는 mpd 인스턴스를 처리해야하는 매우 오래 지속되는 연결에 적합합니다.

낮은 수준의 또 다른 옵션은 소켓을 사용하여 its protocol을 통해 직접 MPD와 상호 작용하는 것입니다.하지만 그렇게하면 libmpdclient 자체의 많은 부분을 다시 구현할 가능성이 있습니다.

편집 : 유감스럽게도 idle 명령은 무언가가 발생할 때까지 차단을 수행하고 단일 오디오 트랙이 지속되는 한 차단할 수 있으므로 중간에 다른 프로그램을 수행해야하는 프로그램이 필요하다면 비동기 적으로 또는 다른 스레드에서 구현하는 방법.

관련 문제