Queue.py (4581B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\Queue.py 2 from time import time as _time 3 try: 4 import threading as _threading 5 except ImportError: 6 import dummy_threading as _threading 7 8 from collections import deque 9 import heapq 10 __all__ = ['Empty', 11 'Full', 12 'Queue', 13 'PriorityQueue', 14 'LifoQueue'] 15 16 class Empty(Exception): 17 pass 18 19 20 class Full(Exception): 21 pass 22 23 24 class Queue: 25 26 def __init__(self, maxsize = 0): 27 self.maxsize = maxsize 28 self._init(maxsize) 29 self.mutex = _threading.Lock() 30 self.not_empty = _threading.Condition(self.mutex) 31 self.not_full = _threading.Condition(self.mutex) 32 self.all_tasks_done = _threading.Condition(self.mutex) 33 self.unfinished_tasks = 0 34 35 def task_done(self): 36 self.all_tasks_done.acquire() 37 try: 38 unfinished = self.unfinished_tasks - 1 39 if unfinished <= 0: 40 if unfinished < 0: 41 raise ValueError('task_done() called too many times') 42 self.all_tasks_done.notify_all() 43 self.unfinished_tasks = unfinished 44 finally: 45 self.all_tasks_done.release() 46 47 def join(self): 48 self.all_tasks_done.acquire() 49 try: 50 while self.unfinished_tasks: 51 self.all_tasks_done.wait() 52 53 finally: 54 self.all_tasks_done.release() 55 56 def qsize(self): 57 self.mutex.acquire() 58 n = self._qsize() 59 self.mutex.release() 60 return n 61 62 def empty(self): 63 self.mutex.acquire() 64 n = not self._qsize() 65 self.mutex.release() 66 return n 67 68 def full(self): 69 self.mutex.acquire() 70 n = 0 < self.maxsize == self._qsize() 71 self.mutex.release() 72 return n 73 74 def put(self, item, block = True, timeout = None): 75 self.not_full.acquire() 76 try: 77 if self.maxsize > 0: 78 if not block: 79 if self._qsize() == self.maxsize: 80 raise Full 81 elif timeout is None: 82 while self._qsize() == self.maxsize: 83 self.not_full.wait() 84 85 elif timeout < 0: 86 raise ValueError("'timeout' must be a positive number") 87 else: 88 endtime = _time() + timeout 89 while self._qsize() == self.maxsize: 90 remaining = endtime - _time() 91 if remaining <= 0.0: 92 raise Full 93 self.not_full.wait(remaining) 94 95 self._put(item) 96 self.unfinished_tasks += 1 97 self.not_empty.notify() 98 finally: 99 self.not_full.release() 100 101 def put_nowait(self, item): 102 return self.put(item, False) 103 104 def get(self, block = True, timeout = None): 105 self.not_empty.acquire() 106 try: 107 if not block: 108 if not self._qsize(): 109 raise Empty 110 elif timeout is None: 111 while not self._qsize(): 112 self.not_empty.wait() 113 114 elif timeout < 0: 115 raise ValueError("'timeout' must be a positive number") 116 else: 117 endtime = _time() + timeout 118 while not self._qsize(): 119 remaining = endtime - _time() 120 if remaining <= 0.0: 121 raise Empty 122 self.not_empty.wait(remaining) 123 124 item = self._get() 125 self.not_full.notify() 126 return item 127 finally: 128 self.not_empty.release() 129 130 def get_nowait(self): 131 return self.get(False) 132 133 def _init(self, maxsize): 134 self.queue = deque() 135 136 def _qsize(self, len = len): 137 return len(self.queue) 138 139 def _put(self, item): 140 self.queue.append(item) 141 142 def _get(self): 143 return self.queue.popleft() 144 145 146 class PriorityQueue(Queue): 147 148 def _init(self, maxsize): 149 self.queue = [] 150 151 def _qsize(self, len = len): 152 return len(self.queue) 153 154 def _put(self, item, heappush = heapq.heappush): 155 heappush(self.queue, item) 156 157 def _get(self, heappop = heapq.heappop): 158 return heappop(self.queue) 159 160 161 class LifoQueue(Queue): 162 163 def _init(self, maxsize): 164 self.queue = [] 165 166 def _qsize(self, len = len): 167 return len(self.queue) 168 169 def _put(self, item): 170 self.queue.append(item) 171 172 def _get(self): 173 return self.queue.pop()