From 0ebb73aa240f0ecffe3e0922d54cfece19f5bfed Mon Sep 17 00:00:00 2001 From: JorisOnGithub Date: Mon, 16 Jan 2023 22:46:58 +0100 Subject: [PATCH] gthread: only read sockets when they are readable --- gunicorn/workers/gthread.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/gunicorn/workers/gthread.py b/gunicorn/workers/gthread.py index d53181154..877c1d128 100644 --- a/gunicorn/workers/gthread.py +++ b/gunicorn/workers/gthread.py @@ -40,12 +40,15 @@ def __init__(self, cfg, sock, client, server): self.timeout = None self.parser = None + self.initialized = False # set the socket to non blocking self.sock.setblocking(False) def init(self): + self.initialized = True self.sock.setblocking(True) + if self.parser is None: # wrap the socket if needed if self.cfg.is_ssl: @@ -120,23 +123,28 @@ def accept(self, server, listener): # initialize the connection object conn = TConn(self.cfg, sock, client, server) self.nr_conns += 1 - # enqueue the job - self.enqueue_req(conn) + + # wait until socket is readable + with self._lock: + self.poller.register(conn.sock, selectors.EVENT_READ, + partial(self.on_client_socket_readable, conn)) except EnvironmentError as e: if e.errno not in (errno.EAGAIN, errno.ECONNABORTED, errno.EWOULDBLOCK): raise - def reuse_connection(self, conn, client): + def on_client_socket_readable(self, conn, client): with self._lock: # unregister the client from the poller self.poller.unregister(client) - # remove the connection from keepalive - try: - self._keep.remove(conn) - except ValueError: - # race condition - return + + if conn.initialized: + # remove the connection from keepalive + try: + self._keep.remove(conn) + except ValueError: + # race condition + return # submit the connection to a worker self.enqueue_req(conn) @@ -249,7 +257,7 @@ def finish_request(self, fs): # add the socket to the event loop self.poller.register(conn.sock, selectors.EVENT_READ, - partial(self.reuse_connection, conn)) + partial(self.on_client_socket_readable, conn)) else: self.nr_conns -= 1 conn.close()