diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2017-08-23 16:07:50 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2017-09-21 12:02:49 +0200 |
commit | 06ce312f79cb0871c0b110ba4bff16f5aaa0f538 (patch) | |
tree | c50424e53902a565d700321740f5898b9d6f004b /vcl | |
parent | 1cfcbf3573206c2e9c435f276ba8d7431c75665c (diff) |
Workaround static Task destruction error
A task has to get the SchedulerLock to remove itself from the
Scheduler list. This doesn't work, if the Task is static, as the
static Scheduler might be destroyed earlier. In this case we fail
with the following backtrace:
#0 SchedulerMutex::acquire
#1 Task::~Task
#2 __run_exit_handlers
Thanks to Michael Stahl to catching this backtrace.
As a workaround this marks static tasks, so they ignore the
SchedulerMutex in the destructor, We also mark all scheduled Tasks
as "static" in DeInitScheduler, as their cleanup was already done.
In the end all Tasks should be removed from static objects.
Change-Id: I38be3206378b9449193efaccbc96896ac8de9478
Reviewed-on: https://gerrit.libreoffice.org/42574
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/README.scheduler | 7 | ||||
-rw-r--r-- | vcl/source/app/scheduler.cxx | 14 | ||||
-rw-r--r-- | vcl/win/gdi/salbmp.cxx | 2 |
3 files changed, 19 insertions, 4 deletions
diff --git a/vcl/README.scheduler b/vcl/README.scheduler index 271ce1949695..7e80c1f04eb8 100644 --- a/vcl/README.scheduler +++ b/vcl/README.scheduler @@ -172,6 +172,13 @@ Since the Scheduler is always handled by the system message queue, there is really no more reasoning to stop after 100 events to prevent LO Scheduler starvation. +== Drop static inherited or composed Task objects == + +The sequence of destruction of static objects is not defined. So a static Task +can not be guaranteed to happen before the Scheduler. When dynamic unloading +is involved, this becomes an even worse problem. This way we could drop the +mbStatic workaround from the Task class. + == Run the LO application in its own thread == This would probably get rid of most of the MacOS and Windows implementation diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index f20c3ae41677..18e9edb8132c 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -160,6 +160,7 @@ void Scheduler::ImplDeInitScheduler() pTask->mbActive = false; } pTask->mpSchedulerData = nullptr; + pTask->SetStatic(); } ImplSchedulerData* pDeleteSchedulerData = pSchedulerData; pSchedulerData = pSchedulerData->mpNext; @@ -548,6 +549,7 @@ Task::Task( const sal_Char *pDebugName ) , mpDebugName( pDebugName ) , mePriority( TaskPriority::DEFAULT ) , mbActive( false ) + , mbStatic( false ) { } @@ -556,6 +558,7 @@ Task::Task( const Task& rTask ) , mpDebugName( rTask.mpDebugName ) , mePriority( rTask.mePriority ) , mbActive( false ) + , mbStatic( false ) { if ( rTask.IsActive() ) Start(); @@ -563,9 +566,14 @@ Task::Task( const Task& rTask ) Task::~Task() COVERITY_NOEXCEPT_FALSE { - SchedulerGuard aSchedulerGuard; - if ( mpSchedulerData ) - mpSchedulerData->mpTask = nullptr; + if ( !IsStatic() ) + { + SchedulerGuard aSchedulerGuard; + if ( mpSchedulerData ) + mpSchedulerData->mpTask = nullptr; + } + else + assert( nullptr == mpSchedulerData ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx index c9216bfd0109..fb8fb10d8055 100644 --- a/vcl/win/gdi/salbmp.cxx +++ b/vcl/win/gdi/salbmp.cxx @@ -80,7 +80,7 @@ public: maEntries() { SetTimeout(1000); - Stop(); + SetStatic(); } ~GdiPlusBuffer() override |