Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@enen92
Copy link
Member

@enen92 enen92 commented Apr 20, 2024

Description

Backport of #25026 for Omega

@enen92
Copy link
Member Author

enen92 commented Apr 21, 2024

Jenkins build this please

@enen92 enen92 merged commit e40dbfb into xbmc:Omega Apr 21, 2024
@ksooo
Copy link
Member

ksooo commented May 1, 2024

@enen92 This causes a reproducible deadlock when starting playback of a movie that triggers a screen resolution change (from movies window if that matters).

I experienced this with latest Omega. Maybe master has the same problem (not tested).

Stacks of the involved threads:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x0000000195814ea4 libsystem_kernel.dylib`__psynch_mutexwait + 8
    frame #1: 0x000000010c5ebe10 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 100
    frame #2: 0x000000010c5ebd2c libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 248
    frame #3: 0x0000000100a6fbe0 Kodi`XbmcThreads::CRecursiveMutex::lock(this=0x000000015161eb28) at RecursiveMutex.h:39:24
    frame #4: 0x0000000100a6fbac Kodi`XbmcThreads::CountingLockable<XbmcThreads::CRecursiveMutex>::lock(this=0x000000015161eb28) at Lockables.h:50:32
    frame #5: 0x0000000100a6fb80 Kodi`std::__1::unique_lock<CCriticalSection>::unique_lock[abi:ue170006](this=0x000000016f47f7f8, __m=0x000000015161eb28) at unique_lock.h:41:11
    frame #6: 0x0000000100a6fb10 Kodi`std::__1::unique_lock<CCriticalSection>::unique_lock[abi:ue170006](this=0x000000016f47f7f8, __m=0x000000015161eb28) at unique_lock.h:40:106
    frame #7: 0x00000001015aaeb4 Kodi`CGUIWindowManager::GetWindow(this=0x000000015167d9a0, id=10000) const at GUIWindowManager.cpp:1404:38
    frame #8: 0x00000001015af8b8 Kodi`CGUIWindowManager::MarkDirty(this=0x000000015167d9a0, rect=0x000000016f47f8f8) at GUIWindowManager.cpp:1240:25
    frame #9: 0x00000001015add60 Kodi`CGUIWindowManager::MarkDirty(this=0x000000015167d9a0) at GUIWindowManager.cpp:1233:3
  * frame #10: 0x0000000100f2be9c Kodi`CApplicationPowerHandling::SetRenderGUI(this=0x000060000296c1d8, renderGUI=true) at ApplicationPowerHandling.cpp:74:52
    frame #11: 0x0000000100eea328 Kodi`CAppInboundProtocol::SetRenderGUI(this=0x0000600001002758, renderGUI=true) at AppInboundProtocol.cpp:30:13
    frame #12: 0x0000000102249a58 Kodi`-[XBMCWindowControllerMacOS windowDidEndLiveResize:](self=0x0000600003b4ae60, _cmd="windowDidEndLiveResize:", notification="NSWindowDidEndLiveResizeNotification") at WindowControllerMacOS.mm:102:14
    frame #13: 0x0000000195926b1c CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148
    frame #14: 0x00000001959badb8 CoreFoundation`___CFXRegistrationPost_block_invoke + 88
    frame #15: 0x00000001959bad00 CoreFoundation`_CFXRegistrationPost + 440
    frame #16: 0x00000001958f5648 CoreFoundation`_CFXNotificationPost + 768
    frame #17: 0x0000000196a11464 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 88
    frame #18: 0x0000000199401d18 AppKit`-[NSWindow _endLiveResize] + 180
    frame #19: 0x0000000199e02654 AppKit`-[_NSFullScreenContentController reshapeContentForTileContentFrame:fromFrame:] + 696
    frame #20: 0x0000000199edc628 AppKit`-[_NSFullScreenSpace updateTileShapeAndReshapeContentsUsingTileFrame:ackServer:] + 200
    frame #21: 0x0000000199eda454 AppKit`__32+[_NSFullScreenSpace initialize]_block_invoke.9 + 120
    frame #22: 0x00000001998032c4 AppKit`__47+[NSCGSSpace addTileResizeNotificationHandler:]_block_invoke + 148
    frame #23: 0x0000000195926b08 CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 128
    frame #24: 0x00000001959badb8 CoreFoundation`___CFXRegistrationPost_block_invoke + 88
    frame #25: 0x00000001959bad00 CoreFoundation`_CFXRegistrationPost + 440
    frame #26: 0x00000001958f5648 CoreFoundation`_CFXNotificationPost + 768
    frame #27: 0x0000000196a11464 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 88
    frame #28: 0x000000019b2c3050 SkyLight`post_coordinated_distributed_notification(CGSNotificationType, void*, unsigned int, void*) + 620
    frame #29: 0x000000019b0144e4 SkyLight`CGSPostLocalNotification + 164
    frame #30: 0x000000019b0140f0 SkyLight`(anonymous namespace)::notify_datagram_handler(unsigned int, CGSDatagramType, void*, unsigned long, void*) + 116
    frame #31: 0x000000019b3b2224 SkyLight`CGSDatagramReadStream::dispatchMainQueueDatagrams() + 228
    frame #32: 0x000000019b3b2120 SkyLight`invocation function for block in CGSDatagramReadStream::mainQueueWakeup() + 28
    frame #33: 0x000000010bff4f2c libdispatch.dylib`_dispatch_call_block_and_release + 32
    frame #34: 0x000000010bff6ba4 libdispatch.dylib`_dispatch_client_callout + 20
    frame #35: 0x000000010c009f08 libdispatch.dylib`_dispatch_main_queue_drain + 1100
    frame #36: 0x000000010c009aac libdispatch.dylib`_dispatch_main_queue_callback_4CF + 44
    frame #37: 0x00000001959734ac CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
    frame #38: 0x0000000195930c30 CoreFoundation`__CFRunLoopRun + 1996
    frame #39: 0x000000019592fe0c CoreFoundation`CFRunLoopRunSpecific + 608
    frame #40: 0x00000001a00cb000 HIToolbox`RunCurrentEventLoopInMode + 292
    frame #41: 0x00000001a00cae3c HIToolbox`ReceiveNextEventCommon + 648
    frame #42: 0x00000001a00cab94 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 76
    frame #43: 0x0000000199188970 AppKit`_DPSNextEvent + 660
    frame #44: 0x000000019997adec AppKit`-[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700
    frame #45: 0x000000019917bcb8 AppKit`-[NSApplication run] + 476
    frame #46: 0x0000000199152f54 AppKit`NSApplicationMain + 880
    frame #47: 0x000000010098a4f0 Kodi`main(argc=1, argv=0x000000016f482ea8) at XBMCApplication.mm:352:12
    frame #48: 0x00000001954ca0e0 dyld`start + 2360

  thread #6, name = 'XBMCMainThread'
    frame #0: 0x0000000195813fac libsystem_kernel.dylib`__ulock_wait + 8
    frame #1: 0x000000010bff7720 libdispatch.dylib`_dlock_wait + 56
    frame #2: 0x000000010bff74d4 libdispatch.dylib`_dispatch_thread_event_wait_slow + 56
    frame #3: 0x000000010c00ba4c libdispatch.dylib`__DISPATCH_WAIT_FOR_QUEUE__ + 384
    frame #4: 0x000000010c00b034 libdispatch.dylib`_dispatch_sync_f_slow + 196
    frame #5: 0x000000010225356c Kodi`CWinSystemOSX::ResizeWindow(this=0x0000000153890600, newWidth=1920, newHeight=1200, newLeft=-1, newTop=-1) at WinSystemOSX.mm:880:3
    frame #6: 0x0000000102247158 Kodi`CWinSystemOSXGL::ResizeWindow(this=0x0000000153890600, newWidth=1920, newHeight=1200, newLeft=-1, newTop=-1) at WinSystemOSXGL.mm:49:18
    frame #7: 0x0000000102253b40 Kodi`CWinSystemOSX::SetFullScreen(this=0x0000000153890600, fullScreen=true, res=0x000000016f737370, blankOtherDisplays=false) at WinSystemOSX.mm:975:3
    frame #8: 0x00000001022471ec Kodi`CWinSystemOSXGL::SetFullScreen(this=0x0000000153890600, fullScreen=true, res=0x000000016f737370, blankOtherDisplays=false) at WinSystemOSXGL.mm:62:18
    frame #9: 0x000000010221b1b0 Kodi`CGraphicContext::SetVideoResolutionInternal(this=0x000000015161eb20, res=26, forceUpdate=false) at GraphicContext.cpp:445:48
    frame #10: 0x000000010221ac48 Kodi`CGraphicContext::SetVideoResolution(this=0x000000015161eb20, res=26, forceUpdate=false) at GraphicContext.cpp:390:5
    frame #11: 0x0000000100ef90ec Kodi`CApplication::OnApplicationMessage(this=0x0000000151704b00, pMsg=0x00006000038065a0) at Application.cpp:1595:53
    frame #12: 0x0000000101838524 Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessMessage(this=0x0000600002f70018, pMsg=0x00006000038065a0) at ApplicationMessenger.cpp:244:17
    frame #13: 0x0000000101838e24 Kodi`KODI::MESSAGING::CApplicationMessenger::ProcessMessages(this=0x0000600002f70018) at ApplicationMessenger.cpp:217:5
    frame #14: 0x0000000100f02704 Kodi`CApplication::Process(this=0x0000000151704b00) at Application.cpp:3220:38
    frame #15: 0x00000001015b09e8 Kodi`CGUIWindowManager::ProcessRenderLoop(this=0x000000015167d9a0, renderOnly=false) at GUIWindowManager.cpp:1421:20
    frame #16: 0x00000001014ea358 Kodi`CGUIDialog::ProcessRenderLoop(this=0x00000001529e5b70, renderOnly=false) at GUIDialog.cpp:239:48
    frame #17: 0x0000000101271248 Kodi`CGUIDialogBusy::WaitOnEvent(event=0x0000000151704de8, displaytime=100, allowCancel=true) at GUIDialogBusy.cpp:90:17
    frame #18: 0x0000000100eff104 Kodi`CApplication::OnMessage(this=0x0000000151704b00, message=0x0000600003b6fc60) at Application.cpp:2820:9
    frame #19: 0x00000001015ab0bc Kodi`CGUIWindowManager::SendMessage(this=0x000000015167d9a0, message=0x0000600003b6fc60) at GUIWindowManager.cpp:510:23
    frame #20: 0x00000001015b1ae4 Kodi`CGUIWindowManager::DispatchThreadMessages(this=0x000000015167d9a0) at GUIWindowManager.cpp:1572:7
    frame #21: 0x0000000100f0266c Kodi`CApplication::Process(this=0x0000000151704b00) at Application.cpp:3203:48
    frame #22: 0x0000000100efbc28 Kodi`CApplication::Run(this=0x0000000151704b00) at Application.cpp:1925:5
    frame #23: 0x0000000101b31d54 Kodi`XBMC_Run(renderGUI=true) at xbmc.cpp:61:26
    frame #24: 0x00000001009892c0 Kodi`__46-[XBMCDelegate applicationDidFinishLaunching:]_block_invoke(.block_descriptor=0x000000010597e450) at XBMCApplication.mm:158:5
    frame #25: 0x0000000196a5c520 Foundation`__NSThread__start__ + 716
    frame #26: 0x000000010c5e55c0 libsystem_pthread.dylib`_pthread_start + 136

  thread #70, name = 'VideoPlayer'
    frame #0: 0x00000001958159ec libsystem_kernel.dylib`__psynch_cvwait + 8
    frame #1: 0x000000010c5e9c00 libsystem_pthread.dylib`_pthread_cond_wait + 1228
    frame #2: 0x0000000195778b14 libc++.1.dylib`std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28
    frame #3: 0x0000000100cf02f0 Kodi`void std::__1::condition_variable_any::wait<XbmcThreads::CRecursiveMutex>(this=0x0000600002c9d070, __lock=0x0000600002c9d0b0) at condition_variable:214:11
    frame #4: 0x0000000100cf0264 Kodi`void std::__1::condition_variable_any::wait[abi:ue170006]<XbmcThreads::CRecursiveMutex, std::__1::function<bool ()>>(this=0x0000600002c9d070, __lock=0x0000600002c9d0b0, __pred= Function = CEvent::Signaled() ) at condition_variable:223:9
    frame #5: 0x0000000100cf01b8 Kodi`XbmcThreads::ConditionVariable::wait(this=0x0000600002c9d070, lock=0x0000600002c9d0b0, predicate=function<bool ()> @ 0x0000000316fc53f8) at Condition.h:40:12
    frame #6: 0x0000000100cef814 Kodi`CEvent::Wait(this=0x0000600002c9d018) at Event.h:113:14
    frame #7: 0x00000001018380dc Kodi`KODI::MESSAGING::CApplicationMessenger::SendMsg(this=0x0000600002f70018, message=0x0000000316fc5570, wait=true) at ApplicationMessenger.cpp:141:18
    frame #8: 0x0000000101838744 Kodi`KODI::MESSAGING::CApplicationMessenger::SendMsg(this=0x0000600002f70018, messageId=1073741838, param1=26, param2=0, payload=0x0000000000000000) at ApplicationMessenger.cpp:156:10
    frame #9: 0x000000010221aca0 Kodi`CGraphicContext::SetVideoResolution(this=0x000000015161eb20, res=26, forceUpdate=false) at GraphicContext.cpp:394:40
    frame #10: 0x00000001011886a0 Kodi`CVideoPlayer::OpenVideoStream(this=0x00000001330cac18, hint=0x0000000316fc5c28, reset=true) at VideoPlayer.cpp:3763:55
    frame #11: 0x00000001011789ec Kodi`CVideoPlayer::OpenStream(this=0x00000001330cac18, current=0x00000001330cb340, demuxerId=7, iStream=0, source=256, reset=true) at VideoPlayer.cpp:3621:13
    frame #12: 0x000000010117756c Kodi`CVideoPlayer::OpenDefaultStreams(this=0x00000001330cac18, reset=true) at VideoPlayer.cpp:890:9
    frame #13: 0x000000010117a6d8 Kodi`CVideoPlayer::Prepare(this=0x00000001330cac18) at VideoPlayer.cpp:1266:5
    frame #14: 0x000000010117c5e0 Kodi`CVideoPlayer::Process(this=0x00000001330cac18) at VideoPlayer.cpp:1363:3
    frame #15: 0x0000000101f3e5f0 Kodi`CThread::Action(this=0x00000001330cac18) at Thread.cpp:283:5
    frame #16: 0x0000000101f3fc60 Kodi`CThread::Create(bool)::$_0::operator()(this=0x00006000011eeb20, pThread=0x00000001330cac18, promise=promise<bool> @ 0x0000000316fc6f30) const at Thread.cpp:152:18
    frame #17: 0x0000000101f3f948 Kodi`decltype(std::declval<CThread::Create(bool)::$_0>()(std::declval<CThread*>(), std::declval<std::__1::promise<bool>>())) std::__1::__invoke[abi:ue170006]<CThread::Create(bool)::$_0, CThread*, std::__1::promise<bool>>(__f=0x00006000011eeb20, __args=0x00006000011eeb28, __args=0x00006000011eeb30) at invoke.h:340:25
    frame #18: 0x0000000101f3f8f0 Kodi`void std::__1::__thread_execute[abi:ue170006]<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, CThread::Create(bool)::$_0, CThread*, std::__1::promise<bool>, 2ul, 3ul>(__t=size=4, (null)=__tuple_indices<2UL, 3UL> @ 0x0000000316fc6f7f) at thread.h:227:5
    frame #19: 0x0000000101f3f4ec Kodi`void* std::__1::__thread_proxy[abi:ue170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, CThread::Create(bool)::$_0, CThread*, std::__1::promise<bool>>>(__vp=0x00006000011eeb20) at thread.h:238:5
    frame #20: 0x000000010c5e55c0 libsystem_pthread.dylib`_pthread_start + 136

@enen92
Copy link
Member Author

enen92 commented May 4, 2024

@ksooo mind giving a go to:

From 0dc8347a94f0a71eeed10903d3f3fb09b59def3b Mon Sep 17 00:00:00 2001
From: Miguel Borges de Freitas <[email protected]>
Date: Sat, 4 May 2024 16:56:54 +0100
Subject: [PATCH] Rendering: Set window dirty only on app thread

---
 xbmc/application/Application.cpp                 | 11 ++++++++++-
 xbmc/application/Application.h                   |  2 ++
 xbmc/application/ApplicationPowerHandling.cpp    |  6 ------
 .../osx/OpenGL/WindowControllerMacOS.mm          | 16 ----------------
 4 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/xbmc/application/Application.cpp b/xbmc/application/Application.cpp
index 6741845c75..6046d2d82e 100644
--- a/xbmc/application/Application.cpp
+++ b/xbmc/application/Application.cpp
@@ -809,7 +809,16 @@ void CApplication::Render()
     return;

   // render gui layer
-  if (appPower->GetRenderGUI() && !m_skipGuiRender)
+  const bool renderGUI = appPower->GetRenderGUI();
+  if (m_guiRenderLastState != std::nullopt && renderGUI && m_guiRenderLastState != renderGUI)
+  {
+    CGUIComponent* gui = CServiceBroker::GetGUI();
+    if (gui)
+      CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
+  }
+  m_guiRenderLastState = renderGUI;
+
+  if (renderGUI && !m_skipGuiRender)
   {
     if (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode())
     {
diff --git a/xbmc/application/Application.h b/xbmc/application/Application.h
index d31e591bcd..b3eaeb5bd4 100644
--- a/xbmc/application/Application.h
+++ b/xbmc/application/Application.h
@@ -24,6 +24,7 @@
 #include <atomic>
 #include <chrono>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>

@@ -218,6 +219,7 @@ protected:

   std::chrono::time_point<std::chrono::steady_clock> m_lastRenderTime;
   bool m_skipGuiRender = false;
+  std::optional<bool> m_guiRenderLastState;

   std::unique_ptr<MUSIC_INFO::CMusicInfoScanner> m_musicInfoScanner;

diff --git a/xbmc/application/ApplicationPowerHandling.cpp b/xbmc/application/ApplicationPowerHandling.cpp
index 4354b9b626..8000a7ee9e 100644
--- a/xbmc/application/ApplicationPowerHandling.cpp
+++ b/xbmc/application/ApplicationPowerHandling.cpp
@@ -67,12 +67,6 @@ void CApplicationPowerHandling::ResetNavigationTimer()

 void CApplicationPowerHandling::SetRenderGUI(bool renderGUI)
 {
-  if (renderGUI && !m_renderGUI)
-  {
-    CGUIComponent* gui = CServiceBroker::GetGUI();
-    if (gui)
-      CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
-  }
   m_renderGUI = renderGUI;
 }

diff --git a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
index 4f50a49dbc..c3eaa113c2 100644
--- a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
+++ b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
@@ -22,8 +22,6 @@

 @implementation XBMCWindowControllerMacOS

-bool m_inFullscreenTransition = false;
-
 - (nullable instancetype)initWithTitle:(NSString*)title defaultSize:(NSSize)size
 {
   auto frame = NSMakeRect(0, 0, size.width, size.height);
@@ -81,9 +79,6 @@ - (void)windowDidResize:(NSNotification*)aNotification

 - (void)windowWillStartLiveResize:(NSNotification*)notification
 {
-  if (m_inFullscreenTransition)
-    return;
-
   std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
   if (appPort)
   {
@@ -93,9 +88,6 @@ - (void)windowWillStartLiveResize:(NSNotification*)notification

 - (void)windowDidEndLiveResize:(NSNotification*)notification
 {
-  if (m_inFullscreenTransition)
-    return;
-
   std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
   if (appPort)
   {
@@ -196,14 +188,8 @@ - (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize
   return frameSize;
 }

-- (void)windowWillExitFullScreen:(NSNotification*)notification
-{
-  m_inFullscreenTransition = true;
-}
-
 - (void)windowWillEnterFullScreen:(NSNotification*)pNotification
 {
-  m_inFullscreenTransition = true;
   CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
   if (!winSystem)
     return;
@@ -241,7 +227,6 @@ - (NSApplicationPresentationOptions)window:(NSWindow*)window

 - (void)windowDidExitFullScreen:(NSNotification*)pNotification
 {
-  m_inFullscreenTransition = false;
   auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
   if (!winSystem)
     return;
@@ -268,7 +253,6 @@ - (void)windowDidExitFullScreen:(NSNotification*)pNotification

 - (void)windowDidEnterFullScreen:(NSNotification*)notification
 {
-  m_inFullscreenTransition = false;
   auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
   if (!winSystem)
     return;
--
2.39.3 (Apple Git-146)

@ksooo
Copy link
Member

ksooo commented May 4, 2024

@enen92 seems to work. Tried several times - no deadlock anymore. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants