Kill deadlock that sometimes occurred on shutdown.

This commit is contained in:
Aldo Cortesi 2011-01-27 13:32:24 +13:00
parent 077272ec97
commit efe11a0782
5 changed files with 20 additions and 15 deletions

View File

@ -714,6 +714,9 @@ class ConsoleMaster(controller.Master):
self.ui.run_wrapper(self.loop) self.ui.run_wrapper(self.loop)
# If True, quit just pops out to connection list view. # If True, quit just pops out to connection list view.
print >> sys.stderr, "Shutting down..."
sys.stderr.flush()
self.shutdown()
self.nested = False self.nested = False
def make_view(self): def make_view(self):
@ -1015,7 +1018,6 @@ class ConsoleMaster(controller.Master):
self.view.keypress(size, k) self.view.keypress(size, k)
except (Stop, KeyboardInterrupt): except (Stop, KeyboardInterrupt):
pass pass
self.shutdown()
def shutdown(self): def shutdown(self):
for i in self.state.flow_list: for i in self.state.flow_list:

View File

@ -29,8 +29,11 @@ class Msg:
def send(self, masterq): def send(self, masterq):
self.acked = False self.acked = False
masterq.put(self) try:
return self.q.get() masterq.put(self, timeout=3)
return self.q.get(timeout=3)
except (Queue.Empty, Queue.Full):
return None
class Slave(threading.Thread): class Slave(threading.Thread):

View File

@ -78,14 +78,13 @@ class Flow:
return isinstance(self.connection, ReplayConnection) return isinstance(self.connection, ReplayConnection)
def kill(self): def kill(self):
if self.intercepting: if self.request and not self.request.acked:
if not self.request.acked: self.request.kill = True
self.request.kill = True self.request.ack()
self.request.ack() elif self.response and not self.response.acked:
elif self.response and not self.response.acked: self.response.kill = True
self.response.kill = True self.response.ack()
self.response.ack() self.intercepting = False
self.intercepting = False
def intercept(self): def intercept(self):
self.intercepting = True self.intercepting = True

View File

@ -85,7 +85,6 @@ class Request(controller.Msg):
self.connection = connection self.connection = connection
self.host, self.port, self.scheme = host, port, scheme self.host, self.port, self.scheme = host, port, scheme
self.method, self.path, self.headers, self.content = method, path, headers, content self.method, self.path, self.headers, self.content = method, path, headers, content
self.kill = False
controller.Msg.__init__(self) controller.Msg.__init__(self)
def get_state(self): def get_state(self):
@ -161,7 +160,6 @@ class Response(controller.Msg):
self.request = request self.request = request
self.code, self.proto, self.msg = code, proto, msg self.code, self.proto, self.msg = code, proto, msg
self.headers, self.content = headers, content self.headers, self.content = headers, content
self.kill = False
controller.Msg.__init__(self) controller.Msg.__init__(self)
def get_state(self): def get_state(self):
@ -341,13 +339,13 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
try: try:
request = self.read_request(bc) request = self.read_request(bc)
request = request.send(self.mqueue) request = request.send(self.mqueue)
if request.kill: if request is None:
self.finish() self.finish()
return return
server = ServerConnection(request) server = ServerConnection(request)
response = server.read_response() response = server.read_response()
response = response.send(self.mqueue) response = response.send(self.mqueue)
if response.kill: if response is None:
server.terminate() server.terminate()
self.finish() self.finish()
return return
@ -405,6 +403,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
self.wfile.flush() self.wfile.flush()
def terminate(self, connection, wfile, rfile): def terminate(self, connection, wfile, rfile):
self.request.close()
try: try:
if not getattr(wfile, "closed", False): if not getattr(wfile, "closed", False):
wfile.flush() wfile.flush()

View File

@ -81,3 +81,5 @@ if __name__ == '__main__':
for i in args: for i in args:
m.load_flows(i) m.load_flows(i)
m.run() m.run()