From f00ac071f337e373a2f13375048d53cc9a971f68 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Mon, 24 Aug 2026 09:34:14 -0400 Subject: [PATCH] Eliminate polling latency in BinaryView search generators. --- python/binaryview.py | 70 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/python/binaryview.py b/python/binaryview.py index c7dd9af48..b5ded0af4 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -9976,6 +9976,8 @@ def find_next_constant( return result.value class QueueGenerator: + _done = object() + def __init__(self, t: threading.Thread, results: queue.Queue): self.thread = t self.results = results @@ -9985,15 +9987,10 @@ def __iter__(self): return self def __next__(self): - while True: - try: - return self.results.get(timeout=0.1) - except queue.Empty: - if not self.thread.is_alive(): - try: - return self.results.get_nowait() - except queue.Empty: - raise StopIteration + result = self.results.get() + if result is self._done: + raise StopIteration + return result @overload def find_all_data( @@ -10067,11 +10064,15 @@ def find_all_data( ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.POINTER(core.BNDataBuffer) )(lambda ctxt, addr, match: results.put((addr, databuffer.DataBuffer(handle=match))) or True) - t = threading.Thread( - target=lambda: core.BNFindAllDataWithProgress( - self.handle, start, end, buf.handle, flags, None, progress_func_obj, None, match_callback_obj - ) - ) + def worker(): + try: + core.BNFindAllDataWithProgress( + self.handle, start, end, buf.handle, flags, None, progress_func_obj, None, match_callback_obj + ) + finally: + results.put(self.QueueGenerator._done) + + t = threading.Thread(target=worker) return self.QueueGenerator(t, results) @@ -10182,12 +10183,16 @@ def find_all_text( or True ) - t = threading.Thread( - target=lambda: core.BNFindAllTextWithProgress( - self.handle, start, end, text, settings.handle, flags, graph_type, None, progress_func_obj, None, - match_callback_obj - ) - ) + def worker(): + try: + core.BNFindAllTextWithProgress( + self.handle, start, end, text, settings.handle, flags, graph_type, None, progress_func_obj, None, + match_callback_obj + ) + finally: + results.put(self.QueueGenerator._done) + + t = threading.Thread(target=worker) return self.QueueGenerator(t, results) @@ -10273,12 +10278,16 @@ def find_all_constant( ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.POINTER(core.BNLinearDisassemblyLine) )(lambda ctxt, addr, line: results.put((addr, self._LinearDisassemblyLine_convertor(line))) or True) - t = threading.Thread( - target=lambda: core.BNFindAllConstantWithProgress( - self.handle, start, end, constant, settings.handle, graph_type, None, progress_func_obj, None, - match_callback_obj - ) - ) + def worker(): + try: + core.BNFindAllConstantWithProgress( + self.handle, start, end, constant, settings.handle, graph_type, None, progress_func_obj, None, + match_callback_obj + ) + finally: + results.put(self.QueueGenerator._done) + + t = threading.Thread(target=worker) return self.QueueGenerator(t, results) @@ -10368,7 +10377,14 @@ def internal_match_callback(ctxt, offset, match): match_callback_obj = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.POINTER(core.BNDataBuffer))(internal_match_callback) results = queue.Queue() - t = threading.Thread(target=lambda: core.BNSearch(self.handle, json.dumps(query), None, progress_callback_obj, None, match_callback_obj)) + + def worker(): + try: + core.BNSearch(self.handle, json.dumps(query), None, progress_callback_obj, None, match_callback_obj) + finally: + results.put(self.QueueGenerator._done) + + t = threading.Thread(target=worker) return self.QueueGenerator(t, results) @staticmethod