Repository: encode/uvicorn

Issue:
Invalid argument was supplied error on windows
There seems to be an issue when I increase the worker process count greater than 1.
**command** -> `uvicorn --port 9000 --workers 2 MyProject.asgi:application`
**error log** ->
```
INFO:     Uvicorn running on http://127.0.0.1:9000 (Press CTRL+C to quit)
INFO:     Started parent process [17696]
INFO:     Started server process [20428]
INFO:     Started server process [15476]
INFO:     Waiting for application startup.
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Application startup complete.
Process SpawnProcess-2:
Traceback (most recent call last):
  File "c:\users\arnab\appdata\local\programs\python\python37-32\Lib\multiprocessing\process.py", line 297, in _bootstrap    
    self.run()
  File "c:\users\arnab\appdata\local\programs\python\python37-32\Lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "t:\my projects\scholify-web\env\lib\site-packages\uvicorn\subprocess.py", line 62, in subprocess_started
    target(sockets=sockets)
  File "t:\my projects\scholify-web\env\lib\site-packages\uvicorn\main.py", line 382, in run
    loop.run_until_complete(self.serve(sockets=sockets))
  File "c:\users\arnab\appdata\local\programs\python\python37-32\Lib\asyncio\base_events.py", line 579, in run_until_complete
    return future.result()
  File "t:\my projects\scholify-web\env\lib\site-packages\uvicorn\main.py", line 399, in serve
    await self.startup(sockets=sockets)
  File "t:\my projects\scholify-web\env\lib\site-packages\uvicorn\main.py", line 433, in startup
    create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog
  File "c:\users\arnab\appdata\local\programs\python\python37-32\Lib\asyncio\base_events.py", line 1393, in create_server    
    server._start_serving()
  File "c:\users\arnab\appdata\local\programs\python\python37-32\Lib\asyncio\base_events.py", line 282, in _start_serving    
    sock.listen(self._backlog)
OSError: [WinError 10022] An invalid argument was supplied
```


Discussion:

Resolving patch:
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -414,8 +414,19 @@ async def startup(self, sockets=None):
         if sockets is not None:
             # Explicitly passed a list of open sockets.
             # We use this when the server is run from a Gunicorn worker.
+
+            def _share_socket(sock: socket) -> socket:
+                # Windows requires the socket be explicitly shared across
+                # multiple workers (processes).
+                from socket import fromshare  # type: ignore
+
+                sock_data = sock.share(os.getpid())  # type: ignore
+                return fromshare(sock_data)
+
             self.servers = []
             for sock in sockets:
+                if config.workers > 1 and platform.system() == "Windows":
+                    sock = _share_socket(sock)
                 server = await loop.create_server(
                     create_protocol, sock=sock, ssl=config.ssl
                 )


Test patch: