[Zope-CVS] CVS: Packages/tcpwatch - CHANGES.txt:1.5 tcpwatch.py:1.8

Shane Hathaway shane at zope.com
Tue Apr 6 12:28:45 EDT 2004


Update of /cvs-repository/Packages/tcpwatch
In directory cvs.zope.org:/tmp/cvs-serv22465

Modified Files:
	CHANGES.txt tcpwatch.py 
Log Message:
Made compatible with versions of tcl that have threads enabled.

Now the window loop runs in the main thread and asyncore runs in a
secondary thread.  (Until now, it was the other way around).  The two
threads pass messages using queues.


=== Packages/tcpwatch/CHANGES.txt 1.4 => 1.5 ===
--- Packages/tcpwatch/CHANGES.txt:1.4	Fri Apr  2 17:31:01 2004
+++ Packages/tcpwatch/CHANGES.txt	Tue Apr  6 12:28:44 2004
@@ -1,6 +1,8 @@
 
 Next release
 
+  - Made compatible with versions of tcl that have threads enabled.
+
   - Log file numbers are now sequential.
 
   - "user at host" is now accepted as a destination hostname.


=== Packages/tcpwatch/tcpwatch.py 1.7 => 1.8 ===
--- Packages/tcpwatch/tcpwatch.py:1.7	Fri Apr  2 17:31:01 2004
+++ Packages/tcpwatch/tcpwatch.py	Tue Apr  6 12:28:44 2004
@@ -474,8 +474,7 @@
 
     import Tkinter
     from ScrolledText import ScrolledText
-    from thread import start_new_thread
-    import asyncore
+    from Queue import Queue, Empty
     try:
         from cStringIO import StringIO
     except ImportError:
@@ -493,12 +492,14 @@
     class TkTCPWatch (Tkinter.Frame):
         '''The tcpwatch top-level window.
         '''
-        def __init__(self, master=None):
+        def __init__(self, master):
             Tkinter.Frame.__init__(self, master)
             self.createWidgets()
             # connections maps ids to TkConnectionObservers.
             self.connections = {}
             self.showingid = ''
+            self.queue = Queue()
+            self.processQueue()
 
         def createWidgets(self):
             listframe = Tkinter.Frame(self)
@@ -547,6 +548,20 @@
                     self.textbox.insert(Tkinter.END, data, style)
                 self.showingid = sel
 
+        def processQueue(self):
+            try:
+                if not self.queue.empty():
+                    # Process messages for up to 1/4 second
+                    from time import time
+                    limit = time() + 0.25
+                    while time() < limit:
+                        try:
+                            f, args = self.queue.get_nowait()
+                        except Empty:
+                            break
+                        f(*args)
+            finally:
+                self.master.after(50, self.processQueue)
 
 
     class TkConnectionObserver (BasicObserver):
@@ -568,13 +583,14 @@
                 base_id = '%03d' % fci.connection_number
             id = '%s (%02d:%02d:%02d)' % (base_id, t[3], t[4], t[5])
             self._id = id
-            frame.addConnection(id, self)
+            frame.queue.put((frame.addConnection, (id, self)))
             self.connection_from(fci)
 
         def write(self, s):
-            output = (s, "message")
-            self._output.append(output)
-            self._frame.updateConnection(self._id, [output])
+            output = [(s, "message")]
+            self._output.extend(output)
+            self._frame.queue.put(
+                (self._frame.updateConnection, (self._id, output)))
 
         def flush(self):
             pass
@@ -633,7 +649,8 @@
 
             # Send output to the frame.
             self._output.extend(output)
-            self._frame.updateConnection(self._id, output)
+            self._frame.queue.put(
+                (self._frame.updateConnection, (self._id, output)))
             if data.endswith('\n'):
                 self.continuing_line = -1
             else:
@@ -643,9 +660,9 @@
             return self._output
 
 
-
     def createApp(titlepart):
-        app = TkTCPWatch()
+        master = Tkinter.Tk()
+        app = TkTCPWatch(master)
         try:
             wm_title = app.master.wm_title
         except AttributeError:
@@ -659,12 +676,7 @@
     def tkObserverFactory(fci, app=app, colorized=colorized):
         return TkConnectionObserver(app, fci, colorized)
 
-    def window_loop(app):
-        app.mainloop()
-        asyncore.close_all()
-
-    start_new_thread(window_loop, (app,))
-    return tkObserverFactory
+    return tkObserverFactory, app.mainloop
 
 
 
@@ -1408,10 +1420,11 @@
             'Recording to directory %s.' % record_directory)
     config_info = '\n'.join(config_info_lines)
     titlepart = ', '.join(title_lst)
+    mainloop = None
 
     if obs_factory is None:
         # If no observer factory has been specified, use Tkinter.
-        obs_factory = setupTk(titlepart, config_info, colorized)
+        obs_factory, mainloop = setupTk(titlepart, config_info, colorized)
 
     if record_directory:
         def _decorateRecorder(fci, sub_factory=obs_factory,
@@ -1455,7 +1468,12 @@
 
         # Run the main loop.
         try:
-            asyncore.loop(timeout=1.0)
+            if mainloop is not None:
+                import thread
+                thread.start_new_thread(asyncore.loop, (), {'timeout': 1.0})
+                mainloop()
+            else:
+                asyncore.loop(timeout=1.0)
         except KeyboardInterrupt:
             sys.stderr.write('TCPWatch finished.\n')
     finally:
@@ -1465,4 +1483,3 @@
 
 if __name__ == '__main__':
     main(sys.argv[1:])
-




More information about the Zope-CVS mailing list