From bf4dd877e9f1e4508f0031e61c7f40cd612be448 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 26 May 2015 22:47:11 +0200 Subject: osx: synchronize access to the input_ctx While all functions of input_ctx are inherently thread-safe, access to the _inputContext field itself is not. It could be unset any time by cocoa_set_input_context(). So even trivial input_ctx calls must be under a lock, so that the input_ctx can not be destroyed while the function call is "starting". (Even a function call in progress wouldn't be fine, because mp_input_uninit() requires the caller to "own" the object, i.e. no other threads can access it at this point.) --- osdep/macosx_events.m | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'osdep') diff --git a/osdep/macosx_events.m b/osdep/macosx_events.m index 6ae5e6d900..9c8d533ec0 100644 --- a/osdep/macosx_events.m +++ b/osdep/macosx_events.m @@ -40,7 +40,7 @@ @interface EventsResponder () { struct input_ctx *_inputContext; - NSCondition *_input_ready; + NSCondition *_input_lock; CFMachPortRef _mk_tap_port; #if HAVE_APPLE_REMOTE HIDRemote *_remote; @@ -223,54 +223,63 @@ void cocoa_set_input_context(struct input_ctx *input_context) { self = [super init]; if (self) { - _input_ready = [NSCondition new]; + _input_lock = [NSCondition new]; } return self; } - (void)waitForInputContext { - [_input_ready lock]; + [_input_lock lock]; while (!_inputContext) - [_input_ready wait]; - [_input_ready unlock]; + [_input_lock wait]; + [_input_lock unlock]; } - (void)setInputContext:(struct input_ctx *)ctx; { - [_input_ready lock]; + [_input_lock lock]; _inputContext = ctx; - [_input_ready signal]; - [_input_ready unlock]; + [_input_lock signal]; + [_input_lock unlock]; } - (void)wakeup { + [_input_lock lock]; mp_input_wakeup(_inputContext); + [_input_lock unlock]; } - (bool)queueCommand:(char *)cmd { - if (!_inputContext) - return false; - - mp_cmd_t *cmdt = mp_input_parse_cmd(_inputContext, bstr0(cmd), ""); - mp_input_queue_cmd(_inputContext, cmdt); - return true; + bool r = false; + [_input_lock lock]; + if (_inputContext) { + mp_cmd_t *cmdt = mp_input_parse_cmd(_inputContext, bstr0(cmd), ""); + mp_input_queue_cmd(_inputContext, cmdt); + r = true; + } + [_input_lock unlock]; + return r; } - (void)putKey:(int)keycode { + [_input_lock lock]; if (_inputContext) mp_input_put_key(_inputContext, keycode); + [_input_lock unlock]; } - (BOOL)useAltGr { + BOOL r = YES; + [_input_lock lock]; if (_inputContext) - return mp_input_use_alt_gr(_inputContext); - else - return YES; + r = mp_input_use_alt_gr(_inputContext); + [_input_lock unlock]; + return r; } - (void)startEventMonitor @@ -460,7 +469,10 @@ void cocoa_set_input_context(struct input_ctx *input_context) size_t bytes = [p lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1); }]; - mp_event_drop_files(_inputContext, num_files, files_utf8); + [_input_lock lock]; + if (_inputContext) + mp_event_drop_files(_inputContext, num_files, files_utf8); + [_input_lock unlock]; talloc_free(files_utf8); } -- cgit v1.2.3