summaryrefslogtreecommitdiff
path: root/replacement_poll_selector.py
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-06-14 14:55:27 -0400
committerbd <bdunahu@operationnull.com>2025-06-14 14:55:27 -0400
commitc21e4366fb64130d168150f0ed94293e699eb525 (patch)
tree90b3ae14e89c950580dfb5802d930bd045fb43c4 /replacement_poll_selector.py
parentf4b54b5a2e99be859558331186f725fbfa224594 (diff)
Begin work of monkey-patching EPollSelector
Diffstat (limited to 'replacement_poll_selector.py')
-rw-r--r--replacement_poll_selector.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/replacement_poll_selector.py b/replacement_poll_selector.py
new file mode 100644
index 0000000..0813a66
--- /dev/null
+++ b/replacement_poll_selector.py
@@ -0,0 +1,41 @@
+import selectors
+import sys
+import threading
+import time
+from typing import List, Optional, Tuple
+
+from mini_scalene import MiniScalene
+
+
+@MiniScalene.shim
+def replacement_poll_selector(mini_scalene: MiniScalene) -> None:
+ """
+ A replacement for selectors.PollSelector that
+ periodically wakes up to accept signals
+ """
+
+ class ReplacementPollSelector(selectors.PollSelector):
+ def select(
+ self, timeout: Optional[float] = -1
+ ) -> List[Tuple[selectors.SelectorKey, int]]:
+ tident = threading.get_ident()
+ start_time = time.perf_counter()
+ if not timeout or timeout < 0:
+ interval = sys.getswitchinterval()
+ else:
+ interval = min(timeout, sys.getswitchinterval())
+ while True:
+ scalene.set_thread_sleeping(tident)
+ selected = super().select(interval)
+ scalene.reset_thread_sleeping(tident)
+ if selected or timeout == 0:
+ return selected
+ end_time = time.perf_counter()
+ if timeout and timeout != -1:
+ if end_time - start_time >= timeout:
+ return [] # None
+
+ ReplacementPollSelector.__qualname__ = (
+ "replacement_poll_selector.ReplacementPollSelector"
+ )
+ selectors.PollSelector = ReplacementPollSelector # type: ignore