Bug 362037 - [OS X] frequent "beachballing"
Summary: [OS X] frequent "beachballing"
Status: RESOLVED DUPLICATE of bug 372040
Alias: None
Product: kdevelop
Classification: Applications
Component: Language Support: CPP (old) (show other bugs)
Version: git master
Platform: Compiled Sources macOS
: NOR normal
Target Milestone: 5.0.3
Assignee: kdevelop-bugs-null
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-21 13:16 UTC by RJVB
Modified: 2017-01-16 18:10 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
simple patch to prevent beachballing (695 bytes, patch)
2016-11-09 16:25 UTC, RJVB
Details

Note You need to log in before you can comment on or make changes to this bug.
Description RJVB 2016-04-21 13:16:24 UTC
This is the bug report requested a while back when I asked about the frequent "beachballing" on kdevelop-devel.

OS X presents a "beachball" cursor when an application hasn't processed the event queue for a while, as an indication that that application doesn't respond to user input. This can be an indication of performing a lengthy operation on the main thread which doesn't call any function that processes the event queue.

Reproducible: Always

Steps to Reproduce:
1. Open a large/ish project in KDevelop. The latest example I noticed this with is KDELibs4Support . I need to add the path to the Qt5 header files in the language settings; YMMV.
2. Open a source file and start editing code, e.g. kuniqueapplication.cpp ; I wanted to query an environment variable after setting the multiple instances variable in KUniqueApplication::start() (using qgetenv).
3 A popup list with functions matching "qset" pops up; I selected (hit enter on) the 1st entry, qsetenv().

Actual Results:  
The application spent significant time doing all kinds of things except processing user input => beachball.
I was running in lldb, so could generate the stacktrace below.

Expected Results:  
No delays; the selected function should be entered within milliseconds and that should be the end of it.

Stacktrace below.

This situation happens very often, often enough to make using KDevelop5 with bigger projects quite annoying. There are also times where it's harder to say if there's substantial beachballing but where reactivity is almost equally affected by interminable lists of output being printed by the parser.

(lldb) bt
* thread #1: tid = 0x10a44b1, 0x00007fff896600aa libsystem_kernel.dylib`__getattrlist + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff896600aa libsystem_kernel.dylib`__getattrlist + 10
    frame #1: 0x00007fff82f23da7 CoreServicesInternal`corePropertyProviderPrepareValues(__CFURL const*, __FileCache*, __CFString const* const*, void const**, long, void const*, __CFError**) + 484
    frame #2: 0x00007fff82f19fbb CoreServicesInternal`prepareValuesForBitmap(__CFURL const*, __FileCache*, _FilePropertyBitmap*, __CFError**) + 227
    frame #3: 0x00007fff82f17ca7 CoreServicesInternal`_FSURLCopyResourcePropertyForKeyInternal(__CFURL const*, __CFString const*, void*, void*, __CFError**, unsigned char) + 213
    frame #4: 0x00007fff82f17bcd CoreServicesInternal`_FSURLCopyResourcePropertyForKey + 15
    frame #5: 0x00007fff8345b2bb CoreFoundation`CFURLCopyResourcePropertyForKey + 123
    frame #6: 0x00000001035aa92c QtCore`hasResourcePropertyFlag(data=<unavailable>, entry=<unavailable>, key=<unavailable>) + 172 at qfilesystemengine_unix.cpp:80
    frame #7: 0x00000001035a8ee9 QtCore`QFileSystemEngine::fillMetaData(entry=0x000000012a866f58, data=0x000000012a866f70, what=<unavailable>) + 649 at qfilesystemengine_unix.cpp:523
    frame #8: 0x000000010354c731 QtCore`QFileInfo::isHidden(this=<unavailable>) const + 81 at qfileinfo.cpp:967
    frame #9: 0x00000001035446c3 QtCore`QDirIteratorPrivate::matchesFilters(this=0x000000011f0d2890, fileName=<unavailable>, fi=0x00007fff5fbfb620) const + 387 at qdiriterator.cpp:352
    frame #10: 0x0000000103543f75 QtCore`QDirIteratorPrivate::advance(this=0x000000011f0d2890) + 1045 at qdiriterator.cpp:249
    frame #11: 0x00000001035434e1 QtCore`QDirIteratorPrivate::QDirIteratorPrivate(this=<unavailable>, entry=<unavailable>, nameFilters=<unavailable>, resolveEngine=<unavailable>, filters=<unavailable>, flags=<unavailable>) + 1137 at qdiriterator.cpp:169
    frame #12: 0x0000000103544e26 QtCore`QDirIterator::QDirIterator(this=0x00007fff5fbfb868, path=<unavailable>, nameFilters=<unavailable>, filters=<unavailable>, flags=<unavailable>) + 86 at qdiriterator.cpp:459
    frame #13: 0x000000010353a03c QtCore`QDir::entryList(this=<unavailable>, nameFilters=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 396 at qdir.cpp:1327
    frame #14: 0x0000000103539e9c QtCore`QDir::entryList(this=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 28 at qdir.cpp:1269
    frame #15: 0x000000011ffbbb1d libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 1581
    frame #16: 0x000000011ffbbc34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 1860
    frame #17: 0x000000011ffbbc34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 1860
    frame #18: 0x000000011ffb8231 libKDevClangPrivate.25.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) + 13025
    frame #19: 0x000000011ffb4db5 libKDevClangPrivate.25.dylib`UnknownDeclarationProblem::solutionAssistant() const + 181
    frame #20: 0x0000000103dd6957 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::checkAssistantForProblems(this=<unavailable>, top=<unavailable>) + 695 at staticassistantsmanager.cpp:296
    frame #21: 0x0000000103dd6681 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::updateReady(this=0x000000011b88cca0, url=<unavailable>, topContext=0x00000001305982c0) + 129 at staticassistantsmanager.cpp:257
    frame #22: 0x0000000103640383 QtCore`QObject::event(this=<unavailable>, e=<unavailable>) + 659 at qobject.cpp:1256
    frame #23: 0x00000001024c2f66 QtWidgets`QApplicationPrivate::notify_helper(this=<unavailable>, receiver=0x000000010b704db0, e=0x000000011dd7a250) + 294 at qapplication.cpp:3714
    frame #24: 0x00000001024c6225 QtWidgets`QApplication::notify(this=<unavailable>, receiver=<unavailable>, e=<unavailable>) + 7877 at qapplication.cpp:3677
    frame #25: 0x0000000103613b07 QtCore`QCoreApplication::notifyInternal2(receiver=0x000000010b704db0, event=0x000000011dd7a250) + 167 at qcoreapplication.cpp:1020
    frame #26: 0x0000000103614706 QtCore`QCoreApplicationPrivate::sendPostedEvents(receiver=0x0000000000000000, event_type=0, data=0x000000010c000e30) + 566 at qcoreapplication.h:227
    frame #27: 0x000000010cca80ce libqcocoa.dylib`QCocoaEventDispatcherPrivate::processPostedEvents(this=0x000000010b79dab0) + 190 at qcocoaeventdispatcher.mm:883
    frame #28: 0x000000010cca89b1 libqcocoa.dylib`QCocoaEventDispatcherPrivate::postedEventsSourceCallback(info=0x000000010b79dab0) + 33 at qcocoaeventdispatcher.mm:920
    frame #29: 0x00007fff8347e5b1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #30: 0x00007fff8346fc62 CoreFoundation`__CFRunLoopDoSources0 + 242
    frame #31: 0x00007fff8346f3ef CoreFoundation`__CFRunLoopRun + 831
    frame #32: 0x00007fff8346ee75 CoreFoundation`CFRunLoopRunSpecific + 309
    frame #33: 0x00007fff891d1a0d HIToolbox`RunCurrentEventLoopInMode + 226
    frame #34: 0x00007fff891d17b7 HIToolbox`ReceiveNextEventCommon + 479
    frame #35: 0x00007fff891d15bc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 65
    frame #36: 0x00007fff8969e24e AppKit`_DPSNextEvent + 1434
    frame #37: 0x00007fff8969d89b AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
    frame #38: 0x00007fff8969199c AppKit`-[NSApplication run] + 553
    frame #39: 0x000000010cca782d libqcocoa.dylib`QCocoaEventDispatcher::processEvents(this=0x000000010b79c0b0, flags=<unavailable>) + 2189 at qcocoaeventdispatcher.mm:416
    frame #40: 0x000000010360ff01 QtCore`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) [inlined] QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 401 at qeventloop.cpp:128
    frame #41: 0x000000010360fee4 QtCore`QEventLoop::exec(this=0x00007fff5fbfe0a0, flags=<unavailable>) + 372 at qeventloop.cpp:204
    frame #42: 0x0000000103614195 QtCore`QCoreApplication::exec() + 325 at qcoreapplication.cpp:1290
    frame #43: 0x000000010001a6cc kdevelop.bin`main(argc=<unavailable>, argv=0x0000000117ceae90) + 54620 at main.cpp:793
    frame #44: 0x00007fff8ad2e5fd libdyld.dylib`start + 1
    frame #45: 0x00007fff8ad2e5fd libdyld.dylib`start + 1
(lldb)
Comment 1 RJVB 2016-04-21 13:19:51 UTC
This backtrace snippet has line numbers:

    frame #7: 0x000000010353a03c QtCore`QDir::entryList(this=<unavailable>, nameFilters=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 396 at qdir.cpp:1327
    frame #8: 0x0000000118d22813 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 419
    frame #9: 0x0000000118d22d34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 1732
    frame #10: 0x0000000118d22d34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(QString const&, QDir const&, int) + 1732
    frame #11: 0x0000000118d1e664 libKDevClangPrivate.25.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) + 8980
    frame #12: 0x0000000118d1c1e5 libKDevClangPrivate.25.dylib`UnknownDeclarationProblem::solutionAssistant() const + 181
    frame #13: 0x0000000103dd6957 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::checkAssistantForProblems(this=<unavailable>, top=<unavailable>) + 695 at staticassistantsmanager.cpp:296
    frame #14: 0x0000000103dd6681 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::updateReady(this=0x000000011aabe8f0, url=<unavailable>, topContext=0x000000012107a840) + 129 at staticassistantsmanager.cpp:257
Comment 2 RJVB 2016-04-21 13:26:38 UTC
Oops:

    frame #7: 0x0000000103539e9c QtCore`QDir::entryList(this=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 28 at qdir.cpp:1269
    frame #8: 0x000000011ec8bc1d libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(identifier=<unavailable>, dir=<unavailable>, maxDepth=<unavailable>) + 1453 at unknowndeclarationproblem.cpp:103
    frame #9: 0x000000011ec8bd34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(identifier=<unavailable>, dir=<unavailable>, maxDepth=<unavailable>) + 1732 at unknowndeclarationproblem.cpp:104
    frame #10: 0x000000011ec8bd34 libKDevClangPrivate.25.dylib`(anonymous namespace)::scanIncludePaths(identifier=<unavailable>, dir=<unavailable>, maxDepth=<unavailable>) + 1732 at unknowndeclarationproblem.cpp:104
    frame #11: 0x000000011ec87664 libKDevClangPrivate.25.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) [inlined] (anonymous namespace)::scanIncludePaths(identifier=0x0000000119a3b8e8) + 119 at unknowndeclarationproblem.cpp:117
    frame #12: 0x000000011ec875ed libKDevClangPrivate.25.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) [inlined] (anonymous namespace)::includeFiles(file=<unavailable>, range=<unavailable>) + 5079 at unknowndeclarationproblem.cpp:416
    frame #13: 0x000000011ec86216 libKDevClangPrivate.25.dylib`(anonymous namespace)::fixUnknownDeclaration(identifier=0x0000000119a3b8e8, file=<unavailable>, docrange=<unavailable>) + 3782 at unknowndeclarationproblem.cpp:452
    frame #14: 0x000000011ec851e5 libKDevClangPrivate.25.dylib`UnknownDeclarationProblem::solutionAssistant(this=0x0000000119a3b8a0) const + 181 at unknowndeclarationproblem.cpp:506
    frame #15: 0x0000000103dd6957 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::checkAssistantForProblems(this=<unavailable>, top=<unavailable>) + 695 at staticassistantsmanager.cpp:296
    frame #16: 0x0000000103dd6d98 libKDevPlatformLanguage.10.dylib`KDevelop::StaticAssistantsManager::Private::timeout(this=0x0000000112b8cc50) + 136 at staticassistantsmanager.cpp:316
Comment 3 RJVB 2016-11-09 15:58:30 UTC
This is still a frequent obstacle that really degrades the user experience. Having to wait up to several seconds every time your (mouse) cursor enters code that is not correct (or no longer correct, as in when you change a variable name) gets old really fast. Similar things also happen when entering new code.

I've always been surprised that I noticed this only on Mac and not on Linux but maybe that's simply because my Linux desktops don't have a beachball cursor equivalent, and since they're so much slower than my Mac I do less development with them anyway. Earlier today I noticed a similar behaviour editing gitmessagehighlighter.cpp for a RR I have open.

Replacing `format.setFontItalic(true)` with something else, I left it as `format.set(true)` while making a point edit elsewhere. Even hovering the mouse pointer over that undefined method blocked the UI.

Reproducing the situation on a Mac I obtained the backtrace below. Apparently this particular and relatively costly parsing operation is performed on the main thread, blocking event handling (which is exactly what triggers the beachball cursor on OS X).

Ideally this operation would be performed on a thread of its own, while the main thread continues to process events and aborts the operation in reaction to certain events (text input or focus movement that changes the expression being parsed, for instance).


  * frame #0: 0x00007fff8ca0ddfa libsystem_kernel.dylib`stat$INODE64 + 10
    frame #1: 0x000000010975989f QtCore`QFileSystemEngine::fillMetaData(entry=0x00007f8549681788, data=0x00007f85496817a0, what=<unavailable>) + 271 at qfilesystemengine_unix.cpp:470 [opt]
    frame #2: 0x00000001096fd481 QtCore`QFileInfo::isHidden(this=<unavailable>) const + 81 at qfileinfo.cpp:967 [opt]
    frame #3: 0x00000001096f5413 QtCore`QDirIteratorPrivate::matchesFilters(this=0x00007f854b70ce50, fileName=<unavailable>, fi=0x00007fff59697f40) const + 387 at qdiriterator.cpp:352 [opt]
    frame #4: 0x00000001096f4cc5 QtCore`QDirIteratorPrivate::advance(this=0x00007f854b70ce50) + 1045 at qdiriterator.cpp:249 [opt]
    frame #5: 0x00000001096f5cf5 QtCore`QDirIterator::next(this=0x00007fff59698068) + 21 at qdiriterator.cpp:481 [opt]
    frame #6: 0x00000001096eadf3 QtCore`QDir::entryList(this=<unavailable>, nameFilters=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 499 at qdir.cpp:1325 [opt]
    frame #7: 0x00000001096eabec QtCore`QDir::entryList(this=<unavailable>, filters=<unavailable>, sort=<unavailable>) const + 28 at qdir.cpp:1265 [opt]
    frame #8: 0x000000011fc9359a libKDevClangPrivate.26.dylib`(anonymous namespace)::scanIncludePaths(identifier="set", dir=<unavailable>, maxDepth=<unavailable>) + 1722 at unknowndeclarationproblem.cpp:104 [opt]
    frame #9: 0x000000011fc93695 libKDevClangPrivate.26.dylib`(anonymous namespace)::scanIncludePaths(identifier="set", dir=<unavailable>, maxDepth=1) + 1973 at unknowndeclarationproblem.cpp:105 [opt]
    frame #10: 0x000000011fc93695 libKDevClangPrivate.26.dylib`(anonymous namespace)::scanIncludePaths(identifier="set", dir=<unavailable>, maxDepth=2) + 1973 at unknowndeclarationproblem.cpp:105 [opt]
    frame #11: 0x000000011fc8ee44 libKDevClangPrivate.26.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) + 121 at unknowndeclarationproblem.cpp:118 [opt]
    frame #12: 0x000000011fc8edcb libKDevClangPrivate.26.dylib`(anonymous namespace)::fixUnknownDeclaration(KDevelop::QualifiedIdentifier const&, KDevelop::Path const&, KDevelop::DocumentRange const&) [inlined] (anonymous namespace)::includeFiles(declarations=<unavailable>, file=("Volumes", "Debian", "Users", "bertin", "work", "src", "new", "KDE", "KF5", "kdevplatform-git-5", "plugins", "git", "gitmessagehighlighter.cpp")) + 4271 at unknowndeclarationproblem.cpp:390 [opt]
    frame #13: 0x000000011fc8dd1c libKDevClangPrivate.26.dylib`(anonymous namespace)::fixUnknownDeclaration(identifier=0x00007f854f7909c8, file=("Volumes", "Debian", "Users", "bertin", "work", "src", "new", "KDE", "KF5", "kdevplatform-git-5", "plugins", "git", "gitmessagehighlighter.cpp"), docrange=<unavailable>) + 5724 at unknowndeclarationproblem.cpp:466 [opt]
    frame #14: 0x000000011fc8c552 libKDevClangPrivate.26.dylib`UnknownDeclarationProblem::solutionAssistant(this=0x00007f854f790980) const + 178 at unknowndeclarationproblem.cpp:520 [opt]
    frame #15: 0x000000011fc90c12 libKDevClangPrivate.26.dylib`non-virtual thunk to UnknownDeclarationProblem::solutionAssistant(this=<unavailable>) const + 18 at unknowndeclarationproblem.cpp:517 [opt]
    frame #16: 0x000000010a080cb7 libKDevPlatformLanguage.10.dylib`KDevelop::ProblemNavigationContext::html(this=<unavailable>, shorten=<unavailable>) + 6551 at problemnavigationcontext.cpp:172 [opt]
    frame #17: 0x000000010a082fb6 libKDevPlatformLanguage.10.dylib`KDevelop::AbstractNavigationWidget::update(this=0x00007f856316dff0) + 54 at abstractnavigationwidget.cpp:148 [opt]
    frame #18: 0x000000010a082e90 libKDevPlatformLanguage.10.dylib`KDevelop::AbstractNavigationWidget::setContext(this=0x00007f856316dff0, context=<unavailable>, initBrows=<unavailable>) + 224 at abstractnavigationwidget.cpp:116 [opt]
    frame #19: 0x000000011eb6229c kdevcontextbrowser.so`ContextBrowserPlugin::navigationWidgetForPosition(this=0x00007f855be738e0, view=0x00007f855d4cbe00, position=<unavailable>) + 2828 at contextbrowser.cpp:539 [opt]
    frame #20: 0x000000011eb60dfa kdevcontextbrowser.so`ContextBrowserPlugin::showToolTip(this=0x00007f855be738e0, view=0x00007f855d4cbe00, position=<unavailable>) + 90 at contextbrowser.cpp:585 [opt]
    frame #21: 0x000000011eb60d84 kdevcontextbrowser.so`ContextBrowserHintProvider::textHint(this=0x00007f855be73a58, view=<unavailable>, cursor=(39, 12)) + 324 at contextbrowser.cpp:407 [opt]
    frame #22: 0x0000000107282297 libKF5TextEditor.5.dylib`KateViewInternal::textHintTimeout(this=0x00007f855d4cc940) + 311 at kateviewinternal.cpp:3101 [opt]
    frame #23: 0x0000000107377f35 libKF5TextEditor.5.dylib`KateViewInternal::qt_static_metacall(_o=<unavailable>, _c=<unavailable>, _id=<unavailable>, _a=<unavailable>) + 885 at moc_kateviewinternal.cpp:200 [opt]
    frame #24: 0x00000001097f98a4 QtCore`QMetaObject::activate(sender="00:00:00", signalOffset=<unavailable>, local_signal_index=<unavailable>, argv=<unavailable>) + 3028 at qobject.cpp:3730 [opt]
    frame #25: 0x00000001097f1ba0 QtCore`QObject::event(this="00:00:00", e=<unavailable>) + 48 at qobject.cpp:1237 [opt]
    frame #26: 0x000000010866e1e6 QtWidgets`QApplicationPrivate::notify_helper(this=<unavailable>, receiver="00:00:00", e="00:00:00") + 294 at qapplication.cpp:3804 [opt]
    frame #27: 0x0000000108671726 QtWidgets`QApplication::notify(this=<unavailable>, receiver=<unavailable>, e=<unavailable>) + 8470 at qapplication.cpp:3767 [opt]
    frame #28: 0x00000001097c5587 QtCore`QCoreApplication::notifyInternal2(receiver="00:00:00", event="00:00:00") + 167 at qcoreapplication.cpp:1020 [opt]
    frame #29: 0x000000010981e7a1 QtCore`QTimerInfoList::activateTimers() [inlined] QCoreApplication::sendEvent(receiver=<unavailable>, event=0x0000000109a30150) + 1329 at qcoreapplication.h:225 [opt]
    frame #30: 0x000000010981e794 QtCore`QTimerInfoList::activateTimers(this="00:00:00") + 1316 at qtimerinfo_unix.cpp:637 [opt]
    frame #31: 0x0000000112ff8482 libqcocoa.dylib`QCocoaEventDispatcherPrivate::activateTimersSourceCallback(info=0x00007f85594606a0) + 18 at qcocoaeventdispatcher.mm:119 [opt]
    frame #32: 0x00007fff866c35b1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #33: 0x00007fff866b4c62 CoreFoundation`__CFRunLoopDoSources0 + 242
    frame #34: 0x00007fff866b43ef CoreFoundation`__CFRunLoopRun + 831
    frame #35: 0x00007fff866b3e75 CoreFoundation`CFRunLoopRunSpecific + 309
    frame #36: 0x00007fff8a9d7a0d HIToolbox`RunCurrentEventLoopInMode + 226
    frame #37: 0x00007fff8a9d77b7 HIToolbox`ReceiveNextEventCommon + 479
    frame #38: 0x00007fff8a9d75bc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 65
    frame #39: 0x00007fff8e86f24e AppKit`_DPSNextEvent + 1434
    frame #40: 0x00007fff8e86e89b AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
    frame #41: 0x00007fff8e86299c AppKit`-[NSApplication run] + 553
    frame #42: 0x0000000112ff908d libqcocoa.dylib`QCocoaEventDispatcher::processEvents(this=0x00007f8559463a30, flags=<unavailable>) + 2189 at qcocoaeventdispatcher.mm:416 [opt]
    frame #43: 0x00000001097c19a1 QtCore`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) [inlined] QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 401 at qeventloop.cpp:128 [opt]
    frame #44: 0x00000001097c1984 QtCore`QEventLoop::exec(this=0x00007fff5969ada0, flags=<unavailable>) + 372 at qeventloop.cpp:204 [opt]
    frame #45: 0x00000001097c5c15 QtCore`QCoreApplication::exec() + 325 at qcoreapplication.cpp:1290 [opt]
Comment 4 RJVB 2016-11-09 16:04:18 UTC
> Ideally this operation would be performed on a thread of its own, while the
> main thread continues to process events and aborts the operation in reaction
> to certain events (text input or focus movement that changes the expression
> being parsed, for instance).

Maybe it'd be easier to check for certain events at appropriate locations in the code which is taking time, and abort the operation within some timeout/grace period after such events?
Comment 5 RJVB 2016-11-09 16:25:42 UTC
Created attachment 102145 [details]
simple patch to prevent beachballing

It may be useful to add a processEvents() call in this function's foreach loop too. sendPostedEvents() may not even be required there.

static ProblemPointer findProblemUnderCursor(TopDUContext* topContext, KTextEditor::Cursor position)
{
  const auto top = ReferencedTopDUContext(topContext);
  foreach (auto problem, DUChainUtils::allProblemsForContext(top)) {
    if (problem->rangeInCurrentRevision().contains(position)) {
      return problem;
    }
  }

  return {};
}
Comment 6 Kevin Funk 2016-11-09 21:28:35 UTC
Agreed, we/I should look into this issue. I'm afraid your patch merely serves as a work-around though.
Comment 7 RJVB 2016-11-09 21:52:55 UTC
Yes, that's exactly what it is - but you can also provoke a nice fireworks display of context browser tooltips with it ;)

It might resemble more of a fix if it's possible to check after processing the events if an action was taken which should abort the ongoing operation. Not sure how you'd do that, but I'm not sure either if there's a truly better, different solution. From what I see, the expensive operation is launched as part of a tooltip display callback, meaning there isn't much else that callback can do when you offload the expensive content creation operation to a background thread. Unless you can create and show the tooltip from a background job?


I'd be happy to test if you have something that should work.
Comment 8 Kevin Funk 2017-01-16 18:10:40 UTC

*** This bug has been marked as a duplicate of bug 372040 ***