================ @@ -501,70 +506,72 @@ def main(): # Build up a big regexy filter from all command line arguments. file_name_re = re.compile("|".join(args.files)) + files = {f for f in files if file_name_re.search(f)} - return_code = 0 + returncode = 0 try: - # Spin up a bunch of tidy-launching threads. - task_queue = queue.Queue(max_task) - # List of files with a non-zero return code. - failed_files = [] - lock = threading.Lock() - for _ in range(max_task): - t = threading.Thread( - target=run_tidy, - args=( - args, - clang_tidy_binary, - export_fixes_dir, - build_path, - task_queue, - lock, - failed_files, - ), + semaphore = asyncio.Semaphore(max_task) + tasks = [ + run_with_semaphore( + semaphore, + run_tidy, + args, + f, + clang_tidy_binary, + export_fixes_dir, + build_path, ) - t.daemon = True - t.start() - - # Fill the queue with files. - for name in files: - if file_name_re.search(name): - task_queue.put(name) - - # Wait for all threads to be done. - task_queue.join() - if len(failed_files): - return_code = 1 - + for f in files + ] + + for i, coro in enumerate(asyncio.as_completed(tasks)): + name, process_returncode, stdout, stderr = await coro + if process_returncode != 0: + returncode = 1 + if process_returncode < 0: + stderr += f"{name}: terminated by signal {-process_returncode}\n" + print(f"[{i + 1}/{len(files)}] {name}") + if stdout: + print(stdout) + if stderr: + print(stderr, file=sys.stderr) except KeyboardInterrupt: # This is a sad hack. Unfortunately subprocess goes # bonkers with ctrl-c and we start forking merrily. print("\nCtrl-C detected, goodbye.") if delete_fixes_dir: + assert export_fixes_dir shutil.rmtree(export_fixes_dir) os.kill(0, 9) if combine_fixes: - print("Writing fixes to " + args.export_fixes + " ...") + print(f"Writing fixes to {args.export_fixes} ...") try: + assert export_fixes_dir merge_replacement_files(export_fixes_dir, args.export_fixes) except: print("Error exporting fixes.\n", file=sys.stderr) traceback.print_exc() - return_code = 1 + returncode = 1 if args.fix: print("Applying fixes ...") try: + assert export_fixes_dir apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir) except: print("Error applying fixes.\n", file=sys.stderr) traceback.print_exc() - return_code = 1 + returncode = 1 if delete_fixes_dir: + assert export_fixes_dir shutil.rmtree(export_fixes_dir) - sys.exit(return_code) + sys.exit(returncode) if __name__ == "__main__": - main() + # FIXME Python 3.7: This can be simplified by asyncio.run(main()). + loop = asyncio.new_event_loop() + loop.run_until_complete(main()) + loop.close() ---------------- nicovank wrote:
If you call main or any other `async` function without special handling you get some ``` RuntimeWarning: coroutine 'main' was never awaited ``` Since `await` can only be used in `async` functions, it's common to use [`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run) and wrap `main`. That is Python 3.7 and above, we get compatibility with 3.6 by using those 3 lines instead. https://github.com/llvm/llvm-project/pull/89490 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits