Use a lock in send_line_raw and don't thread sending of data through the mainloop

This commit is contained in:
Juhani Haverinen 2017-09-05 10:05:02 +03:00
parent 8cfec71fb1
commit 4e1efa5b61
1 changed files with 5 additions and 19 deletions

View File

@ -13,13 +13,16 @@ class ServerThread(threading.Thread):
self.server = server self.server = server
self.control_socket = control_socket self.control_socket = control_socket
self.server_socket_write_lock = threading.Lock()
threading.Thread.__init__(self) threading.Thread.__init__(self)
def send_line_raw(self, line): def send_line_raw(self, line):
# Sanitize line just in case # Sanitize line just in case
line = line.replace(b'\r', b'').replace(b'\n', b'')[:510] line = line.replace(b'\r', b'').replace(b'\n', b'')[:510]
self.server_socket.sendall(line + b'\r\n') with self.server_socket_write_lock:
self.server_socket.sendall(line + b'\r\n')
# FIXME: print is not thread safe # FIXME: print is not thread safe
print('>' + line.decode(encoding = 'utf-8', errors = 'replace')) print('>' + line.decode(encoding = 'utf-8', errors = 'replace'))
@ -37,11 +40,9 @@ class ServerThread(threading.Thread):
# Keep buffers for input and output # Keep buffers for input and output
server_input_buffer = bytearray() server_input_buffer = bytearray()
server_output_buffer = bytearray()
control_input_buffer = bytearray() control_input_buffer = bytearray()
quitting = False quitting = False
writing = False
while not quitting: while not quitting:
# Wait until we can do something # Wait until we can do something
for fd, event in poll.poll(): for fd, event in poll.poll():
@ -60,11 +61,6 @@ class ServerThread(threading.Thread):
self.handle_line(line) self.handle_line(line)
# Ready to send, send buffered output as far as possible
if event | select.POLLOUT:
sent = self.server_socket.send(server_output_buffer)
server_output_buffer = server_output_buffer[sent:]
# Control # Control
elif fd == self.control_socket.fileno(): elif fd == self.control_socket.fileno():
# Read into buffer and handle full commands # Read into buffer and handle full commands
@ -78,17 +74,6 @@ class ServerThread(threading.Thread):
else: else:
assert False #unreachable assert False #unreachable
# See if we have to change what we're listening for
if not writing and len(server_output_buffer) > 0:
# Mark we're listening to socket becoming writable, and start listening
writing = True
poll.modify(self.server_socket, select.POLLIN | select.POLLOUT)
elif writing and len(server_output_buffer) == 0:
# Mark we're not listening to socket becoming writable, and stop listening
writing = False
poll.modify(self.server_socket, select.POLLIN)
def run(self): def run(self):
# Connect to given server # Connect to given server
address = (self.server.host, self.server.port) address = (self.server.host, self.server.port)
@ -140,6 +125,7 @@ if __name__ == '__main__':
print(control_messages.decode(encoding = 'utf-8', errors = 'replace')) print(control_messages.decode(encoding = 'utf-8', errors = 'replace'))
elif cmd == 'q': elif cmd == 'q':
control_socket.sendall(b'Q\n')
control_socket.close() control_socket.close()
break break