| 149 | print("Path: %s" % "/".join(test.path)) |
| 150 | |
| 151 | def Run(self, tasks) -> Dict: |
| 152 | self.Starting() |
| 153 | threads = [] |
| 154 | # Spawn N-1 threads and then use this thread as the last one. |
| 155 | # That way -j1 avoids threading altogether which is a nice fallback |
| 156 | # in case of threading problems. |
| 157 | for i in range(tasks - 1): |
| 158 | thread = threading.Thread(target=self.RunSingle, args=[True, i + 1]) |
| 159 | threads.append(thread) |
| 160 | thread.start() |
| 161 | try: |
| 162 | self.RunSingle(False, 0) |
| 163 | # Wait for the remaining threads |
| 164 | for thread in threads: |
| 165 | # Use a timeout so that signals (ctrl-c) will be processed. |
| 166 | thread.join(timeout=1000000) |
| 167 | except (KeyboardInterrupt, SystemExit): |
| 168 | self.shutdown_event.set() |
| 169 | except Exception: |
| 170 | # If there's an exception we schedule an interruption for any |
| 171 | # remaining threads. |
| 172 | self.shutdown_event.set() |
| 173 | # ...and then reraise the exception to bail out |
| 174 | raise |
| 175 | self.Done() |
| 176 | return { |
| 177 | 'allPassed': not self.failed and not self.shutdown_event.is_set(), |
| 178 | 'failed': self.failed, |
| 179 | } |
| 180 | |
| 181 | def RunSingle(self, parallel, thread_id): |
| 182 | while not self.shutdown_event.is_set(): |