from threading import Condition, Lock
from typing import TypeVar, Generic, Optional

_T = TypeVar("_T")


class SyncValue(Generic[_T]):
    def __init__(self):
        self._lock = Lock()
        self._cv = Condition()
        self._value = None

    def sync_send(self, value: _T, timeout: float):
        with self._lock:
            self._value = value

        def predicate():
            with self._lock:
                return self._value is None

        with self._cv:
            return self._cv.wait_for(predicate, timeout)

    def recv_and_notify(self) -> Optional[_T]:
        value = None
        with self._lock:
            if self._value is not None:
                value = self._value
                self._value = None

        if value is not None:
            with self._cv:
                self._cv.notify()

        return value
