Windows 8+: make waiting for messages correspond to emptiness check
Fixes high cpu usage spikes on win10. When queue was containing messages of only non-QS_POSTMESSAGE type the "while (m_buffer->isEmpty())" busy-looped in EventQueue::getEvent since isEmpty was true (checked only QS_POSTMESSAGE message type), but waitForEvent returned immediately (checked more message types). Investigation shows that the difference was introduced in https://github.com/debauchee/barrier/commit/dbfb04a6e to fix a problem with bad behaviour of GetQueueStatus Researching showed that a similar problem was fixed in Qt, and the solution was "pass different flags to GetQueueStatus depending on version of windows" https://bugreports.qt.io/browse/QTBUG-29097 So this patch makes changes to a barrier non-GUI core similar to Qt fix.
This commit is contained in:
parent
8ab6ad64f9
commit
95f2a840be
|
@ -21,6 +21,7 @@
|
|||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "base/IEventQueue.h"
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
//
|
||||
// EventQueueTimer
|
||||
|
@ -48,6 +49,15 @@ MSWindowsEventQueueBuffer::MSWindowsEventQueueBuffer(IEventQueue* events) :
|
|||
// make sure this thread has a message queue
|
||||
MSG dummy;
|
||||
PeekMessage(&dummy, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
||||
|
||||
m_os_supported_message_types = QS_ALLINPUT;
|
||||
if (!IsWindows8OrGreater())
|
||||
{
|
||||
// don't use QS_POINTER, QS_TOUCH
|
||||
// because they can cause GetQueueStatus() to always return 0 and we miss events
|
||||
// since those flags are confusing Windows 7. See QTBUG-29097 for related info
|
||||
m_os_supported_message_types &= ~(QS_TOUCH | QS_POINTER);
|
||||
}
|
||||
}
|
||||
|
||||
MSWindowsEventQueueBuffer::~MSWindowsEventQueueBuffer()
|
||||
|
@ -79,7 +89,7 @@ MSWindowsEventQueueBuffer::waitForEvent(double timeout)
|
|||
// cancellation but that's okay because we're run in the main
|
||||
// thread and we never cancel that thread.
|
||||
HANDLE dummy[1];
|
||||
MsgWaitForMultipleObjects(0, dummy, FALSE, t, QS_ALLINPUT);
|
||||
MsgWaitForMultipleObjects(0, dummy, FALSE, t, m_os_supported_message_types);
|
||||
}
|
||||
|
||||
IEventQueueBuffer::Type
|
||||
|
@ -128,9 +138,7 @@ MSWindowsEventQueueBuffer::addEvent(UInt32 dataID)
|
|||
bool
|
||||
MSWindowsEventQueueBuffer::isEmpty() const
|
||||
{
|
||||
// don't use QS_POINTER, QS_TOUCH, or any meta-flags that include them (like QS_ALLINPUT)
|
||||
// because they can cause GetQueueStatus() to always return 0 and we miss events
|
||||
return (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) == 0);
|
||||
return (HIWORD(GetQueueStatus(m_os_supported_message_types)) == 0);
|
||||
}
|
||||
|
||||
EventQueueTimer*
|
||||
|
|
|
@ -47,4 +47,5 @@ private:
|
|||
MSG m_event;
|
||||
UINT m_daemonQuit;
|
||||
IEventQueue* m_events;
|
||||
UINT m_os_supported_message_types;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue