[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()