mirror of https://github.com/proxmox/mirror_qemu
ui/cocoa: Ensure we have the iothread lock when calling into QEMU
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.bolshakov@yadro.com> Tested-by: Roman Bolshakov <r.bolshakov@yadro.com> Message-id: 20190225102433.22401-2-peter.maydell@linaro.org Message-id: 20190214102816.3393-2-peter.maydell@linaro.orgmaster
parent
88687719c8
commit
31819e9509
91
ui/cocoa.m
91
ui/cocoa.m
|
@ -129,6 +129,21 @@ bool stretch_video;
|
||||||
NSTextField *pauseLabel;
|
NSTextField *pauseLabel;
|
||||||
NSArray * supportedImageFileTypes;
|
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
|
// Mac to QKeyCode conversion
|
||||||
const int mac_to_qkeycode_map[] = {
|
const int mac_to_qkeycode_map[] = {
|
||||||
[kVK_ANSI_A] = Q_KEY_CODE_A,
|
[kVK_ANSI_A] = Q_KEY_CODE_A,
|
||||||
|
@ -306,6 +321,7 @@ static void handleAnyDeviceErrors(Error * err)
|
||||||
- (void) toggleFullScreen:(id)sender;
|
- (void) toggleFullScreen:(id)sender;
|
||||||
- (void) handleMonitorInput:(NSEvent *)event;
|
- (void) handleMonitorInput:(NSEvent *)event;
|
||||||
- (void) handleEvent:(NSEvent *)event;
|
- (void) handleEvent:(NSEvent *)event;
|
||||||
|
- (void) handleEventLocked:(NSEvent *)event;
|
||||||
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
|
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
|
||||||
/* The state surrounding mouse grabbing is potentially confusing.
|
/* The state surrounding mouse grabbing is potentially confusing.
|
||||||
* isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated
|
* isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated
|
||||||
|
@ -649,8 +665,14 @@ QemuCocoaView *cocoaView;
|
||||||
|
|
||||||
- (void) handleEvent:(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 buttons = 0;
|
||||||
int keycode = 0;
|
int keycode = 0;
|
||||||
bool mouse_event = false;
|
bool mouse_event = false;
|
||||||
|
@ -945,15 +967,18 @@ QemuCocoaView *cocoaView;
|
||||||
*/
|
*/
|
||||||
- (void) raiseAllKeys
|
- (void) raiseAllKeys
|
||||||
{
|
{
|
||||||
int index;
|
|
||||||
const int max_index = ARRAY_SIZE(modifiers_state);
|
const int max_index = ARRAY_SIZE(modifiers_state);
|
||||||
|
|
||||||
for (index = 0; index < max_index; index++) {
|
with_iothread_lock(^{
|
||||||
if (modifiers_state[index]) {
|
int index;
|
||||||
modifiers_state[index] = 0;
|
|
||||||
qemu_input_event_send_key_qcode(dcl->con, index, false);
|
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
|
@end
|
||||||
|
|
||||||
|
@ -1178,7 +1203,9 @@ QemuCocoaView *cocoaView;
|
||||||
/* Pause the guest */
|
/* Pause the guest */
|
||||||
- (void)pauseQEMU:(id)sender
|
- (void)pauseQEMU:(id)sender
|
||||||
{
|
{
|
||||||
qmp_stop(NULL);
|
with_iothread_lock(^{
|
||||||
|
qmp_stop(NULL);
|
||||||
|
});
|
||||||
[sender setEnabled: NO];
|
[sender setEnabled: NO];
|
||||||
[[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
|
[[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
|
||||||
[self displayPause];
|
[self displayPause];
|
||||||
|
@ -1187,7 +1214,9 @@ QemuCocoaView *cocoaView;
|
||||||
/* Resume running the guest operating system */
|
/* Resume running the guest operating system */
|
||||||
- (void)resumeQEMU:(id) sender
|
- (void)resumeQEMU:(id) sender
|
||||||
{
|
{
|
||||||
qmp_cont(NULL);
|
with_iothread_lock(^{
|
||||||
|
qmp_cont(NULL);
|
||||||
|
});
|
||||||
[sender setEnabled: NO];
|
[sender setEnabled: NO];
|
||||||
[[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
|
[[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
|
||||||
[self removePause];
|
[self removePause];
|
||||||
|
@ -1215,13 +1244,17 @@ QemuCocoaView *cocoaView;
|
||||||
/* Restarts QEMU */
|
/* Restarts QEMU */
|
||||||
- (void)restartQEMU:(id)sender
|
- (void)restartQEMU:(id)sender
|
||||||
{
|
{
|
||||||
qmp_system_reset(NULL);
|
with_iothread_lock(^{
|
||||||
|
qmp_system_reset(NULL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Powers down QEMU */
|
/* Powers down QEMU */
|
||||||
- (void)powerDownQEMU:(id)sender
|
- (void)powerDownQEMU:(id)sender
|
||||||
{
|
{
|
||||||
qmp_system_powerdown(NULL);
|
with_iothread_lock(^{
|
||||||
|
qmp_system_powerdown(NULL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ejects the media.
|
/* Ejects the media.
|
||||||
|
@ -1237,9 +1270,11 @@ QemuCocoaView *cocoaView;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error *err = NULL;
|
__block Error *err = NULL;
|
||||||
qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding],
|
with_iothread_lock(^{
|
||||||
false, NULL, false, false, &err);
|
qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding],
|
||||||
|
false, NULL, false, false, &err);
|
||||||
|
});
|
||||||
handleAnyDeviceErrors(err);
|
handleAnyDeviceErrors(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1271,16 +1306,18 @@ QemuCocoaView *cocoaView;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error *err = NULL;
|
__block Error *err = NULL;
|
||||||
qmp_blockdev_change_medium(true,
|
with_iothread_lock(^{
|
||||||
[drive cStringUsingEncoding:
|
qmp_blockdev_change_medium(true,
|
||||||
NSASCIIStringEncoding],
|
[drive cStringUsingEncoding:
|
||||||
false, NULL,
|
NSASCIIStringEncoding],
|
||||||
[file cStringUsingEncoding:
|
false, NULL,
|
||||||
NSASCIIStringEncoding],
|
[file cStringUsingEncoding:
|
||||||
true, "raw",
|
NSASCIIStringEncoding],
|
||||||
false, 0,
|
true, "raw",
|
||||||
&err);
|
false, 0,
|
||||||
|
&err);
|
||||||
|
});
|
||||||
handleAnyDeviceErrors(err);
|
handleAnyDeviceErrors(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1419,7 +1456,9 @@ QemuCocoaView *cocoaView;
|
||||||
// get the throttle percentage
|
// get the throttle percentage
|
||||||
throttle_pct = [sender tag];
|
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(), '%');
|
COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(), '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue