Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[windows] Fix CGUIMediaWindow::WaitGetDirectoryItems to leave 'wait f… #23844

Merged
merged 1 commit into from Oct 1, 2023

Conversation

ksooo
Copy link
Member

@ksooo ksooo commented Sep 30, 2023

…or update job finished loop' also if the update was canceled via CGUIMediaWindow::CancelUpdateItems.

Fixes #23738

Fix was confirmed working by the issue submitter.

A bit hard to explain what happened but I can try. ;-)

While the user started live TV channel playback from inside the PVR channels window, but before the channels window got deactivated (because full screen video was activated), PVR core notified a bunch async events, which lead to a refresh of the channels window list items.

In the moment, the channels window gets deactivated, CGUIMediaWindow::CancelUpdateItems gets called (frame 0).

This then calls m_updateEvent.Wait. Once this wait call returns, m_updateEventwill be reset - and this is important thing here, also if it was already set before the 'Wait' call by a job triggered by CGUIMediaWindow::WaitGetDirectoryItems (frame 17), leading the m_updateEvent.Wait call done in a loop in CGUIMediaWindow::WaitGetDirectoryItems never leaving that loop.

Because even lower on the stack (frame 34), there is a CGUIDialogBusy::WaitOnEvent call which will never return in this situation, the user saw an endless busy spinner on top of the running live tv channel.

Because of the async nature of the problem it was very hard to reproduce, but at the end I hacked together a special test case for that (not nice at all, but effective). :-)

If you want to understand all the details, you need at least to study the implementation of CGUIMediaWindow::CancelUpdateItems, CGUIMediaWindow::WaitGetDirectoryItems and CEvent::Wait(calling CEvent::prepReturnwhere the reset of 'signalled' happens').

It is also worth mentioning that this problem is not caused by the "busy dialog". This can also happen without busy dialog being involved. And the problem is not restricted to Live TV. Could happen with any kind of media window content.

(lldb) thread backtrace all
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x000000010a3f6056 Kodi`CGUIMediaWindow::CancelUpdateItems(this=0x00007f80eb1fa800) at GUIMediaWindow.cpp:2326:10
    frame #1: 0x000000010a3f61e4 Kodi`CGUIMediaWindow::OnMessage(this=0x00007f80eb1fa800, message=0x00007ff7b81a28b0) at GUIMediaWindow.cpp:247:7
    frame #2: 0x0000000109c91e6f Kodi`PVR::CGUIWindowPVRBase::OnMessage(this=0x00007f80eb1fa800, message=0x00007ff7b81a28b0) at GUIWindowPVRBase.cpp:371:38
    frame #3: 0x0000000109c9b236 Kodi`PVR::CGUIWindowPVRChannelsBase::OnMessage(this=0x00007f80eb1fa800, message=0x00007ff7b81a28b0) at GUIWindowPVRChannels.cpp:274:40
    frame #4: 0x0000000108e584d9 Kodi`CGUIWindow::Close_Internal(this=0x00007f80eb1fa800, forceClose=true, nextWindowID=12005, enableSound=true) at GUIWindow.cpp:394:3
    frame #5: 0x0000000108e58281 Kodi`CGUIWindow::Close(this=0x00007f80eb1fa800, forceClose=false, nextWindowID=12005, enableSound=true, bWait=true) at GUIWindow.cpp:412:5
    frame #6: 0x0000000108e6b9eb Kodi`CGUIWindowManager::CloseWindowSync(this=0x00007f80ec894b30, window=0x00007f80eb1fa800, nextWindowID=12005) at GUIWindowManager.cpp:1787:11
    frame #7: 0x0000000108e6c79f Kodi`CGUIWindowManager::ActivateWindow_Internal(this=0x00007f80ec894b30, iWindowID=12005, params=size=0, swappingWindows=false, force=true) at GUIWindowManager.cpp:870:5
    frame #8: 0x0000000108e6bfff Kodi`CGUIWindowManager::ActivateWindow(this=0x00007f80ec894b30, iWindowID=12005, params=size=0, swappingWindows=false, force=true) at GUIWindowManager.cpp:791:5
    frame #9: 0x0000000108e6c0ee Kodi`CGUIWindowManager::ForceActivateWindow(this=0x00007f80ec894b30, iWindowID=12005, strPath="") at GUIWindowManager.cpp:776:3
    frame #10: 0x0000000108e6d566 Kodi`CGUIWindowManager::SwitchToFullScreen(this=0x00007f80ec894b30, force=true) at GUIWindowManager.cpp:972:7
    frame #11: 0x00000001083d8a79 Kodi`CApplication::OnApplicationMessage(this=0x00007f80eaf05990, pMsg=0x00006000076d3aa0) at Application.cpp:1588:31
    frame #12: 0x00000001092c85bd Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessMessage(this=0x0000600002218018, pMsg=0x00006000076d3aa0) at ApplicationMessenger.cpp:244:17
    frame #13: 0x00000001092c90eb Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessMessages(this=0x0000600002218018) at ApplicationMessenger.cpp:217:5
    frame #14: 0x00000001083e3492 Kodi`CApplication::Process(this=0x00007f80eaf05990) at Application.cpp:3127:38
    frame #15: 0x0000000108e6fc14 Kodi`CGUIWindowManager::ProcessRenderLoop(this=0x00007f80ec894b30, renderOnly=false) at GUIWindowManager.cpp:1410:20
    frame #16: 0x000000010a4066f1 Kodi`CGUIMediaWindow::ProcessRenderLoop(this=0x00007f80eb1fa800, renderOnly=false) at GUIMediaWindow.cpp:2221:55
  * frame #17: 0x000000010a406a8f Kodi`CGUIMediaWindow::WaitGetDirectoryItems(this=0x00007f80eb1fa800, items=0x00007ff7b81a49d8)::CGetDirectoryItems&) at GUIMediaWindow.cpp:2306:12
    frame #18: 0x000000010a3fcb5b Kodi`CGUIMediaWindow::GetDirectoryItems(this=0x00007f80eb1fa800, url=0x00007ff7b81a4e38, items=0x00007ff7b81a4fc8, useDir=false) at GUIMediaWindow.cpp:2233:10
    frame #19: 0x000000010a3fc0ea Kodi`CGUIMediaWindow::GetDirectory(this=0x00007f80eb1fa800, strDirectory="pvr://channels/tv/All%20channels@-1/", items=0x00007f80ecc959a0) at GUIMediaWindow.cpp:752:10
    frame #20: 0x000000010a3fd3e1 Kodi`CGUIMediaWindow::Update(this=0x00007f80eb1fa800, strDirectory="pvr://channels/tv/All%20channels@-1/", updateFilterPath=true) at GUIMediaWindow.cpp:839:8
    frame #21: 0x0000000109c932bf Kodi`PVR::CGUIWindowPVRBase::Update(this=0x00007f80eb1fa800, strDirectory="pvr://channels/tv/All%20channels@-1/", updateFilterPath=true) at GUIWindowPVRBase.cpp:583:35
    frame #22: 0x0000000109c9a34d Kodi`PVR::CGUIWindowPVRChannelsBase::Update(this=0x00007f80eb1fa800, strDirectory="pvr://channels/tv/All%20channels@-1/", updateFilterPath=false) at GUIWindowPVRChannels.cpp:92:37
    frame #23: 0x000000010a3fed08 Kodi`CGUIMediaWindow::Refresh(this=0x00007f80eb1fa800, clearCache=true) at GUIMediaWindow.cpp:964:8
    frame #24: 0x0000000109c91d37 Kodi`PVR::CGUIWindowPVRBase::OnMessage(this=0x00007f80eb1fa800, message=0x00006000139a80c0) at GUIWindowPVRBase.cpp:326:13
    frame #25: 0x0000000109c9b236 Kodi`PVR::CGUIWindowPVRChannelsBase::OnMessage(this=0x00007f80eb1fa800, message=0x00006000139a80c0) at GUIWindowPVRChannels.cpp:274:40
    frame #26: 0x0000000108e69e13 Kodi`CGUIWindowManager::SendMessage(this=0x00007f80ec894b30, message=0x00006000139a80c0) at GUIWindowManager.cpp:567:21
    frame #27: 0x0000000108e6a1f2 Kodi`CGUIWindowManager::SendMessage(this=0x00007f80ec894b30, message=0x00006000139a80c0, window=0) at GUIWindowManager.cpp:582:12
    frame #28: 0x0000000108e6da9f Kodi`CGUIWindowManager::OnApplicationMessage(this=0x00007f80ec894b30, pMsg=0x00006000076eaed0) at GUIWindowManager.cpp:1064:7
    frame #29: 0x00000001092c85bd Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessMessage(this=0x0000600002218018, pMsg=0x00006000076eaed0) at ApplicationMessenger.cpp:244:17
    frame #30: 0x00000001092c93e7 Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessWindowMessages(this=0x0000600002218018) at ApplicationMessenger.cpp:265:5
    frame #31: 0x00000001083e33fa Kodi`CApplication::Process(this=0x00007f80eaf05990) at Application.cpp:3114:38
    frame #32: 0x0000000108e6fc14 Kodi`CGUIWindowManager::ProcessRenderLoop(this=0x00007f80ec894b30, renderOnly=false) at GUIWindowManager.cpp:1410:20
    frame #33: 0x0000000108d3d661 Kodi`CGUIDialog::ProcessRenderLoop(this=0x00007f80eaf65b40, renderOnly=false) at GUIDialog.cpp:238:48
    frame #34: 0x00000001088cede9 Kodi`CGUIDialogBusy::WaitOnEvent(event=0x00007f80eaf05a30, displaytime=100, allowCancel=true) at GUIDialogBusy.cpp:94:17
    frame #35: 0x00000001083e06b5 Kodi`CApplication::OnMessage(this=0x00007f80eaf05990, message=0x0000600013904ae0) at Application.cpp:2796:11
    frame #36: 0x0000000108e6991c Kodi`CGUIWindowManager::SendMessage(this=0x00007f80ec894b30, message=0x0000600013904ae0) at GUIWindowManager.cpp:499:23
    frame #37: 0x0000000108e70df8 Kodi`CGUIWindowManager::DispatchThreadMessages(this=0x00007f80ec894b30) at GUIWindowManager.cpp:1561:7
    frame #38: 0x00000001083e33dc Kodi`CApplication::Process(this=0x00007f80eaf05990) at Application.cpp:3110:48
    frame #39: 0x00000001083dc526 Kodi`CApplication::Run(this=0x00007f80eaf05990) at Application.cpp:1918:5
    frame #40: 0x00000001098220fe Kodi`::XBMC_Run(renderGUI=true) at xbmc.cpp:61:26
    frame #41: 0x0000000107d676eb Kodi`::SDL_main(argc=1, argv=0x0000600001f10390) at main.cpp:71:16
    frame #42: 0x0000000107d66975 Kodi`main(argc=1, argv=0x00007ff7b81a7f78) at SDLMain.mm:567:14
    frame #43: 0x000000011f1ff52e dyld`start + 462

I have no idea who could review this, thus setting no reviewer.
I will merge this after a week or so of inactivity.

…or update job finished loop' also if the update was canceled via CGUIMediaWindow::CancelUpdateItems.
@ksooo ksooo merged commit ba7adbd into xbmc:master Oct 1, 2023
2 checks passed
@ksooo ksooo deleted the mediawindow-fix-canelupdateitems branch October 1, 2023 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backport: Done Type: Fix non-breaking change which fixes an issue v21 Omega
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Live TV (pvr.hts) - Randomly spinner stays forever although channel is playing fine
2 participants