changeset 827:58c1a0dfbcfc

Fixed runtime shutdown. The runtime will now shutdown correctly by closing the listening port and the pair-wise connections before calling reactor.stop().
author Martin Geisler <mg@daimi.au.dk>
date Sun, 13 Jul 2008 16:28:15 +0200
parents 420569d71d4d
children fe3bcd629827
files viff/runtime.py
diffstat 1 files changed, 20 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/viff/runtime.py	Sun Jul 13 15:21:40 2008 +0200
+++ b/viff/runtime.py	Sun Jul 13 16:28:15 2008 +0200
@@ -47,6 +47,7 @@
 from twisted.internet import reactor
 from twisted.internet.error import ConnectionDone
 from twisted.internet.defer import Deferred, DeferredList, gatherResults, succeed
+from twisted.internet.defer import maybeDeferred
 from twisted.internet.protocol import ClientFactory, ServerFactory
 from twisted.protocols.basic import Int16StringReceiver
 
@@ -251,7 +252,7 @@
 
     def __init__(self):
         self.peer_id = None
-
+        self.lost_connection = Deferred()
         #: Data expected to be received in the future.
         self.incoming_data = {}
 
@@ -260,6 +261,7 @@
 
     def connectionLost(self, reason):
         reason.trap(ConnectionDone)
+        self.lost_connection.callback(self)
 
     def stringReceived(self, string):
         """Called when a share is received.
@@ -497,15 +499,27 @@
         All connections are closed and the runtime cannot be used
         again after this has been called.
         """
+        print "Synchronizing shutdown... ",
 
-        def stop(_):
-            print "Initiating shutdown sequence."
+        def close_connections(_):
+            print "done."
+            print "Closing connections... ",
+            results = [maybeDeferred(self.port.stopListening)]
             for protocol in self.protocols.itervalues():
+                results.append(protocol.lost_connection)
                 protocol.loseConnection()
+            return DeferredList(results)
+
+        def stop_reactor(_):
+            print "done."
+            print "Stopping reactor... ",
             reactor.stop()
+            print "done."
 
         sync = self.synchronize()
-        sync.addCallback(stop)
+        sync.addCallback(close_connections) 
+        sync.addCallback(stop_reactor)
+        return sync
 
     def wait_for(self, *vars):
         """Make the runtime wait for the variables given.
@@ -1522,10 +1536,10 @@
                 return self.ctx
 
         ctx_factory = SSLContextFactory(id)
-        reactor.listenSSL(players[id].port, factory, ctx_factory)
+        runtime.port = reactor.listenSSL(players[id].port, factory, ctx_factory)
     else:
         print "Not using SSL"
-        reactor.listenTCP(players[id].port, factory)
+        runtime.port = reactor.listenTCP(players[id].port, factory)
 
     for peer_id, player in players.iteritems():
         if peer_id > id: