sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx |    9 
+++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

New commits:
commit b206d6a95cf90fcbcd8f76b79f538375e93c2ba8
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Sep 26 11:10:49 2025 +0200
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Sep 26 13:06:37 2025 +0200

    Avoid a deadlock
    
    Seen accidentally in JunitTest_forms_unoapi_3 (I believe).
    The main thread owned solar mutex, and was trying to lock
    ChangeRequestQueueProcessor::maMutex:
    
      sal3.dll!osl_acquireMutex(_oslMutexImpl * Mutex) Line 65
      sdlo.dll!osl::Mutex::acquire() Line 63
      sdlo.dll!osl::Guard<osl::Mutex>::Guard<osl::Mutex>(osl::Mutex & t) Line 
144
      sdlo.dll!sd::framework::ChangeRequestQueueProcessor::ProcessEvent(void * 
__formal) Line 111
      
sdlo.dll!sd::framework::ChangeRequestQueueProcessor::LinkStubProcessEvent(void 
* instance, void * data) Line 109
      vcllo.dll!Link<void *,void>::Call(void * data) Line 105
      vcllo.dll!ImplHandleUserEvent(ImplSVEvent * pSVEvent) Line 2312
      vcllo.dll!ImplWindowFrameProc(vcl::Window * _pWindow, SalEvent nEvent, 
const void * pEvent) Line 2869
      vcllo.dll!SalFrame::CallCallback(SalEvent nEvent, const void * pEvent) 
Line 310
      vclplug_winlo.dll!ImplHandleUserEvent(HWND__ * hWnd, __int64 lParam) Line 
4525
      vclplug_winlo.dll!SalFrameWndProc(HWND__ * hWnd, unsigned int nMsg, 
unsigned __int64 wParam, __int64 lParam, bool & rDef) Line 6120
      vclplug_winlo.dll!SalFrameWndProcW(HWND__ * hWnd, unsigned int nMsg, 
unsigned __int64 wParam, __int64 lParam) Line 6226
      user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 
(*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum 
_WM_VALUE,unsigned __int64,__int64,void *,int)
      user32.dll!DispatchMessageWorker()
      vclplug_winlo.dll!ImplSalDispatchMessage(const tagMSG * pMsg) Line 431
      vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) 
Line 462
      vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool 
bHandleAllCurrentEvents) Line 537
      vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) Line 389
      vcllo.dll!Application::Yield() Line 492
      vcllo.dll!Application::Execute() Line 365
      sofficeapp.dll!desktop::Desktop::Main() Line 1682
      vcllo.dll!ImplSVMain() Line 230
      vcllo.dll!SVMain() Line 249
      sofficeapp.dll!soffice_main() Line 122
      soffice.bin!sal_main() Line 51
      soffice.bin!main(int argc, char * * argv) Line 49
      soffice.bin!invoke_main() Line 79
      soffice.bin!__scrt_common_main_seh() Line 288
      soffice.bin!__scrt_common_main() Line 331
      soffice.bin!mainCRTStartup(void * __formal) Line 17
      kernel32.dll!BaseThreadInitThunk()
      ntdll.dll!RtlUserThreadStart()
    
    which was locked in another thread, itself trying to lock solar mutex:
    
      sal3.dll!osl_acquireMutex(_oslMutexImpl * Mutex) Line 65
      vclplug_winlo.dll!osl::Mutex::acquire() Line 63
      vclplug_winlo.dll!SalYieldMutex::doAcquire(unsigned long nLockCount) Line 
145
      comphelper.dll!comphelper::SolarMutex::acquire(unsigned long nLockCount) 
Line 86
      vcllo.dll!SalInstance::AcquireYieldMutex(unsigned long nCount) Line 146
      vcllo.dll!Application::AcquireSolarMutex(unsigned long nCount) Line 527
      vclplug_winlo.dll!SolarMutexReleaser::~SolarMutexReleaser() Line 1426
      vclplug_winlo.dll!SolarMutexReleaser::`scalar deleting 
destructor'(unsigned int)
      
vclplug_winlo.dll!std::_Optional_destruct_base<SolarMutexReleaser,0>::~_Optional_destruct_base<SolarMutexReleaser,0>()
 Line 109
      
vclplug_winlo.dll!std::_Optional_construct_base<SolarMutexReleaser>::~_Optional_construct_base<SolarMutexReleaser>()
      
vclplug_winlo.dll!std::_Non_trivial_copy<std::_Optional_construct_base<SolarMutexReleaser>>::~_Non_trivial_copy<std::_Optional_construct_base<SolarMutexReleaser>>()
      
vclplug_winlo.dll!std::_Non_trivial_move<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>::~_Non_trivial_move<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>()
      
vclplug_winlo.dll!std::_Deleted_copy_assign<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>::~_Deleted_copy_assign<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>()
      
vclplug_winlo.dll!std::_Deleted_move_assign<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>::~_Deleted_move_assign<std::_Optional_construct_base<SolarMutexReleaser>,SolarMutexReleaser>()
      
vclplug_winlo.dll!std::optional<SolarMutexReleaser>::~optional<SolarMutexReleaser>()
      vclplug_winlo.dll!WinSalInstance::SendWndMessage_impl(HWND__ * hWnd, 
unsigned int Msg, unsigned __int64 wParam, __int64 lParam) Line 771
      vclplug_winlo.dll!WinSalInstance::SendComWndMessage(unsigned int Msg, 
unsigned __int64 wParam, __int64 lParam) Line 782
      vclplug_winlo.dll!WinSalInstance::CreateFrame(SalFrame * pParent, 
SalFrameStyleFlags nSalFrameStyle) Line 799
      vcllo.dll!vcl::Window::ImplInit(vcl::Window * pParent, __int64 nStyle, 
SystemParentData * pSystemParentData) Line 1054
      vcllo.dll!ImplBorderWindow::ImplInit(vcl::Window * pParent, __int64 
nStyle, BorderWindowStyle nTypeStyle, SystemParentData * pSystemParentData) 
Line 1566
      vcllo.dll!ImplBorderWindow::ImplBorderWindow(vcl::Window * pParent, 
SystemParentData * pSystemParentData, __int64 nStyle, BorderWindowStyle 
nTypeStyle) Line 1594
      
vcllo.dll!VclPtrInstance<ImplBorderWindow>::VclPtrInstance<ImplBorderWindow><vcl::Window
 * &,SystemParentData * &,__int64 &,enum BorderWindowStyle &>(vcl::Window * & 
<arg_0>, SystemParentData * & <arg_1>, __int64 & <arg_2>, BorderWindowStyle & 
<arg_3>) Line 258
      vcllo.dll!WorkWindow::ImplInit(vcl::Window * pParent, __int64 nStyle, 
SystemParentData * pSystemParentData) Line 51
      vcllo.dll!WorkWindow::WorkWindow(vcl::Window * pParent, __int64 nStyle) 
Line 95
      sdlo.dll!VclPtr<WorkWindow>::Create<std::nullptr_t,__int64 const &>(void 
* && <arg_0>, const __int64 & <arg_1>) Line 143
      sdlo.dll!sd::framework::BasicViewFactory::BasicViewFactory(const 
rtl::Reference<sd::DrawController> & rxController) Line 74
      sdlo.dll!sd::framework::ModuleController::requestResource(const 
rtl::OUString & rsResourceURL) Line 142
      sdlo.dll!sd::framework::ResourceFactoryManager::GetFactory(const 
rtl::OUString & rsCompleteURL) Line 137
      
sdlo.dll!sd::framework::ConfigurationControllerResourceManager::ActivateResource(const
 rtl::Reference<sd::framework::ResourceId> & rxResourceId, const 
rtl::Reference<sd::framework::Configuration> & rxConfiguration) Line 117
      
sdlo.dll!sd::framework::ConfigurationControllerResourceManager::ActivateResources(const
 
std::vector<rtl::Reference<sd::framework::ResourceId>,std::allocator<rtl::Reference<sd::framework::ResourceId>>>
 & rResources, const rtl::Reference<sd::framework::Configuration> & 
rxConfiguration) Line 75
      sdlo.dll!sd::framework::ConfigurationUpdater::UpdateCore(const 
sd::framework::ConfigurationClassifier & rClassifier) Line 251
      sdlo.dll!sd::framework::ConfigurationUpdater::UpdateConfiguration() Line 
161
      sdlo.dll!sd::framework::ConfigurationUpdater::RequestUpdate(const 
rtl::Reference<sd::framework::Configuration> & rxRequestedConfiguration) Line 
108
      sdlo.dll!sd::framework::ChangeRequestQueueProcessor::ProcessOneEvent() 
Line 158
      sdlo.dll!sd::framework::ConfigurationController::ProcessEvent() Line 157
      sdlo.dll!sd::ViewShellBase::LateInit(const rtl::OUString & rsDefaultView) 
Line 345
      sdlo.dll!sd::GraphicViewShellBase::CreateInstance(SfxViewFrame & rFrame, 
SfxViewShell * pOldView) Line 42
      sfxlo.dll!SfxViewFactory::CreateInstance(SfxViewFrame & rFrame, 
SfxViewShell * pOldSh) Line 27
      sfxlo.dll!SfxBaseModel::createViewController(const rtl::OUString & 
i_rViewName, const 
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & 
i_rArguments, const 
com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & i_rFrame) Line 
4365
      sfxlo.dll!`anonymous 
namespace'::SfxFrameLoader_Impl::impl_createDocumentView(const 
com::sun::star::uno::Reference<com::sun::star::frame::XModel2> & i_rModel, 
const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & i_rFrame, 
const comphelper::NamedValueCollection & i_rViewFactoryArgs, const 
rtl::OUString & i_rViewName) Line 586
      sfxlo.dll!`anonymous namespace'::SfxFrameLoader_Impl::load(const 
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & rArgs, 
const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & 
_rTargetFrame) Line 812
      fwklo.dll!framework::LoadEnv::impl_loadContent() Line 1181
      fwklo.dll!framework::LoadEnv::start() Line 416
      fwklo.dll!framework::LoadEnv::startLoading(const rtl::OUString & sURL, 
const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & 
lMediaDescriptor, const 
com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & xBaseFrame, 
const rtl::OUString & sTarget, long nSearchFlags, LoadEnvFeatures eFeature) 
Line 312
      fwklo.dll!framework::LoadEnv::loadComponentFromURL(const 
com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> & 
xLoader, const 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
xContext, const rtl::OUString & sURL, const rtl::OUString & sTarget, long 
nSearchFlags, const 
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & lArgs) 
Line 168
      fwklo.dll!framework::Desktop::loadComponentFromURL(const rtl::OUString & 
sURL, const rtl::OUString & sTargetFrameName, long nSearchFlags, const 
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & 
lArguments) Line 594
      mscx_uno.dll!`anonymous 
namespace'::cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 
bridges::cpp_uno::shared::VtableSlot aVtableSlot, 
_typelib_TypeDescriptionReference * pReturnTypeRef, long nParams, 
_typelib_MethodParameter * pParams, void * pUnoReturn, void * * pUnoArgs, 
_uno_Any * * ppUnoExc) Line 214
      mscx_uno.dll!unoInterfaceProxyDispatch(_uno_Interface * pUnoI, const 
_typelib_TypeDescription * pMemberTD, void * pReturn, void * * pArgs, _uno_Any 
* * ppException) Line 430
      
binaryurplo.dll!binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny 
* returnValue, 
std::vector<binaryurp::BinaryAny,std::allocator<binaryurp::BinaryAny>> * 
outArguments) Line 239
      binaryurplo.dll!binaryurp::IncomingRequest::execute() Line 79
      binaryurplo.dll!request(void * pThreadSpecificData) Line 84
      cppu3.dll!cppu_threadpool::JobQueue::enter(const void * nDisposeId, bool 
bReturnWhenNoJob) Line 101
      cppu3.dll!cppu_threadpool::ORequestThread::run() Line 165
      cppu3.dll!threadFunc(void * param) Line 190
      sal3.dll!oslWorkerWrapperFunction(void * pData) Line 67
      ucrtbased.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * 
const parameter) Line 97
      kernel32.dll!BaseThreadInitThunk()
      ntdll.dll!RtlUserThreadStart()
    
    I can't reproduce it, so this is a blind fix.
    
    Change-Id: Ib3142ea924dca5fc40c671ee2c6d2c9e22510a18
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191531
    Reviewed-by: Mike Kaganski <[email protected]>
    Tested-by: Jenkins

diff --git 
a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx 
b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx
index dbdd837e3a21..c6727559e538 100644
--- a/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx
+++ b/sd/source/ui/framework/configuration/ChangeRequestQueueProcessor.cxx
@@ -123,7 +123,7 @@ IMPL_LINK_NOARG(ChangeRequestQueueProcessor, ProcessEvent, 
void*, void)
 
 void ChangeRequestQueueProcessor::ProcessOneEvent()
 {
-    ::osl::MutexGuard aGuard (maMutex);
+    osl::ClearableMutexGuard aGuard(maMutex);
 
     SAL_INFO("sd.fwk", __func__ << ": ProcessOneEvent");
 
@@ -155,7 +155,12 @@ void ChangeRequestQueueProcessor::ProcessOneEvent()
         ConfigurationTracer::TraceConfiguration (
             mxConfiguration, "updating to configuration");
 #endif
-        mpConfigurationUpdater->RequestUpdate(mxConfiguration);
+        // RequestUpdate may eventually call a code that needs to lock a solar 
mutex, owned by
+        // another thread, that waits for maMutex; release it here, to avoid 
deadlocks
+        auto pConfigurationUpdater = mpConfigurationUpdater;
+        auto xConfiguration = mxConfiguration;
+        aGuard.clear();
+        pConfigurationUpdater->RequestUpdate(xConfiguration);
     }
 }
 

Reply via email to