GNOME Bugzilla – Bug 610994
Asynchronicity of TPL breaks the way pending messages are ACK.
Last modified: 2018-05-22 14:03:54 UTC
With Empathy log blockig APIs pending messages are ACK as soon as a window/tab is focused. The blocking API flow is: Msg recvd -> Build message window -> ACK (calling empathy_chat_messages_read()) The "Build message window" was blocking so the end of the function (empathy_chat.c:chat_constructed) meant the window was ready to be shown and the messages could be ACK. Situation pre fix: When TPL is enabled, chat_constructed calls an async API, returning immediatly. This fools empathy_window which calls empathy_chat_messages_read() to ACK the messages, without waiting for the async call to finish. The async call might finish after the ACK, resulting in the lost of the pending queue which was ACK before being shown properly. To avoid it, with Guillaume, we decided to add a flag in EmpathyChatPriv, retrieving_backlog, which is set by the async call and read by empathy_chat_messages_read(). If true empathy_chat_messages_read() will not ACK the queue. The async call chain, at its end, will call empathy_chat_messages_read() after setting the flag TRUE, to ACK the messages.
From KA (explanation in diagram form): In empathy before TPL (blocking API) MSG RECV -> TAB FOCUSED -> LAST 5 LINES FROM LOG SHOWED -> PENDING MESSAGES SHOWED -> P.M. ACK With TPL MSG RECV -> TAB FOCUSED -> GET 5 LINE of LOGS (ASYNC) -> P.M. ACK \->LAST 5 LINES FROM LOG SHOWED (callback)-> PENDING MESSAGES SHOWED (callback chain) race occur because "P.M ACK" is called before the callback actually starts, so "PENDING MESSAGES SHOWED" will show nothing, since the queue has already been empetied
Since the ack is triggered by the window focus event, it seems to me like the easiest fix for this is to delay the gtk_widget_show() for the window into the callback from async function (after all there is nothing to show until this function returns). The focus event can't be triggered until the window is visible.
This is the FIXME in empathy-chat.c: /* FIXME: retrieving_backlogs flag is a workaround for Bug#610994 and should * be differently handled since it introduces another race condition, which * is really hard to occur, but still possible. * * With the current workaround (which has the race above), we need to be * sure to ACK any pending messages only when the retrieval of backlogs is * finished, that's why using retrieving_backlogs flag. * empathy_chat_messages_read () will check this variable and not ACK * anything when TRUE. It will be set TRUE at chat_constructed () and set * back to FALSE when the backlog has been retrieved and the pending * messages actually showed to the user. * * Race condition introduced with this workaround: * Scenario: a message is pending, the user is notified and selects the tab. * the tab with a pending message is focused before the messages are properly * shown (since the preparation of the window is slower AND async WRT the * tab showing), which means the user won't see any new messages (rare but * possible), if he/she will change tab focus before the messages are * properly shown, the tab will be set as 'seen' and the user won't be * notified again about the already notified pending messages when the * messages in tab will be properly shown */
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/empathy/issues/192.