Skip to content

Commit ddd0e20

Browse files
author
ShresthSamyak
committed
fix(macos): extract active wait logic to helper method to fix review comments
1 parent 459e096 commit ddd0e20

1 file changed

Lines changed: 48 additions & 40 deletions

File tree

mpv.py

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,52 @@ def shutdown_handler(event):
10451045
pass
10461046
return shutdown_handler.unregister_mpv_events
10471047

1048+
def _wait_for_future(self, result, timeout):
1049+
"""Wait for a future to complete. On macOS main thread, this actively pumps the CoreFoundation event loop."""
1050+
self.check_core_alive()
1051+
1052+
if sys.platform == 'darwin' and threading.current_thread() is threading.main_thread():
1053+
import time
1054+
import ctypes
1055+
import ctypes.util
1056+
1057+
global _core_foundation
1058+
global _cf_runloop_default_mode
1059+
try:
1060+
if _core_foundation is None or _cf_runloop_default_mode is None:
1061+
_core_foundation = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))
1062+
1063+
# CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled)
1064+
_core_foundation.CFRunLoopRunInMode.argtypes = [ctypes.c_void_p, ctypes.c_double, ctypes.c_bool]
1065+
_core_foundation.CFRunLoopRunInMode.restype = ctypes.c_int32
1066+
1067+
_cf_runloop_default_mode = ctypes.c_void_p.in_dll(_core_foundation, 'kCFRunLoopDefaultMode')
1068+
1069+
start_time = time.monotonic()
1070+
while not result.done():
1071+
remaining = 0
1072+
if timeout is not None:
1073+
remaining = timeout - (time.monotonic() - start_time)
1074+
if remaining <= 0:
1075+
break
1076+
1077+
# Pump events for up to 0.05 seconds, or remaining timeout if smaller
1078+
sleep_time = min(0.05, remaining)
1079+
else:
1080+
sleep_time = 0.05
1081+
1082+
_core_foundation.CFRunLoopRunInMode(_cf_runloop_default_mode, sleep_time, False)
1083+
self.check_core_alive()
1084+
except ShutdownError:
1085+
raise
1086+
except Exception as e:
1087+
# Fallback if CoreFoundation loading fails
1088+
warn(f"Failed to load CoreFoundation for mpv macOS event loop: {e}", RuntimeWarning)
1089+
1090+
return result.result(0 if timeout is not None else None)
1091+
else:
1092+
return result.result(timeout)
1093+
10481094
@contextmanager
10491095
def prepare_and_wait_for_property(self, name, cond=lambda val: val, level_sensitive=True, timeout=None, catch_errors=True):
10501096
"""Context manager that waits until ``cond`` evaluates to a truthy value on the named property. See
@@ -1084,8 +1130,7 @@ def observer(name, val):
10841130
result.set_result(rv)
10851131
return
10861132

1087-
self.check_core_alive()
1088-
result.result(timeout)
1133+
self._wait_for_future(result, timeout)
10891134

10901135
except InvalidStateError:
10911136
pass
@@ -1144,44 +1189,7 @@ def target_handler(evt):
11441189

11451190
yield result
11461191

1147-
self.check_core_alive()
1148-
1149-
self.check_core_alive()
1150-
1151-
if sys.platform == 'darwin' and threading.current_thread() is threading.main_thread():
1152-
import time
1153-
import ctypes
1154-
import ctypes.util
1155-
1156-
global _core_foundation
1157-
global _cf_runloop_default_mode
1158-
try:
1159-
if _core_foundation is None:
1160-
_core_foundation = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))
1161-
1162-
# CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled)
1163-
_core_foundation.CFRunLoopRunInMode.argtypes = [ctypes.c_void_p, ctypes.c_double, ctypes.c_bool]
1164-
_core_foundation.CFRunLoopRunInMode.restype = ctypes.c_int32
1165-
1166-
_cf_runloop_default_mode = ctypes.c_void_p.in_dll(_core_foundation, 'kCFRunLoopDefaultMode')
1167-
1168-
start_time = time.monotonic()
1169-
while not result.done():
1170-
remaining = 0
1171-
if timeout is not None:
1172-
remaining = timeout - (time.monotonic() - start_time)
1173-
if remaining <= 0:
1174-
break
1175-
1176-
# Pump events for up to 0.05 seconds, or remaining timeout if smaller
1177-
sleep_time = min(0.05, remaining) if timeout is not None else 0.05
1178-
_core_foundation.CFRunLoopRunInMode(_cf_runloop_default_mode, sleep_time, False)
1179-
self.check_core_alive()
1180-
except Exception as e:
1181-
# Fallback if CoreFoundation loading fails
1182-
warn(f"Failed to load CoreFoundation for mpv macOS event loop: {e}", RuntimeWarning)
1183-
1184-
result.result(timeout)
1192+
self._wait_for_future(result, timeout)
11851193

11861194
finally:
11871195
err_unregister()

0 commit comments

Comments
 (0)