summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/task.hxx10
-rw-r--r--svx/source/svdraw/svdetc.cxx1
-rw-r--r--vcl/README.scheduler7
-rw-r--r--vcl/source/app/scheduler.cxx14
-rw-r--r--vcl/win/gdi/salbmp.cxx2
5 files changed, 30 insertions, 4 deletions
diff --git a/include/vcl/task.hxx b/include/vcl/task.hxx
index e45fe3f5ae73..2711d4343932 100644
--- a/include/vcl/task.hxx
+++ b/include/vcl/task.hxx
@@ -47,6 +47,7 @@ class VCL_DLLPUBLIC Task
const sal_Char *mpDebugName; ///< Useful for debugging
TaskPriority mePriority; ///< Task priority
bool mbActive; ///< Currently in the scheduler
+ bool mbStatic; ///< Is a static object
protected:
static void StartTimer( sal_uInt64 nMS );
@@ -88,6 +89,15 @@ public:
void Stop();
bool IsActive() const { return mbActive; }
+
+ /**
+ * This function must be called for static tasks, so the Task destructor
+ * ignores the SchedulerMutex, as it may not be available anymore.
+ * The cleanup is still correct, as it has already happened in
+ * DeInitScheduler call well before the static destructor calls.
+ */
+ void SetStatic() { mbStatic = true; }
+ bool IsStatic() const { return mbStatic; }
};
#endif // INCLUDED_VCL_TASK_HXX
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 89c17590984c..3cc369a49be5 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -112,6 +112,7 @@ OLEObjCache::OLEObjCache()
pTimer = new AutoTimer( "svx OLEObjCache pTimer UnloadCheck" );
pTimer->SetInvokeHandler( LINK(this, OLEObjCache, UnloadCheckHdl) );
pTimer->SetTimeout(20000);
+ pTimer->SetStatic();
}
OLEObjCache::~OLEObjCache()
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