[Python-Dev] blocking a non-blocking socket

Bill Janssen janssen at parc.com
Sun Dec 2 21:23:01 CET 2007


An interesting question has come up in the development of the SSL module.

The function ssl.wrap_socket() takes a flag, do_handshake_on_connect,
which tells it whether to do the SSL handshake before returning an
SSLSocket object to the caller.  If the socket being wrapped is
non-blocking, the code in wrap_socket() must invoke do_handshake()
multiple times, and effectively block until the handshake is done.

Right now, I'm doing it with this loop:

            if do_handshake_on_connect:
                # have to loop to support non-blocking sockets
                while True:
                    try:
                        self.do_handshake()
                        break
                    except SSLError, err:
                        if err.args[0] == SSL_ERROR_WANT_READ:
                            select.select([self], [], [])
                        elif err.args[0] == SSL_ERROR_WANT_WRITE:
                            select.select([], [self], [])
                        else:
                            raise

But this seems fragile to me.  "select" and/or "poll" is awfully
system-dependent.  What I'd like to do is just use the socket API,
something like:

    blocking = self.getblocking()
    try:
        self.setblocking(1)
	self.do_handshake()
    finally:
        self.setblocking(blocking)

But there's no "getblocking" method on sockets.  Instead, there's
"gettimeout".  So I'd write something like
	
    timeout = self.gettimeout()
    try:
        self.setblocking(1)
	self.do_handshake()
    finally:
        if (timeout == 0.0):
	    self.setblocking(0)

But my mother taught me never to test for equality against
floating-point zero.  But in this case it might just fly...

Or, should I just set the timeout:

    timeout = self.gettimeout()
    try:
        self.settimeout(None)
	self.do_handshake()
    finally:
        self.settimeout(timeout)

This is the solution I'm leaning towards...

Any recommendations?

Bill


More information about the Python-Dev mailing list