| 159 | #c int log_level=0, bint result_id=False, bint exc_stack=False, bint exc_args=False, |
| 160 | #c int done_max=0): |
| 161 | def __init__(self, max_children=-9999, child_name_prefix="", init_callback=None, #p |
| 162 | init_args=None, finish_callback=None, done_callback=None, failed_callback=None, #p |
| 163 | log_level=None, result_id=False, exc_stack=False, exc_args=False, #p |
| 164 | done_max=0): #p |
| 165 | self._job_cnt = Semaphore(0) |
| 166 | self._children = deque() |
| 167 | if max_children <= -9999: |
| 168 | self.max_children = cpu_count() |
| 169 | elif max_children > 0: |
| 170 | self.max_children = max_children |
| 171 | else: |
| 172 | self.max_children = cpu_count() + max_children |
| 173 | if self.max_children <= 0: |
| 174 | raise ValueError("Number of child threads must be greater than 0") |
| 175 | self.child_name_prefix = child_name_prefix + "-" if child_name_prefix else "ThreadPool%s-" % id(self) |
| 176 | self.result_id = result_id # Add id to each result |
| 177 | self.exc_stack = exc_stack # Return frame stack for each error instead of short error message. |
| 178 | self.exc_args = exc_args # In case of an exception in child thread also return work item arguments |
| 179 | #c self._busy_lock = pythread.PyThread_allocate_lock() |
| 180 | self._busy_lock = Lock() #p |
| 181 | self._busy_cnt = 0 # Number of busy child threads |
| 182 | self._idle_event = Event() |
| 183 | self._delayed = deque() |
| 184 | self._scheduled = deque() |
| 185 | self._jobs = deque() |
| 186 | self._jobs_append = self._jobs.append |
| 187 | self._jobs_appendleft = self._jobs.appendleft |
| 188 | self._done = deque() |
| 189 | self._failed = deque() |
| 190 | self._done_cnt = Semaphore(0) |
| 191 | self._failed_cnt = Semaphore(0) |
| 192 | self._shutdown_children = False |
| 193 | self._shutdown = False |
| 194 | self.logger = None |
| 195 | self.init_callback = init_callback |
| 196 | self.init_args = tuple() if init_args is None else init_args |
| 197 | self.done_callback = False if done_callback is False else True |
| 198 | self.finish_callback = finish_callback |
| 199 | self._done_max = done_max # Maximum number of results in done queue (0=no limit). |
| 200 | #c self._done_max_lock = pythread.PyThread_allocate_lock() |
| 201 | self._done_max_lock = Lock() #p |
| 202 | if callable(done_callback): |
| 203 | self._thr_done = Thread(target=self._done_thread, args=(done_callback, ), |
| 204 | name="ThreadPoolDone") |
| 205 | self._thr_done.daemon = True |
| 206 | self._thr_done.start() |
| 207 | else: |
| 208 | self._thr_done = None |
| 209 | if failed_callback or log_level: |
| 210 | if log_level: |
| 211 | import logging |
| 212 | self.logger = logging.getLogger(LOGGER_NAME) |
| 213 | self.logger.propagate = False |
| 214 | formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT) |
| 215 | handler = logging.StreamHandler() |
| 216 | handler.setFormatter(formatter) |
| 217 | self.logger.addHandler(handler) |
| 218 | if log_level: |