Remove last globals, be actually re-entrant
This commit is contained in:
parent
dbcd1ee014
commit
0e1cb2952d
52
neomi.py
52
neomi.py
|
@ -133,13 +133,10 @@ def get_request(sock, *, config):
|
||||||
path = ''
|
path = ''
|
||||||
return path, Protocol.gopher, None
|
return path, Protocol.gopher, None
|
||||||
|
|
||||||
# Global variables to keep track of the amount of running worker threads
|
|
||||||
threads_amount = 0
|
|
||||||
threads_lock = threading.Lock()
|
|
||||||
|
|
||||||
# Worker thread implementation
|
# Worker thread implementation
|
||||||
class Serve(threading.Thread):
|
class Serve(threading.Thread):
|
||||||
def __init__(self, sock, address, config):
|
def __init__(self, controller, sock, address, config):
|
||||||
|
self.controller = controller
|
||||||
self.sock = sock
|
self.sock = sock
|
||||||
self.address = address
|
self.address = address
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -159,25 +156,33 @@ class Serve(threading.Thread):
|
||||||
error('Worker thread (%s) died with: %s' % (self.address, err))
|
error('Worker thread (%s) died with: %s' % (self.address, err))
|
||||||
finally:
|
finally:
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
with threads_lock:
|
self.controller.thread_end()
|
||||||
threads_amount -= 1
|
|
||||||
|
|
||||||
# spawn_thread(sock, address, config)
|
class Threads_controller:
|
||||||
# Spawn a new thread to serve a connection if possible, do nothing if not
|
def __init__(self):
|
||||||
def spawn_thread(sock, address, config):
|
self.threads_amount = 0
|
||||||
global threads_amount, threads_lock
|
self.threads_lock = threading.Lock()
|
||||||
|
|
||||||
# See if we can spawn a new thread. If not, log an error, close the socket and return. If yes, increment the amount of threads running
|
# .spawn_thread(sock, address, config)
|
||||||
with threads_lock:
|
# Spawn a new thread to serve a connection if possible, do nothing if not
|
||||||
if threads_amount >= config.max_threads:
|
def spawn_thread(self, sock, address, config):
|
||||||
error('Could not serve a request from %s, worker thread limit exhausted' % address)
|
# See if we can spawn a new thread. If not, log an error, close the socket and return. If yes, increment the amount of threads running
|
||||||
sock.close()
|
with self.threads_lock:
|
||||||
return
|
if self.threads_amount >= config.max_threads:
|
||||||
else:
|
error('Could not serve a request from %s, worker thread limit exhausted' % address)
|
||||||
threads_amount += 1
|
sock.close()
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.threads_amount += 1
|
||||||
|
|
||||||
# Spawn a new worker thread
|
# Spawn a new worker thread
|
||||||
Serve(sock, address, config).start()
|
Serve(self, sock, address, config).start()
|
||||||
|
|
||||||
|
# .thread_end()
|
||||||
|
# Called from worker thread to signal it's exiting
|
||||||
|
def thread_end(self):
|
||||||
|
with self.threads_lock:
|
||||||
|
self.threads_amount -= 1
|
||||||
|
|
||||||
# listen(config) → (Never returns)
|
# listen(config) → (Never returns)
|
||||||
# Binds itself to all interfaces on designated port and listens on incoming connections
|
# Binds itself to all interfaces on designated port and listens on incoming connections
|
||||||
|
@ -200,6 +205,9 @@ def listen(config):
|
||||||
sock_by_fd[s.fileno()] = s
|
sock_by_fd[s.fileno()] = s
|
||||||
del listening_sockets
|
del listening_sockets
|
||||||
|
|
||||||
|
# Create a controller object for the worker threads
|
||||||
|
threads_controller = Threads_controller()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Wait for listening sockets to get activity
|
# Wait for listening sockets to get activity
|
||||||
events = listening.poll()
|
events = listening.poll()
|
||||||
|
@ -213,7 +221,7 @@ def listen(config):
|
||||||
# Set timeout for socket
|
# Set timeout for socket
|
||||||
conn.settimeout(config.socket_timeout)
|
conn.settimeout(config.socket_timeout)
|
||||||
|
|
||||||
spawn_thread(conn, addr[0], config)
|
threads_controller.spawn_thread(conn, addr[0], config)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
listen(default_config)
|
listen(default_config)
|
||||||
|
|
Loading…
Reference in New Issue