()
| 752 | |
| 753 | # Wrapper around the asyncore loop that lets us poll the in/out pipes every 1ms |
| 754 | def run_loop(): |
| 755 | global must_exit |
| 756 | global in_pipe |
| 757 | global out_pipe |
| 758 | global needs_flush |
| 759 | global flush_pipes |
| 760 | global last_activity |
| 761 | global last_client_disconnected |
| 762 | global dns_cache |
| 763 | winmm = None |
| 764 | |
| 765 | # increase the windows timer resolution to 1ms |
| 766 | if platform.system() == "Windows": |
| 767 | try: |
| 768 | import ctypes |
| 769 | winmm = ctypes.WinDLL('winmm') |
| 770 | winmm.timeBeginPeriod(1) |
| 771 | except: |
| 772 | pass |
| 773 | |
| 774 | last_activity = current_time() |
| 775 | last_check = current_time() |
| 776 | # disable gc to avoid pauses during traffic shaping/proxying |
| 777 | gc.disable() |
| 778 | out_interval = None |
| 779 | in_interval = None |
| 780 | while not must_exit: |
| 781 | # Tick every 1ms if traffic-shaping is enabled and we have data or are doing background dns lookups, every 1 second otherwise |
| 782 | lock.acquire() |
| 783 | tick_interval = 0.001 |
| 784 | if out_interval is not None: |
| 785 | tick_interval = max(tick_interval, out_interval) |
| 786 | if in_interval is not None: |
| 787 | tick_interval = max(tick_interval, in_interval) |
| 788 | if background_activity_count == 0: |
| 789 | if in_pipe.next_message is None and in_pipe.queue.empty() and out_pipe.next_message is None and out_pipe.queue.empty(): |
| 790 | tick_interval = 1.0 |
| 791 | elif in_pipe.kbps == .0 and in_pipe.latency == 0 and out_pipe.kbps == .0 and out_pipe.latency == 0: |
| 792 | tick_interval = 1.0 |
| 793 | lock.release() |
| 794 | logging.debug("Tick Time: %0.3f", tick_interval) |
| 795 | asyncore.poll(tick_interval, asyncore.socket_map) |
| 796 | if needs_flush: |
| 797 | flush_pipes = True |
| 798 | dns_cache = {} |
| 799 | needs_flush = False |
| 800 | out_interval = out_pipe.tick() |
| 801 | in_interval = in_pipe.tick() |
| 802 | if flush_pipes: |
| 803 | PrintMessage('OK') |
| 804 | flush_pipes = False |
| 805 | now = current_time() |
| 806 | # Clear the DNS cache 500ms after the last client disconnects |
| 807 | if options.flushdnscache and last_client_disconnected is not None and dns_cache: |
| 808 | if now - last_client_disconnected >= 0.5: |
| 809 | dns_cache = {} |
| 810 | last_client_disconnected = None |
| 811 | logging.debug("Flushed DNS cache") |
no test coverage detected