pythonpython-3.xsockets

Why is `setblocking(False)` used in Python's socketpair implementation?


I was looking through a Python implementation of socketpair that uses standard sockets. Here's the code snippet I found:

def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
    if family == AF_INET:
        host = _LOCALHOST
    elif family == AF_INET6:
        host = _LOCALHOST_V6
    else:
        raise ValueError("Only AF_INET and AF_INET6 socket address families "
                            "are supported")
    if type != SOCK_STREAM:
        raise ValueError("Only SOCK_STREAM socket type is supported")
    if proto != 0:
        raise ValueError("Only protocol zero is supported")

    # We create a connected TCP socket. Note the trick with
    # setblocking(False) that prevents us from having to create a thread.
    lsock = socket(family, type, proto)
    try:
        lsock.bind((host, 0))
        lsock.listen()
        addr, port = lsock.getsockname()[:2]
        csock = socket(family, type, proto)
        try:
            csock.setblocking(False)
            try:
                csock.connect((addr, port))
            except (BlockingIOError, InterruptedError):
                pass
            csock.setblocking(True)
            ssock, _ = lsock.accept()
        except:
            csock.close()
            raise
    finally:
        lsock.close()
    return (ssock, csock)

The implementation mentions that setblocking(False) is necessary to "prevent us from having to create a thread," but I can't seem to understand why this is required.

I initially thought that omitting setblocking(False) could lead to a deadlock or blocking behavior, but after testing on both Linux and Windows, the code seems to work fine without it, and the connect call does not block.

So my question is:

  1. What specific issue is setblocking(False) intended to solve here?
  2. Are there platform-specific scenarios or edge cases where the absence of setblocking(False) would cause problems?

Any insight into this behavior would be greatly appreciated.


Solution

  • The code is initiating a non-blocking connect to another socket within the same thread, i.e.

    1. create server (listener) socket lsock and client socket csock
    2. initiate non-blocking connect from csock to lsock
    3. accept this connect on lsock, returning ssock

    The non-blocking connect in (2) returns immediately, even if the socket is not yet accepted (3). If instead a blocking connect would be used then it would hang in (2) until accept gets called in (3), which would never happen because it hangs in (2).

    The alternative would be to do a blocking connect and a blocking accept in separate threads. Hence the comment:

    # ... Note the trick with
    # setblocking(False) that prevents us from having to create a thread