* [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools
@ 2022-02-24 10:13 Peter Maydell
2022-02-24 10:13 ` [PATCH v2 1/2] ui/cocoa.m: Fix updateUIInfo threading issues Peter Maydell
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Peter Maydell @ 2022-02-24 10:13 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Akihiko Odaki
This patchset was originally provoked by Akihiko Odaki noting
that we have some unnecessary creation and deletion of autorelease
pools in the Cocoa UI code. Patch 2 deletes them; but to get there
we need to do a bit of cleanup of the updateUIInfo support,
which wasn't considering threads.
Tested only very lightly.
v1->v2 changes:
* name method updateUIInfoLocked, to match existing handleEventLocked
* don't call updateUIInfo in cocoa_display_init() -- this happens
indirectly as a result of register_displaychangelistener()
thanks
-- PMM
Peter Maydell (2):
ui/cocoa.m: Fix updateUIInfo threading issues
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
ui/cocoa.m | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] ui/cocoa.m: Fix updateUIInfo threading issues
2022-02-24 10:13 [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Peter Maydell
@ 2022-02-24 10:13 ` Peter Maydell
2022-02-24 10:13 ` [PATCH v2 2/2] ui/cocoa.m: Remove unnecessary NSAutoreleasePools Peter Maydell
2022-02-24 11:46 ` [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Akihiko Odaki
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2022-02-24 10:13 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Akihiko Odaki
The updateUIInfo method makes Cocoa API calls. It also calls back
into QEMU functions like dpy_set_ui_info(). To do this safely, we
need to follow two rules:
* Cocoa API calls are made on the Cocoa UI thread
* When calling back into QEMU we must hold the iothread lock
Fix the places where we got this wrong, by taking the iothread lock
while executing updateUIInfo, and moving the call in cocoa_switch()
inside the dispatch_async block.
Some of the Cocoa UI methods which call updateUIInfo are invoked as
part of the initial application startup, while we're still doing the
little cross-thread dance described in the comment just above
call_qemu_main(). This meant they were calling back into the QEMU UI
layer before we'd actually finished initializing our display and
registered the DisplayChangeListener, which isn't really valid. Once
updateUIInfo takes the iothread lock, we no longer get away with
this, because during this startup phase the iothread lock is held by
the QEMU main-loop thread which is waiting for us to finish our
display initialization. So we must suppress updateUIInfo until
applicationDidFinishLaunching allows the QEMU main-loop thread to
continue.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
v1->v2:
* name method updateUIInfoLocked, to match existing handleEventLocked
* don't call updateUIInfo in cocoa_display_init() -- this happens
indirectly as a result of register_displaychangelistener()
---
ui/cocoa.m | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index a8f1cdaf926..5ed1495552a 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -522,8 +522,9 @@ QemuCocoaView *cocoaView;
}
}
-- (void) updateUIInfo
+- (void) updateUIInfoLocked
{
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
NSSize frameSize;
QemuUIInfo info;
@@ -554,6 +555,25 @@ QemuCocoaView *cocoaView;
dpy_set_ui_info(dcl.con, &info, TRUE);
}
+- (void) updateUIInfo
+{
+ if (!allow_events) {
+ /*
+ * Don't try to tell QEMU about UI information in the application
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
+ * layer, and also trying to take the iothread lock would deadlock.
+ * When cocoa_display_init() does register the dcl, the UI layer
+ * will call cocoa_switch(), which will call updateUIInfo, so
+ * we don't lose any information here.
+ */
+ return;
+ }
+
+ with_iothread_lock(^{
+ [self updateUIInfoLocked];
+ });
+}
+
- (void)viewDidMoveToWindow
{
[self updateUIInfo];
@@ -1985,8 +2005,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
- [cocoaView updateUIInfo];
-
// The DisplaySurface will be freed as soon as this callback returns.
// We take a reference to the underlying pixman image here so it does
// not disappear from under our feet; the switchSurface method will
@@ -1994,6 +2012,7 @@ static void cocoa_switch(DisplayChangeListener *dcl,
pixman_image_ref(image);
dispatch_async(dispatch_get_main_queue(), ^{
+ [cocoaView updateUIInfo];
[cocoaView switchSurface:image];
});
[pool release];
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] ui/cocoa.m: Remove unnecessary NSAutoreleasePools
2022-02-24 10:13 [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Peter Maydell
2022-02-24 10:13 ` [PATCH v2 1/2] ui/cocoa.m: Fix updateUIInfo threading issues Peter Maydell
@ 2022-02-24 10:13 ` Peter Maydell
2022-02-24 11:46 ` [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Akihiko Odaki
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2022-02-24 10:13 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Akihiko Odaki
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
deal with complaints from macOS when we made calls into Cocoa from
threads that didn't have automatically created autorelease pools.
Later on, macOS got stricter about forbidding cross-thread Cocoa
calls, and in commit 5588840ff77800e839d8 we restructured the code to
avoid them. This left the autorelease pool creation in several
functions without any purpose; delete it.
We still need the pool in cocoa_refresh() for the clipboard related
code which is called directly there.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
ui/cocoa.m | 6 ------
1 file changed, 6 deletions(-)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5ed1495552a..b6e70e9134d 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -1976,8 +1976,6 @@ int main (int argc, char **argv) {
static void cocoa_update(DisplayChangeListener *dcl,
int x, int y, int w, int h)
{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
dispatch_async(dispatch_get_main_queue(), ^{
@@ -1993,14 +1991,11 @@ static void cocoa_update(DisplayChangeListener *dcl,
}
[cocoaView setNeedsDisplayInRect:rect];
});
-
- [pool release];
}
static void cocoa_switch(DisplayChangeListener *dcl,
DisplaySurface *surface)
{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
pixman_image_t *image = surface->image;
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
@@ -2015,7 +2010,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
[cocoaView updateUIInfo];
[cocoaView switchSurface:image];
});
- [pool release];
}
static void cocoa_refresh(DisplayChangeListener *dcl)
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools
2022-02-24 10:13 [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Peter Maydell
2022-02-24 10:13 ` [PATCH v2 1/2] ui/cocoa.m: Fix updateUIInfo threading issues Peter Maydell
2022-02-24 10:13 ` [PATCH v2 2/2] ui/cocoa.m: Remove unnecessary NSAutoreleasePools Peter Maydell
@ 2022-02-24 11:46 ` Akihiko Odaki
2 siblings, 0 replies; 4+ messages in thread
From: Akihiko Odaki @ 2022-02-24 11:46 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Gerd Hoffmann
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
On 2022/02/24 19:13, Peter Maydell wrote:
> This patchset was originally provoked by Akihiko Odaki noting
> that we have some unnecessary creation and deletion of autorelease
> pools in the Cocoa UI code. Patch 2 deletes them; but to get there
> we need to do a bit of cleanup of the updateUIInfo support,
> which wasn't considering threads.
>
> Tested only very lightly.
>
> v1->v2 changes:
> * name method updateUIInfoLocked, to match existing handleEventLocked
> * don't call updateUIInfo in cocoa_display_init() -- this happens
> indirectly as a result of register_displaychangelistener()
>
> thanks
> -- PMM
>
> Peter Maydell (2):
> ui/cocoa.m: Fix updateUIInfo threading issues
> ui/cocoa.m: Remove unnecessary NSAutoreleasePools
>
> ui/cocoa.m | 31 ++++++++++++++++++++++---------
> 1 file changed, 22 insertions(+), 9 deletions(-)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-24 11:48 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-24 10:13 [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Peter Maydell
2022-02-24 10:13 ` [PATCH v2 1/2] ui/cocoa.m: Fix updateUIInfo threading issues Peter Maydell
2022-02-24 10:13 ` [PATCH v2 2/2] ui/cocoa.m: Remove unnecessary NSAutoreleasePools Peter Maydell
2022-02-24 11:46 ` [PATCH v2 0/2] ui/cocoa: updateUIInfo threading, autorelease pools Akihiko Odaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).