[Libreoffice-commits] core.git: tools/source vcl/inc vcl/win
Jan Holesovsky
kendy at collabora.com
Thu Sep 25 13:00:25 PDT 2014
tools/source/datetime/ttime.cxx | 13 ++++++-------
vcl/inc/win/saldata.hxx | 2 +-
vcl/win/source/app/salinst.cxx | 17 ++++++++++++++---
vcl/win/source/app/saltimer.cxx | 27 ++++++++++++++++-----------
4 files changed, 37 insertions(+), 22 deletions(-)
New commits:
commit d68ce6e173502e1b1ce214503f41729a8502cd92
Author: Jan Holesovsky <kendy at collabora.com>
Date: Thu Sep 25 16:30:05 2014 +0200
fdo#84000: Sort out problems with short timeouts & long callbacks.
Previously, the timer events could have accumulated in that scenario leading
to unresponsiveness to user events.
Change-Id: I455d726ae7475f7dbf98d871c54d8c156cb64e52
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
index 71836e7..66d16b4 100644
--- a/tools/source/datetime/ttime.cxx
+++ b/tools/source/datetime/ttime.cxx
@@ -400,19 +400,18 @@ Time Time::GetUTCOffset()
sal_uIntPtr Time::GetSystemTicks()
{
#if defined WNT
- static LARGE_INTEGER nTicksPerMS;
- static bool bTicksPerMSInitialized = false;
- if (!bTicksPerMSInitialized)
+ static LARGE_INTEGER nTicksPerSecond;
+ static bool bTicksPerSecondInitialized = false;
+ if (!bTicksPerSecondInitialized)
{
- QueryPerformanceFrequency(&nTicksPerMS);
- nTicksPerMS.QuadPart /= 1000;
- bTicksPerMSInitialized = true;
+ QueryPerformanceFrequency(&nTicksPerSecond);
+ bTicksPerSecondInitialized = true;
}
LARGE_INTEGER nPerformanceCount;
QueryPerformanceCounter(&nPerformanceCount);
- return (sal_uIntPtr)(nPerformanceCount.QuadPart/nTicksPerMS.QuadPart);
+ return (sal_uIntPtr)((nPerformanceCount.QuadPart*1000)/nTicksPerSecond.QuadPart);
#else
timeval tv;
gettimeofday (&tv, 0);
diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index a50e67d..e1ae8cc 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -180,7 +180,7 @@ void ImplSalAcquireYieldMutex( sal_uLong nCount );
LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
-void EmitTimerCallback(bool bAllowRecursive);
+void EmitTimerCallback();
void SalTestMouseLeave();
bool ImplWriteLastError( DWORD lastError, const char *szApiCall );
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
index 57dfc28..b1d33e4 100644
--- a/vcl/win/source/app/salinst.cxx
+++ b/vcl/win/source/app/salinst.cxx
@@ -345,7 +345,6 @@ SalData::SalData()
mnNextTimerTime = 0;
mnLastEventTime = 0;
mnTimerId = 0; // windows timer id
- mbInTimerProc = FALSE; // timer event is currently being dispatched
mhSalObjMsgHook = 0; // hook to get interesting msg for SalObject
mhWantLeaveMsg = 0; // window handle, that want a MOUSELEAVE message
mpMouseLeaveTimer = 0; // Timer for MouseLeave Test
@@ -731,10 +730,22 @@ LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lPar
rDef = FALSE;
break;
case SAL_MSG_POSTTIMER:
- EmitTimerCallback(/*bAllowRecursive = */ true);
+ EmitTimerCallback();
break;
case SAL_MSG_TIMER_CALLBACK:
- EmitTimerCallback(/*bAllowRecursive = */ false);
+ EmitTimerCallback();
+ MSG aMsg;
+ while (PeekMessageW(&aMsg, 0, SAL_MSG_TIMER_CALLBACK, SAL_MSG_TIMER_CALLBACK, PM_REMOVE))
+ {
+ // nothing; just remove all the SAL_MSG_TIMER_CALLBACKs that
+ // accumulated in the queue during the EmitTimerCallback(),
+ // otherwise it happens with short timeouts and long callbacks
+ // that no other events will ever be processed, as the queue
+ // is full of SAL_MSG_TIMER_CALLBACKs.
+ // It is impossible to limit the amount of them being emited
+ // in the first place, as they are emited asynchronously, but
+ // here we are already fully synchronized.
+ }
break;
}
diff --git a/vcl/win/source/app/saltimer.cxx b/vcl/win/source/app/saltimer.cxx
index 9191d5e..e1ce31e 100644
--- a/vcl/win/source/app/saltimer.cxx
+++ b/vcl/win/source/app/saltimer.cxx
@@ -54,9 +54,11 @@ void ImplSalStartTimer( sal_uLong nMS, bool bMutex )
if (nMS > MAX_SYSPERIOD)
nMS = MAX_SYSPERIOD;
- // can't change a one-shot timer if it has fired already (odd) so delete & re-create
- ImplSalStopTimer(pSalData);
- CreateTimerQueueTimer(&pSalData->mnTimerId, NULL, SalTimerProc, NULL, nMS, nMS, WT_EXECUTEDEFAULT);
+ // change if it exists, create if not
+ if (pSalData->mnTimerId)
+ ChangeTimerQueueTimer(NULL, pSalData->mnTimerId, nMS, nMS);
+ else
+ CreateTimerQueueTimer(&pSalData->mnTimerId, NULL, SalTimerProc, NULL, nMS, nMS, WT_EXECUTEDEFAULT);
pSalData->mnNextTimerTime = pSalData->mnLastEventTime + nMS;
}
@@ -111,6 +113,10 @@ void CALLBACK SalTimerProc(PVOID, BOOLEAN)
#endif
SalData* pSalData = GetSalData();
+
+ // always post message when the timer fires, we will remove the ones
+ // that happened during execution of the callback later directly from
+ // the message queue
PostMessageW(pSalData->mpFirstInstance->mhComWnd, SAL_MSG_TIMER_CALLBACK, 0, 0);
#if defined ( __MINGW32__ ) && !defined ( _WIN64 )
@@ -128,11 +134,8 @@ void CALLBACK SalTimerProc(PVOID, BOOLEAN)
We assured that by posting the message from the SalTimeProc only, the real
call then happens when the main thread gets SAL_MSG_TIMER_CALLBACK.
-
- at param bAllowRecursive allows to skip the check that assures that two timeouts
-do not overlap.
*/
-void EmitTimerCallback(bool bAllowRecursive)
+void EmitTimerCallback()
{
SalData* pSalData = GetSalData();
ImplSVData* pSVData = ImplGetSVData();
@@ -142,13 +145,15 @@ void EmitTimerCallback(bool bAllowRecursive)
// Try to acquire the mutex. If we don't get the mutex then we
// try this a short time later again.
- if (ImplSalYieldMutexTryToAcquire() &&
- (pSVData->mpSalTimer && (!pSalData->mbInTimerProc || bAllowRecursive)))
+ if (pSVData->mpSalTimer && ImplSalYieldMutexTryToAcquire())
{
- pSalData->mbInTimerProc = true;
pSVData->mpSalTimer->CallCallback();
- pSalData->mbInTimerProc = false;
ImplSalYieldMutexRelease();
+
+ // Run the timer in the correct time, if we started this
+ // with a small timeout, because we didn't get the mutex
+ if (pSalData->mnTimerId && (pSalData->mnTimerMS != pSalData->mnTimerOrgMS))
+ ImplSalStartTimer(pSalData->mnTimerOrgMS, false);
}
else
{
More information about the Libreoffice-commits
mailing list