Index: abstract.py
===================================================================
--- abstract.py	(revision 26336)
+++ abstract.py	(working copy)
@@ -91,40 +91,55 @@
                                   reflect.qual(self.__class__))
 
     def doWrite(self):
+        """Called when data can be written.
+        A result that is true (which will be a negative number) implies the
+        connection was lost. A false result implies the connection is still
+        there; a result of 0 implies no write was done, and a result of None
+        indicates that a write was done.
         """
-        Called when data can be written.
-
-        A result that is true (which will be a negative number or an
-        exception instance) indicates that the connection was lost. A false
-        result implies the connection is still there; a result of 0
-        indicates no write was done, and a result of None indicates that a
-        write was done.
-        """
-        if len(self.dataBuffer) - self.offset < self.SEND_LIMIT:
-            # If there is currently less than SEND_LIMIT bytes left to send
-            # in the string, extend it with the array data.
-            self.dataBuffer = buffer(self.dataBuffer, self.offset) + "".join(self._tempDataBuffer)
-            self.offset = 0
-            self._tempDataBuffer = []
-            self._tempDataLen = 0
-
-        # Send as much data as you can.
-        if self.offset:
-            l = self.writeSomeData(buffer(self.dataBuffer, self.offset))
-        else:
-            l = self.writeSomeData(self.dataBuffer)
-
-        # There is no writeSomeData implementation in Twisted which returns
-        # 0, but the documentation for writeSomeData used to claim negative
-        # integers meant connection lost.  Keep supporting this here,
-        # although it may be worth deprecating and removing at some point.
-        if l < 0 or isinstance(l, Exception):
-            return l
-        if l == 0 and self.dataBuffer:
-            result = 0
-        else:
-            result = None
-        self.offset += l
+        while 1:
+            # always try to do something
+            # quit when dataBuffer size is acceptably low (see end)
+            if len(self.dataBuffer) - self.offset < self.SEND_LIMIT:
+                # If there is currently less than SEND_LIMIT bytes left to send
+                # in the string, extend it with the array data.
+                buf = []
+                accum = len(self.dataBuffer)-self.offset
+                m = 2 * max(self.SEND_LIMIT, self.bufferSize)
+                chunk = None
+                while self._tempDataBuffer and accum < m:
+                    # don't want to join too much data at once
+                    chunk = self._tempDataBuffer.pop(0)
+                    buf.append(chunk)
+                    n = len(chunk)
+                    accum += n
+                    self._tempDataLen -= n
+                del chunk, accum, m
+                self.dataBuffer = (buffer(self.dataBuffer, self.offset) + "".join(buf))
+                del buf
+                self.offset = 0
+            # Send as much data as you can.
+            if self.offset:
+                l = self.writeSomeData(buffer(self.dataBuffer, self.offset))
+            else:
+                l = self.writeSomeData(self.dataBuffer)
+            # There is no writeSomeData implementation in Twisted which returns
+            # 0, but the documentation for writeSomeData used to claim negative
+            # integers meant connection lost.  Keep supporting this here,
+            # although it may be worth deprecating and removing at some point.
+            if l < 0 or isinstance(l, Exception):
+                return l
+            if l == 0 and self.dataBuffer:
+                # Couldn't send data
+                result = 0
+                break
+            else:
+                result = None
+            self.offset += l
+            if len(self.dataBuffer) - self.offset + self._tempDataLen < self.bufferSize:
+              # quit, 'cause dataBuffer AND _tempDataBuffer is small enough
+              break
+        #
         # If there is nothing left to send,
         if self.offset == len(self.dataBuffer) and not self._tempDataLen:
             self.dataBuffer = ""
