diff mbox series

[v3,1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU

Message ID 20190225102433.22401-2-peter.maydell@linaro.org
State Accepted
Headers show
Series ui/cocoa: Use OSX's main loop | expand

Commit Message

Peter Maydell Feb. 25, 2019, 10:24 a.m. UTC
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.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Roman Bolshakov <r.bolshakv@yadro.com>

Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>

Message-id: 20190214102816.3393-2-peter.maydell@linaro.org
---
Changes since v2: add with_iothread_lock wrap to the
qmp_stop()/qmp_cont() calls
---
 ui/cocoa.m | 91 ++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 65 insertions(+), 26 deletions(-)

-- 
2.17.2 (Apple Git-113)

Comments

G 3 Feb. 28, 2019, 9:53 p.m. UTC | #1
On Mon, Feb 25, 2019 at 5:24 AM Peter Maydell <peter.maydell@linaro.org>
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.

>

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> Reviewed-by: Roman Bolshakov <r.bolshakv@yadro.com>

> Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>

> Message-id: 20190214102816.3393-2-peter.maydell@linaro.org

> ---

> Changes since v2: add with_iothread_lock wrap to the

> qmp_stop()/qmp_cont() calls

> ---

>  ui/cocoa.m | 91 ++++++++++++++++++++++++++++++++++++++----------------

>  1 file changed, 65 insertions(+), 26 deletions(-)

>

> diff --git a/ui/cocoa.m b/ui/cocoa.m

> index e2567d6946..f1171c4865 100644

> --- a/ui/cocoa.m

> +++ b/ui/cocoa.m

> @@ -129,6 +129,21 @@

>  NSTextField *pauseLabel;

>  NSArray * supportedImageFileTypes;

>

> +// Utility function to run specified code block with iothread lock held

> +typedef void (^CodeBlock)(void);

>


Please don't use blocks. It would lock Mac OS X users into having to use
CLang. GCC does not support this non-standard extension.

C function pointers and Objective-C's selectors could work in place of
blocks.

Thank you.
<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Feb 25, 2019 at 5:24 AM Peter Maydell &lt;<a href="mailto:peter.maydell@linaro.org">peter.maydell@linaro.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The Cocoa UI should run on the main thread; this is enforced<br>
in OSX Mojave. In order to be able to run on the main thread,<br>
we need to make sure we hold the iothread lock whenever we<br>
call into various QEMU UI midlayer functions.<br>
<br>
Signed-off-by: Peter Maydell &lt;<a href="mailto:peter.maydell@linaro.org" target="_blank">peter.maydell@linaro.org</a>&gt;<br>

Reviewed-by: Roman Bolshakov &lt;<a href="mailto:r.bolshakv@yadro.com" target="_blank">r.bolshakv@yadro.com</a>&gt;<br>

Tested-by: Roman Bolshakov &lt;<a href="mailto:r.bolshakov@yadro.com" target="_blank">r.bolshakov@yadro.com</a>&gt;<br>

Message-id: <a href="mailto:20190214102816.3393-2-peter.maydell@linaro.org" target="_blank">20190214102816.3393-2-peter.maydell@linaro.org</a><br>
---<br>
Changes since v2: add with_iothread_lock wrap to the<br>
qmp_stop()/qmp_cont() calls<br>
---<br>
 ui/cocoa.m | 91 ++++++++++++++++++++++++++++++++++++++----------------<br>
 1 file changed, 65 insertions(+), 26 deletions(-)<br>
<br>
diff --git a/ui/cocoa.m b/ui/cocoa.m<br>
index e2567d6946..f1171c4865 100644<br>
--- a/ui/cocoa.m<br>
+++ b/ui/cocoa.m<br>
@@ -129,6 +129,21 @@<br>
 NSTextField *pauseLabel;<br>
 NSArray * supportedImageFileTypes;<br>
<br>
+// Utility function to run specified code block with iothread lock held<br>
+typedef void (^CodeBlock)(void);<br></blockquote><div><br></div><div>Please don&#39;t use blocks. It would lock Mac OS X users into having to use CLang. GCC does not support this non-standard extension.<br></div><div><br></div><div>C function pointers and Objective-C&#39;s selectors could work in place of blocks.<br></div><div> </div><div>Thank you.<br></div></div></div>
Peter Maydell March 1, 2019, 9:47 a.m. UTC | #2
On Thu, 28 Feb 2019 at 21:53, G 3 <programmingkidx@gmail.com> wrote:
> On Mon, Feb 25, 2019 at 5:24 AM Peter Maydell <peter.maydell@linaro.org> wrote:

>> +// Utility function to run specified code block with iothread lock held

>> +typedef void (^CodeBlock)(void);

>

>

> Please don't use blocks. It would lock Mac OS X users into having to use CLang. GCC does not support this non-standard extension.

>

> C function pointers and Objective-C's selectors could work in place of blocks.


Clang is the standard toolchain for this OS. We have such
little developer resource for OSX that I don't think we
can reasonably support two toolchains here. Besides,
we need blocks to use dispatch_async(), which is a much
simpler way to achieve what we're trying to do than
the 10.6 compatible approach.

Similarly, I am not prepared to continue to support 10.6
at this point:
 * 10.6's last release was over seven years ago
 * Apple stopped supporting it four years ago
 * there have been multiple OSX releases since then
 * attempting to maintain support for 10.6 would make the
   code less readable and maintainable for newer OSes
   we do care about
 * we do not have either the user base or the developer
   base on OSX to justify maintaining support for this
   ancient OS version
 * it would be out of line with our overall host OS
   support policy, which targets only the last LTS
   version or two of distros and OSes

I'm sorry if this is inconvenient to you personally, but
I don't think it makes any sense as a project to try to
support this any longer.

thanks
-- PMM
diff mbox series

Patch

diff --git a/ui/cocoa.m b/ui/cocoa.m
index e2567d6946..f1171c4865 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -129,6 +129,21 @@ 
 NSTextField *pauseLabel;
 NSArray * supportedImageFileTypes;
 
+// Utility function to run specified code block with iothread lock held
+typedef void (^CodeBlock)(void);
+
+static void with_iothread_lock(CodeBlock block)
+{
+    bool locked = qemu_mutex_iothread_locked();
+    if (!locked) {
+        qemu_mutex_lock_iothread();
+    }
+    block();
+    if (!locked) {
+        qemu_mutex_unlock_iothread();
+    }
+}
+
 // Mac to QKeyCode conversion
 const int mac_to_qkeycode_map[] = {
     [kVK_ANSI_A] = Q_KEY_CODE_A,
@@ -306,6 +321,7 @@  - (void) ungrabMouse;
 - (void) toggleFullScreen:(id)sender;
 - (void) handleMonitorInput:(NSEvent *)event;
 - (void) handleEvent:(NSEvent *)event;
+- (void) handleEventLocked:(NSEvent *)event;
 - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
 /* The state surrounding mouse grabbing is potentially confusing.
  * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated
@@ -649,8 +665,14 @@  - (void) handleMonitorInput:(NSEvent *)event
 
 - (void) handleEvent:(NSEvent *)event
 {
-    COCOA_DEBUG("QemuCocoaView: handleEvent\n");
+    with_iothread_lock(^{
+        [self handleEventLocked:event];
+    });
+}
 
+- (void) handleEventLocked:(NSEvent *)event
+{
+    COCOA_DEBUG("QemuCocoaView: handleEvent\n");
     int buttons = 0;
     int keycode = 0;
     bool mouse_event = false;
@@ -945,15 +967,18 @@  - (QEMUScreen) gscreen {return screen;}
  */
 - (void) raiseAllKeys
 {
-    int index;
     const int max_index = ARRAY_SIZE(modifiers_state);
 
-   for (index = 0; index < max_index; index++) {
-       if (modifiers_state[index]) {
-           modifiers_state[index] = 0;
-           qemu_input_event_send_key_qcode(dcl->con, index, false);
-       }
-   }
+    with_iothread_lock(^{
+        int index;
+
+        for (index = 0; index < max_index; index++) {
+            if (modifiers_state[index]) {
+                modifiers_state[index] = 0;
+                qemu_input_event_send_key_qcode(dcl->con, index, false);
+            }
+        }
+    });
 }
 @end
 
@@ -1178,7 +1203,9 @@  - (void)displayConsole:(id)sender
 /* Pause the guest */
 - (void)pauseQEMU:(id)sender
 {
-    qmp_stop(NULL);
+    with_iothread_lock(^{
+        qmp_stop(NULL);
+    });
     [sender setEnabled: NO];
     [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
     [self displayPause];
@@ -1187,7 +1214,9 @@  - (void)pauseQEMU:(id)sender
 /* Resume running the guest operating system */
 - (void)resumeQEMU:(id) sender
 {
-    qmp_cont(NULL);
+    with_iothread_lock(^{
+        qmp_cont(NULL);
+    });
     [sender setEnabled: NO];
     [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
     [self removePause];
@@ -1215,13 +1244,17 @@  - (void)removePause
 /* Restarts QEMU */
 - (void)restartQEMU:(id)sender
 {
-    qmp_system_reset(NULL);
+    with_iothread_lock(^{
+        qmp_system_reset(NULL);
+    });
 }
 
 /* Powers down QEMU */
 - (void)powerDownQEMU:(id)sender
 {
-    qmp_system_powerdown(NULL);
+    with_iothread_lock(^{
+        qmp_system_powerdown(NULL);
+    });
 }
 
 /* Ejects the media.
@@ -1237,9 +1270,11 @@  - (void)ejectDeviceMedia:(id)sender
         return;
     }
 
-    Error *err = NULL;
-    qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding],
-              false, NULL, false, false, &err);
+    __block Error *err = NULL;
+    with_iothread_lock(^{
+        qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding],
+                  false, NULL, false, false, &err);
+    });
     handleAnyDeviceErrors(err);
 }
 
@@ -1271,16 +1306,18 @@  - (void)changeDeviceMedia:(id)sender
             return;
         }
 
-        Error *err = NULL;
-        qmp_blockdev_change_medium(true,
-                                   [drive cStringUsingEncoding:
-                                          NSASCIIStringEncoding],
-                                   false, NULL,
-                                   [file cStringUsingEncoding:
-                                         NSASCIIStringEncoding],
-                                   true, "raw",
-                                   false, 0,
-                                   &err);
+        __block Error *err = NULL;
+        with_iothread_lock(^{
+            qmp_blockdev_change_medium(true,
+                                       [drive cStringUsingEncoding:
+                                                  NSASCIIStringEncoding],
+                                       false, NULL,
+                                       [file cStringUsingEncoding:
+                                                 NSASCIIStringEncoding],
+                                       true, "raw",
+                                       false, 0,
+                                       &err);
+        });
         handleAnyDeviceErrors(err);
     }
 }
@@ -1419,7 +1456,9 @@  - (void)adjustSpeed:(id)sender
     // get the throttle percentage
     throttle_pct = [sender tag];
 
-    cpu_throttle_set(throttle_pct);
+    with_iothread_lock(^{
+        cpu_throttle_set(throttle_pct);
+    });
     COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(), '%');
 }