# Buggy code
def reformat_many(
    sources: Set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: "Report"
) -> None:
    """Reformat multiple files using a ProcessPoolExecutor."""
    loop = asyncio.get_event_loop()
    worker_count = os.cpu_count()
    if sys.platform == "win32":
        # Work around https://bugs.python.org/issue26903
        worker_count = min(worker_count, 61)
    executor = ProcessPoolExecutor(max_workers=worker_count)
    try:
        loop.run_until_complete(
            schedule_formatting(
                sources=sources,
                fast=fast,
                write_back=write_back,
                mode=mode,
                report=report,
                loop=loop,
                executor=executor,
            )
        )
    finally:
        shutdown(loop)
        executor.shutdown()


# Traceback (OSError)
|Traceback (most recent call last):
|  File "/usr/local/lib/XXX/virtualenv/bin/black", line 11, in <module>
|    sys.exit(patched_main())
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/black.py", line 3754, in patched_main
|    main()
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/click/core.py", line 764, in __call__
|    return self.main(*args, **kwargs)
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/click/core.py", line 717, in main
|    rv = self.invoke(ctx)
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/click/core.py", line 956, in invoke
|    return ctx.invoke(self.callback, **ctx.params)
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/click/core.py", line 555, in invoke
|    return callback(*args, **kwargs)
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/click/decorators.py", line 17, in new_func
|    return f(get_current_context(), *args, **kwargs)
|  File "/usr/local/lib/XXX/virtualenv/lib/python3.6/site-packages/black.py", line 435, in main
|    executor = ProcessPoolExecutor(max_workers=os.cpu_count())
|  File "/usr/lib/python3.6/concurrent/futures/process.py", line 402, in __init__
|    EXTRA_QUEUED_CALLS)
|  File "/usr/lib/python3.6/multiprocessing/context.py", line 102, in Queue
|    return Queue(maxsize, ctx=self.get_context())
|  File "/usr/lib/python3.6/multiprocessing/queues.py", line 42, in __init__
|    self._rlock = ctx.Lock()
|  File "/usr/lib/python3.6/multiprocessing/context.py", line 67, in Lock
|    return Lock(ctx=self.get_context())
|  File "/usr/lib/python3.6/multiprocessing/synchronize.py", line 162, in __init__
|    SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx)
|  File "/usr/lib/python3.6/multiprocessing/synchronize.py", line 59, in __init__
|    unlink_now)
|OSError: [Errno 30] Read-only file system

# Fixed code
def reformat_many(
    sources: Set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: "Report"
) -> None:
    """Reformat multiple files using a ProcessPoolExecutor."""
    loop = asyncio.get_event_loop()
    worker_count = os.cpu_count()
    if sys.platform == "win32":
        # Work around https://bugs.python.org/issue26903
        worker_count = min(worker_count, 61)
    try:
        executor = ProcessPoolExecutor(max_workers=worker_count)
    except OSError:
        # we arrive here if the underlying system does not support multi-processing
        # like in AWS Lambda, in which case we gracefully fallback to the default
        # mono-process Executor by using None
        executor = None

    try:
        loop.run_until_complete(
            schedule_formatting(
                sources=sources,
                fast=fast,
                write_back=write_back,
                mode=mode,
                report=report,
                loop=loop,
                executor=executor,
            )
        )
    finally:
        shutdown(loop)
        if executor is not None:
            executor.shutdown()