2017-08-25 95 views
3

當試圖爲DBus回覆使用回調函數時,我遇到了創建一個良好/工作正常的主循環的問題。低級DBus C API主循環

我想要做的事很簡單,做一個DBus調用,並指定一個函數,當應答到來時應該調用它。這是因爲我不想一直阻止我的線程,直到答覆已經計算併到達。

我首先使用dbus_connection_send_with_reply(..)來獲得一個DBusPendingCall,然後我使用dbus_pending_call_set_notify(..)指定一個回調函數。在這樣做之前,當連接到總線時,我已經啓動了另一個應該等待響應並調用回調函數的線程。我沒有找到任何實例,也沒有關於如何設計這樣的dbus主循環的非常好的文檔。我曾嘗試:

// Main dbus loop handling data transfer and callbacks.. 
void *dbus_main(void *args) 
{ 
    my_dbus dbus = (my_dbus)args; 

    while (MY_DBUS_STATUS_STOPPING != dbus->status 
      && dbus_connection_read_write_dispatch(dbus->conn, -1)) 
     ; 

    return 0; 
} 

// Start the dbus main loop in a new thread 
void dbus_main_start(my_dbus dbus) { 
    if (!pthread_create(&dbus->th, NULL, dbus_main, dbus)) { 
     // PRINT ERROR 
    } 
} 

我的問題是兩件事情:

  • 我試圖通過設置dbus->狀態標誌MY_DBUS_STATUS_STOPPING和等待的線程加入到停止應用程序。如果線程在dbus_connection_read_write_dispatch(..)函數中被阻塞,則這不起作用。如果我想要應用程序停止快速,那麼我需要指定一個非常短的超時。我不能以其他方式喚醒阻塞的線程嗎?

  • 更嚴重的是,使用此代碼我沒有從我調用的方法中獲得任何回調。如果我添加一些fprintf(..)寫入標準輸出,我可能會突然收到我的回調。這似乎很隨機,所以也許會出現某種僵局?我試着在發送消息和使用_set_notify(..)函數添加回調函數之間有一個dbus_connection_flush(..)。沒有任何區別......但是在同一個地方打印一些字母到stdout可以解決問題。打印到dbus-main-loop中標準輸出的空白「;」似乎做有時伎倆......

因此,任何人誰擁有使用低級別的dbus API的例子與異步方法一起,即不使用_block(..)?

回答

0

這是高度建議您使用d-Bus的庫其他比libdbus,作爲libdbus是繁瑣的正確使用,因爲你發現。如果可能,請改爲使用GDBusQtDBus,因爲它們是更易於使用的高級別綁定。如果您需要較低級別的綁定,則sd-bus比libdbus更現代。

如果使用GDBus,則可以使用GMainLoop來實現主循環。如果您使用sd-bus,則可以使用sd-event

0

可以按如下方式創建一個簡單的DBus申請...

要設置一個服務器來處理傳入的消息,請致電dbus_connection_register_object_path傳遞一個虛函數表包含函數指針來處理消息。如:

{ .unregister_function = UnregisteredMessage, .message_function = ServiceMessage }

發送新郵件,打電話dbus_connection_send_with_reply然後dbus_pending_call_set_notify一個回調函數來處理答覆相關聯。

接下來你將需要服務DBus。這可以在單獨的線程或通過用在同一線程非阻塞調用週期性調用來完成,如下所示:

/* Non-blocking read of the next available message */ 
dbus_connection_read_write (MyDBusConnection, 0) ; 

while (dbus_connection_get_dispatch_status (MyDBusConnection) == DBUS_DISPATCH_DATA_REMAINS) 
{ 
    dbus_connection_dispatch (MyDBusConnection) ; 
} 

這裏有使用DBUS C API的一些很好的例子:http://www.matthew.ath.cx/misc/dbus