Author: tack
Date: Mon Jan 21 10:41:07 2008
New Revision: 3002

Log:
Fix Socket to deal with exception changes.  It now also will call
set_as_mainthread() if mainthread is not running in order to initialize
notifier pipe: this fixes a bug when Socket was being insantiated before
main.run()


Modified:
   trunk/base/src/notifier/async.py
   trunk/base/src/notifier/sockets.py
   trunk/base/src/notifier/thread.py

Modified: trunk/base/src/notifier/async.py
==============================================================================
--- trunk/base/src/notifier/async.py    (original)
+++ trunk/base/src/notifier/async.py    Mon Jan 21 10:41:07 2008
@@ -153,6 +153,8 @@
         done because it raised an exception.
         """
         if self.exception.count() == 0:
+            # FIXME: we must still log the exception if we have an internal
+            # handler but no external handler.  In this case count() > 0.
             # There is no handler, so dump the exception.
             trace = ''.join(traceback.format_exception(type, value, tb))
             log.error('*** Unhandled InProgress exception ***\n%s', trace)

Modified: trunk/base/src/notifier/sockets.py
==============================================================================
--- trunk/base/src/notifier/sockets.py  (original)
+++ trunk/base/src/notifier/sockets.py  Mon Jan 21 10:41:07 2008
@@ -37,8 +37,10 @@
 import logging
 
 import nf_wrapper as notifier
+import main
+from jobserver import execute_in_thread
 from callback import Callback, Signal
-from thread import MainThreadCallback, ThreadCallback, is_mainthread
+from thread import MainThreadCallback, ThreadCallback, is_mainthread, 
set_as_mainthread
 
 # get logging object
 log = logging.getLogger('notifier')
@@ -156,7 +158,7 @@
 
 
 
-    def connect(self, addr, async = False):
+    def connect(self, addr, async = None):
         """
         Connects to the host specified in addr.  If addr is a string in the
         form host:port, or a tuple the form (host, port), a TCP socket is
@@ -164,9 +166,10 @@
         treated as a filename.
 
         If async is not None, it is a callback that will be invoked when the
-        connection has been established.  This callback takes one parameter,
-        which is True if the connection was established successfully, or an
-        Exception object otherwise.
+        connection has been established.  This callback takes one or three 
+        parameters: if the connection was successful, the first parameter is
+        True; otherwise there was an exception, and the three parameters are
+        type, value, and traceback of the exception.
 
         If async is None, this call will block until either connected or an
         exception is raised.  Although this call blocks, the notifier loop
@@ -174,31 +177,32 @@
         """
         self._make_socket(addr)
 
+        if async is not None and not callable(async):
+            raise ValueError, 'async argument must be callable'
 
-        in_progress = ThreadCallback(self._connect_thread)()
-        result_holder = []
-        if not async:
-            cb = Callback(lambda res, x: x.append(res), result_holder)
-        else:
-            cb = self.signals["connected"].emit
-
-
-        # XXX FIXME: exception handling is wrong
-        # XXX At will call self.signals["connected"] with three arguments
-        # XXX or crash with result_holder
+        in_progress = self._connect_thread()
 
-        in_progress.connect_both(cb, cb)
-
-        if async != None:
+        if async:
+            in_progress.connect_both(async, async)
             return
+        elif not main.is_running():
+            # No main loop is running yet.  We're calling step() below,
+            # but we won't get notified of the connect thread completion
+            # unless the thread notifier pipe is initialized.
+            set_as_mainthread()
+
+        # Connect a dummy handler to exception to prevent it from being
+        # logged.  We will reraise it after.
+        in_progress.exception.connect(lambda *args: None)
 
-        while len(result_holder) == 0:
-            notifier.step()
+        while not in_progress.is_finished():
+            main.step()
 
-        if isinstance(result_holder[0], (Exception, socket.error)):
-            raise result_holder[0]
+        # Any exception that occurred in the thread will get raised here:
+        return in_progress.get_result()
 
 
+    @execute_in_thread()
     def _connect_thread(self):
         if type(self._addr) == str:
             # Unix socket, just connect.
@@ -214,7 +218,6 @@
         return True
 
 
-
     def wrap(self, sock = None, addr = None):
         if sock:
             self._socket = sock
@@ -272,7 +275,7 @@
 
     def write(self, data):
         self._write_buffer += data
-        if self._socket and not self._wmon.active():
+        if self._socket and self._wmon and not self._wmon.active():
             self._wmon.register(self._socket, IO_WRITE)
 
     def _handle_write(self):

Modified: trunk/base/src/notifier/thread.py
==============================================================================
--- trunk/base/src/notifier/thread.py   (original)
+++ trunk/base/src/notifier/thread.py   Mon Jan 21 10:41:07 2008
@@ -145,7 +145,7 @@
             return None
         try:
             MainThreadCallback(self.finished, self._callback())()
-        except Exception, e:
+        except:
             MainThreadCallback(self.throw, *sys.exc_info())()
         self._callback = None
 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to