[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 1/7] ui/cocoa: Ensure we have the iothread lo
From: |
Roman Bolshakov |
Subject: |
Re: [Qemu-devel] [PATCH v2 1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU |
Date: |
Fri, 22 Feb 2019 18:19:10 +0300 |
User-agent: |
NeoMutt/20180716 |
On Thu, Feb 14, 2019 at 10:28:10AM +0000, Peter Maydell wrote:
> The Cocoa UI should run on the main thread; this is enforced
> in OSX Mojave. In order to be able to run on the main thread,
> we need to make sure we hold the iothread lock whenever we
> call into various QEMU UI midlayer functions.
>
Hi Peter,
I wonder if qmp_stop and qmp_cont calls should be made in locked context
within pauseQEMU and resumeQEMU methods, respectively?
I also think it's better to clarify that the reason of the commit is not
Mojave enforcing usage of event loop in main thread but an improvement
of event processing in Cocoa UI, because Cocoa UI works on Mojave.
As of now qemu main loop and Cocoa events processing is done in the same
thread. And you can see from below that invocation of the qemu_main blocks
Cocoa event loop [NSApp run] in applicationDidFinishLaunching as qemu_main
doesn't quit.
Here's a backtrace that shows lockup of the primary Cocoa event loop:
(lldb) b cocoa_refresh
Breakpoint 1: where = qemu-system-x86_64`cocoa_refresh + 12 at cocoa.m:1634,
address = 0x0000000109a03a0c
(lldb) c
Process 46179 resuming
Process 46179 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000109a03a0c
qemu-system-x86_64`cocoa_refresh(dcl=0x00007f914eccefe0) at cocoa.m:1634
1631
1632 static void cocoa_refresh(DisplayChangeListener *dcl)
1633 {
-> 1634 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
1635
1636 COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
1637 graphic_hw_update(NULL);
Target 0: (qemu-system-x86_64) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000109a03a0c
qemu-system-x86_64`cocoa_refresh(dcl=0x00007f914eccefe0) at cocoa.m:1634
frame #1: 0x00000001099f6888
qemu-system-x86_64`dpy_refresh(s=0x00007f915074cbd0) at console.c:1622
frame #2: 0x00000001099f66dd
qemu-system-x86_64`gui_update(opaque=0x00007f915074cbd0) at console.c:205
frame #3: 0x0000000109ba6009
qemu-system-x86_64`timerlist_run_timers(timer_list=0x00007f915070c390) at
qemu-timer.c:574
frame #4: 0x0000000109ba60e0
qemu-system-x86_64`qemu_clock_run_timers(type=QEMU_CLOCK_REALTIME) at
qemu-timer.c:588
frame #5: 0x0000000109ba662a qemu-system-x86_64`qemu_clock_run_all_timers
at qemu-timer.c:708
frame #6: 0x0000000109ba6b8f
qemu-system-x86_64`main_loop_wait(nonblocking=0) at main-loop.c:521
frame #7: 0x0000000109760464 qemu-system-x86_64`main_loop at vl.c:1923
frame #8: 0x000000010975b624 qemu-system-x86_64`qemu_main(argc=5,
argv=0x00007ffee66a0688, envp=0x00007ffee66a06b8) at vl.c:4578
frame #9: 0x00000001099ffef9 qemu-system-x86_64`-[QemuCocoaAppController
startEmulationWithArgc:argv:](self=0x00007f914ee05e10,
_cmd="startEmulationWithArgc:argv:", argc=5, argv=0x00007ffee66a0688) at
cocoa.m:1135
frame #10: 0x00000001099ffd97 qemu-system-x86_64`-[QemuCocoaAppController
applicationDidFinishLaunching:](self=0x00007f914ee05e10,
_cmd="applicationDidFinishLaunching:",
note=@"NSApplicationDidFinishLaunchingNotification") at cocoa.m:1087
frame #11: 0x00007fff46bd5632
CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
frame #12: 0x00007fff46bd55ac
CoreFoundation`___CFXRegistrationPost_block_invoke + 63
frame #13: 0x00007fff46bd54cd CoreFoundation`_CFXRegistrationPost + 398
frame #14: 0x00007fff46bdd929
CoreFoundation`___CFXNotificationPost_block_invoke + 87
frame #15: 0x00007fff46b450ca CoreFoundation`-[_CFXNotificationRegistrar
find:object:observer:enumerator:] + 1633
frame #16: 0x00007fff46b4448d CoreFoundation`_CFXNotificationPost + 742
frame #17: 0x00007fff48ecca7b Foundation`-[NSNotificationCenter
postNotificationName:object:userInfo:] + 66
frame #18: 0x00007fff440c964a AppKit`-[NSApplication
_postDidFinishNotification] + 313
frame #19: 0x00007fff440c8f6e AppKit`-[NSApplication
_sendFinishLaunchingNotification] + 209
frame #20: 0x00007fff440c68c8 AppKit`-[NSApplication(NSAppleEventHandling)
_handleAEOpenEvent:] + 552
frame #21: 0x00007fff440c6517 AppKit`-[NSApplication(NSAppleEventHandling)
_handleCoreEvent:withReplyEvent:] + 690
frame #22: 0x00007fff48f17144 Foundation`-[NSAppleEventManager
dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 287
frame #23: 0x00007fff48f16fc0 Foundation`_NSAppleEventManagerGenericHandler
+ 102
frame #24: 0x00007fff47dfcb93 AE`aeDispatchAppleEvent(AEDesc const*,
AEDesc*, unsigned int, unsigned char*) + 1855
frame #25: 0x00007fff47dfc3fd AE`dispatchEventAndSendReply(AEDesc const*,
AEDesc*) + 41
frame #26: 0x00007fff47dfc2d5 AE`aeProcessAppleEvent + 439
frame #27: 0x00007fff45e1110e HIToolbox`AEProcessAppleEvent + 55
frame #28: 0x00007fff440c2644 AppKit`_DPSNextEvent + 1734
frame #29: 0x00007fff440c1102 AppKit`-[NSApplication(NSEvent)
_nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
frame #30: 0x00007fff440bb165 AppKit`-[NSApplication run] + 699
frame #31: 0x0000000109a03041 qemu-system-x86_64`main(argc=5,
argv=0x00007ffee66a0688) at cocoa.m:1589
frame #32: 0x00007fff73dc2ed9 libdyld.dylib`start + 1
frame #33: 0x00007fff73dc2ed9 libdyld.dylib`start + 1
Each millisecond cocoa_refresh gets called by display handler. The function
extracts all available events from the cocoa event queue and dispatches them to
handleEvent:
event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:distantPast
inMode: NSDefaultRunLoopMode dequeue:YES];
if (event != nil) {
[cocoaView handleEvent:event];
}
handleEvent enqueues keyboard and mouse events into ps2 queue and the
other events are enqueued to Cocoa event queue. I'm curious what happens
to the events that are enqueued with:
[NSApp sendEvent:event];
Perhaps the events are enqueued in handleEvent over and over and never
get out of the event queue. And there could be a chance of the event
queue overrun.
--
Thanks,
Roman
- Re: [Qemu-devel] [PATCH v2 5/7] ui/cocoa: Don't call NSApp sendEvent directly from handleEvent, (continued)
Re: [Qemu-devel] [PATCH v2 5/7] ui/cocoa: Don't call NSApp sendEvent directly from handleEvent, Roman Bolshakov, 2019/02/22
[Qemu-devel] [PATCH v2 4/7] ui/cocoa: Move console/device menu creation code up in file, Peter Maydell, 2019/02/14
[Qemu-devel] [PATCH v2 2/7] ui/cocoa: Use the pixman image directly in switchSurface, Peter Maydell, 2019/02/14
[Qemu-devel] [PATCH v2 1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU, Peter Maydell, 2019/02/14
- Re: [Qemu-devel] [PATCH v2 1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU,
Roman Bolshakov <=
[Qemu-devel] [PATCH v2 6/7] ui/cocoa: Subclass NSApplication so we can implement sendEvent, Peter Maydell, 2019/02/14
[Qemu-devel] [PATCH v2 7/7] ui/cocoa: Perform UI operations only on the main thread, Peter Maydell, 2019/02/14