Сигнал sd-bus не вызывает функцию cb

У меня одна проблема. В приложении C ++ я использую sd-bus, и сигнал не вызывает мою функцию обратного вызова.

Я подключился к org.freedesktop.login1, интерфейс - org.freedesktop.DBus.Properties, член - PropertiesChanged и путь - / org / freedesktop / login1 / seat / seat0

В моем методе подключения у меня есть это:

sd_bus_add_match(m_bus, NULL, "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/login1/seat/seat0',type='signal'", on_properties_changed, NULL)

При изменении свойств метод следующий:

static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
    printf("got some signal");
}

Итак, когда я запускал эту программу, я также выполнил следующую команду в cmd: ¸

gdbus monitor --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1/seat/seat0

Однако, когда я переключаюсь с userA на userB, я получаю следующую строку в окне cmd:

/org/freedesktop/login1/seat/seat0: org.freedesktop.DBus.Properties.PropertiesChanged ('org.freedesktop.login1.Seat', {'ActiveSession': <('c7', objectpath '/org/freedesktop/login1/session/c7')>}, @as [])

Также, когда я пробовал это

busctl --system --match "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/login1/seat/seat0',type='signal' monitor

тогда я тоже получаю правильный ответ

Type=signal  Endian=l  Flags=1  Version=1  Priority=0 Cookie=2281
  Sender=:1.0  Path=/org/freedesktop/login1/seat/seat0  Interface=org.freedesktop.DBus.Properties  Member=PropertiesChanged
  UniqueName=:1.0
  MESSAGE "sa{sv}as" {
          STRING "org.freedesktop.login1.Seat";
          ARRAY "{sv}" {
                  DICT_ENTRY "sv" {
                          STRING "ActiveSession";
                          VARIANT "(so)" {
                                  STRUCT "so" {
                                          STRING "c2";
                                          OBJECT_PATH "/org/freedesktop/login1/session/c2";
                                  };
                          };
                  };
          };
          ARRAY "s" {
          };
  };

Но в С ++ эта функция обратного вызова не вызывается. Есть идеи, почему это не называется?

Я использую Ubuntu 16.04, а моя версия systemd - 229.


person golobitch    schedule 07.09.2018    source источник


Ответы (1)


Я нашел решение этой проблемы. Проблема заключалась в том, что я не был привязан ни к одному циклу событий.

Итак, я создал новую функцию run (), и в этой функции я говорю следующее:

while(m_running) {
    sd_bus_message *m = NULL;
    r = sd_bus_process(m_bus, &m);
    if (r < 0) {
        //error handling
    }

    r = sd_bus_wait(m_bus, (uint64_t)-1);
    if (r < 0) {
        //error handling
    }
}

и теперь я вызываю эту функцию после подключения к сигналу, и функция обратного вызова sd_bus_add_match обычно вызывается

person golobitch    schedule 07.09.2018
comment
Я знаю, что, скорее всего, опубликованный вами код является просто примером, однако я хочу сообщить, что вы являетесь владельцем сообщения, возвращенного после sd_bus_process. Вы должны освободить сообщение, если закончили с ним (unref). Этот код, как показано, имеет утечку памяти. - person DJJ; 09.04.2020