[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server - dual_mode_channel.py:1.1.2.6

Shane Hathaway shane@digicool.com
Mon, 7 Jan 2002 10:33:56 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Server
In directory cvs.zope.org:/tmp/cvs-serv31746

Modified Files:
      Tag: Zope-3x-branch
	dual_mode_channel.py 
Log Message:
Provided a way to use alternate socket maps in dual_mode_channel, along with
support for alternate triggers.


=== Zope3/lib/python/Zope/Server/dual_mode_channel.py 1.1.2.5 => 1.1.2.6 ===
 import sys
 from time import time
+from UserDict import UserDict
 
 try:
     from cStringIO import StringIO
 except ImportError:
     from StringIO import StringIO
 
-from medusa.thread.select_trigger import trigger
+from medusa.thread import select_trigger
 from Adjustments import default_adj
 
 
-pull_trigger = trigger().pull_trigger
-
-
 # copy_bytes controls the size of temp. strings for shuffling data around.
 COPY_BYTES = 1 << 18  # 64K
 
@@ -31,7 +29,58 @@
 STRBUF_LIMIT = 8192
 
 
-class dual_mode_channel (asyncore.dispatcher):
+class AlternateSocketMapMixin:
+    """Mixin for asyncore.dispatcher to more easily support
+    alternate socket maps"""
+
+    socket_map = None
+
+    def add_channel(self, map=None):
+        if map is None:
+            map = self.socket_map
+        asyncore.dispatcher.add_channel(self, map)
+
+    def del_channel(self, map=None):
+        if map is None:
+            map = self.socket_map
+        asyncore.dispatcher.del_channel(self, map)
+
+    def pull_trigger(self):
+        pull_trigger = getattr(self.socket_map, 'pull_trigger', None)
+        if pull_trigger is not None:
+            # Use the trigger from the socket map.
+            pull_trigger()
+        else:
+            t = select_trigger.the_trigger
+            if t is None:
+                t = trigger()
+                select_trigger.the_trigger = t
+            t.pull_trigger()
+
+
+class ASMTrigger (AlternateSocketMapMixin, select_trigger.trigger):
+    """Trigger for an alternate socket map"""
+
+    def __init__(self, socket_map):
+        self.socket_map = socket_map
+        select_trigger.trigger.__init__(self)
+
+    pull_trigger = select_trigger.trigger.pull_trigger
+
+
+class SocketMapWithTrigger (UserDict):
+
+    trigger = None
+
+    def pull_trigger(self):
+        t = self.trigger
+        if t is None:
+            t = ASMTrigger(self)
+            self.trigger = t
+        t.pull_trigger()
+
+
+class dual_mode_channel (AlternateSocketMapMixin, asyncore.dispatcher):
     """
     The channel switches between asynchronous and synchronous mode.
     """
@@ -42,12 +91,13 @@
     # boolean: async or sync mode
     async_mode = 1
 
-    def __init__(self, server, conn, addr, adj=None):
+    def __init__(self, server, conn, addr, adj=None, socket_map=None):
         self.server = server
         self.addr = addr
         if adj is None:
             adj = default_adj
         self.adj = adj
+        self.socket_map = socket_map
         self.outbuf = OverflowableBuffer(adj.outbuf_overflow)
         self.creation_time = time()
         asyncore.dispatcher.__init__(self, conn)
@@ -149,7 +199,7 @@
 
     def set_async(self):
         self.async_mode = 1
-        pull_trigger()
+        self.pull_trigger()
 
     #
     # METHODS USED IN BOTH MODES
@@ -168,7 +218,7 @@
     def close_when_done(self):
         if self.async_mode:
             self.will_close = 1
-            pull_trigger()
+            self.pull_trigger()
         else:
             # We might be able close immediately.
             while self._flush_some():
@@ -180,7 +230,7 @@
                 # Wait until outbuf is flushed.
                 self.will_close = 1
                 self.async_mode = 1
-                pull_trigger()
+                self.pull_trigger()
 
 
 allocate_lock = None
@@ -193,7 +243,7 @@
     and fill the input buffer.
     """
 
-    def __init__(self, server, conn, addr, adj=None):
+    def __init__(self, server, conn, addr, adj=None, socket_map=None):
         global allocate_lock
         if allocate_lock is None:
             from thread import allocate_lock
@@ -202,7 +252,7 @@
         self._writelock_acquire = writelock.acquire
         self._writelock_release = writelock.release
         self._writelock_locked = writelock.locked
-        dual_mode_channel.__init__(self, server, conn, addr, adj)
+        dual_mode_channel.__init__(self, server, conn, addr, adj, socket_map)
 
     #
     # ASYNCHRONOUS METHODS
@@ -257,7 +307,7 @@
 
     def close_when_done(self):
         self.will_close = 1
-        pull_trigger()
+        self.pull_trigger()