"""TRACKEXEC-01: FIFO turns for small-array ByteTrack work; channel state stays private."""

from collections import deque
from contextlib import contextmanager
import threading
import time


class TrackingKernel:
    def __init__(self):
        self._condition = threading.Condition()
        self._waiting = deque()
        self._owner = None

    @contextmanager
    def turn(self):
        started = time.monotonic_ns()
        token = object()
        ident = threading.get_ident()
        with self._condition:
            if self._owner == ident:
                raise RuntimeError('Tracking kernel cannot be entered recursively.')
            self._waiting.append(token)
            try:
                self._condition.wait_for(lambda: self._waiting[0] is token)
            except BaseException:
                self._waiting.remove(token)
                self._condition.notify_all()
                raise
            self._owner = ident
        try:
            yield time.monotonic_ns() - started
        finally:
            with self._condition:
                self._waiting.popleft()
                self._owner = None
                self._condition.notify_all()


TRACKING_KERNEL = TrackingKernel()
