# Path: pyinstrument/stack_sampler.py
# class StackSamplerSubscriber:
# class StackSampler:
#     class SubscriberNotFound(Exception):
# class AsyncState(NamedTuple):
#     def __init__(
#         self,
#         *,
#         target: StackSamplerSubscriberTarget,
#         desired_interval: float,
#         bound_to_async_context: bool,
#         async_state: AsyncState | None,
#     ) -> None:
#     def __init__(self) -> None:
#     def subscribe(
#         self,
#         target: StackSamplerSubscriberTarget,
#         desired_interval: float,
#         use_async_context: bool,
#     ):
#     def unsubscribe(self, target: StackSamplerSubscriberTarget):
#     def _update(self):
#     def _start_sampling(self, interval: float):
#     def _stop_sampling(self):
#     def _sample(self, frame: types.FrameType, event: str, arg: Any):
#     def _timer(self):
# def get_stack_sampler() -> StackSampler:
# def build_call_stack(frame: types.FrameType | None, event: str, arg: Any) -> list[str]:
# 
# Path: test/util.py
# def do_nothing():
#     pass


import contextvars
import sys
import time
import pytest
from pyinstrument import stack_sampler
from .util import do_nothing
    counter_1 = SampleCounter()
    counter_2 = SampleCounter()

    sampler.subscribe(counter_1.sample, desired_interval=0.001, use_async_context=True)

    with pytest.raises(RuntimeError):
        sampler.subscribe(counter_2.sample, desired_interval=0.001, use_async_context=True)

    sampler.unsubscribe(counter_1.sample)


def test_multiple_contexts():
    sampler = stack_sampler.get_stack_sampler()

    counter_1 = SampleCounter()
    counter_2 = SampleCounter()

    context_1 = contextvars.copy_context()
    context_2 = contextvars.copy_context()

    assert sys.getprofile() is None
    assert len(sampler.subscribers) == 0
    context_1.run(sampler.subscribe, counter_1.sample, 0.001, True)
    context_2.run(sampler.subscribe, counter_2.sample, 0.001, True)

    assert sys.getprofile() is not None
    assert len(sampler.subscribers) == 2

    start = time.time()
    while time.time() < start + 1 and counter_1.count == 0 and counter_2.count == 0:

# Path: pyinstrument/stack_sampler.py
# class StackSamplerSubscriber:
# class StackSampler:
#     class SubscriberNotFound(Exception):
# class AsyncState(NamedTuple):
#     def __init__(
#         self,
#         *,
#         target: StackSamplerSubscriberTarget,
#         desired_interval: float,
#         bound_to_async_context: bool,
#         async_state: AsyncState | None,
#     ) -> None:
#     def __init__(self) -> None:
#     def subscribe(
#         self,
#         target: StackSamplerSubscriberTarget,
#         desired_interval: float,
#         use_async_context: bool,
#     ):
#     def unsubscribe(self, target: StackSamplerSubscriberTarget):
#     def _update(self):
#     def _start_sampling(self, interval: float):
#     def _stop_sampling(self):
#     def _sample(self, frame: types.FrameType, event: str, arg: Any):
#     def _timer(self):
# def get_stack_sampler() -> StackSampler:
# def build_call_stack(frame: types.FrameType | None, event: str, arg: Any) -> list[str]:
# 
# Path: test/util.py
# def do_nothing():
#     pass


# Path: test/test_stack_sampler.py
import contextvars
import sys
import time
import pytest
from pyinstrument import stack_sampler
from .util import do_nothing

    counter_1 = SampleCounter()
    counter_2 = SampleCounter()

    sampler.subscribe(counter_1.sample, desired_interval=0.001, use_async_context=True)

    with pytest.raises(RuntimeError):
        sampler.subscribe(counter_2.sample, desired_interval=0.001, use_async_context=True)

    sampler.unsubscribe(counter_1.sample)


def test_multiple_contexts():
    sampler = stack_sampler.get_stack_sampler()

    counter_1 = SampleCounter()
    counter_2 = SampleCounter()

    context_1 = contextvars.copy_context()
    context_2 = contextvars.copy_context()

    assert sys.getprofile() is None
    assert len(sampler.subscribers) == 0
    context_1.run(sampler.subscribe, counter_1.sample, 0.001, True)
    context_2.run(sampler.subscribe, counter_2.sample, 0.001, True)

    assert sys.getprofile() is not None
    assert len(sampler.subscribers) == 2

    start = time.time()
    while time.time() < start + 1 and counter_1.count == 0 and counter_2.count == 0:

        do_nothing()