Complete.Org: Mailing Lists: Archives: offlineimap: March 2008:
Re: [OfflineIMAP] #20: Memory leak on Mac OS X ?
Home

Re: [OfflineIMAP] #20: Memory leak on Mac OS X ?

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: John Goerzen <jgoerzen@xxxxxxxxxxxx>
Cc: offlineimap@xxxxxxxxxxxx
Subject: Re: [OfflineIMAP] #20: Memory leak on Mac OS X ?
From: Vincent Beffara <vbeffara+ml@xxxxxxxxx>
Date: Sat, 22 Mar 2008 12:30:42 +0100

Hi,

> > [Well, this answers my yet-unasked question, the solution is to still 
> > install the python 2.5 in Fink to get the patch.]
> 
> OK.  I'll keep the bug open, and I've noted this in it.

In the meantime I did finally build a temporary patch that fixes the 
crash on Darwin, at least in my case. I am attaching the patch file to 
this e-mail. It feels a little bit dirty, esp. the arbitrary choice of 
the chunk size, and it is not really efficient I guess, so I still 
wouldn't include it into mainline Fink (except as a system-specific hack 
with a Python version test maybe).

Anyway, I am attaching it to the Fink package, so it will be 
non-crashing there at least; I will then pull the patch whenever Python 
itself is fixed.

Cheers,

  /vincent

-- 
Vincent Beffara
UMPA - ENS Lyon
46 Allée d'Italie
69364 LYON cedex 07
Tel: 04 72 72 85 25
Fax: 04 72 72 84 80

-- Attached file included as plaintext by Ecartis --

diff --git a/offlineimap/imapserver.py b/offlineimap/imapserver.py
index 4e37ece..ac39b77 100644
--- a/offlineimap/imapserver.py
+++ b/offlineimap/imapserver.py
@@ -23,6 +23,8 @@ from threading import *
 import thread, hmac, os
 import base64
 
+from StringIO import StringIO
+
 try:
     # do we have a recent pykerberos?
     have_gss = False
@@ -60,10 +62,38 @@ class UsefulIMAP4(UsefulIMAPMixIn, imaplib.IMAP4):
     def open(self, host = '', port = imaplib.IMAP4_PORT):
         imaplibutil.new_open(self, host, port)
 
+    # This is a hack to go around Darwin's implementation of
+    # realloc(), which Python uses inside the socket class. If a message
+    # is larger than 1M, we get it piece by piece instead of all at
+    # once.
+
+    def read(self, size):
+        read = 0
+        io = StringIO()
+        while read < size:
+            tmp = size-read
+            if (tmp>1000000): tmp=1000000
+            data = self.file.read(tmp)
+            read += len(data)
+            io.write(data)
+        return io.getvalue()
+
 class UsefulIMAP4_SSL(UsefulIMAPMixIn, imaplibutil.WrappedIMAP4_SSL):
     def open(self, host = '', port = imaplib.IMAP4_SSL_PORT):
         imaplibutil.new_open_ssl(self, host, port)
 
+    # This is the same thing as above, except we can be a little bit
+    # more clever by avoiding the socket class altogether.
+
+    def read(self, size):
+        read = 0
+        io = StringIO()
+        while read < size:
+            data = self.sslobj.read(size-read)
+            read += len(data)
+            io.write(data)
+        return io.getvalue()
+
 class UsefulIMAP4_Tunnel(UsefulIMAPMixIn, imaplibutil.IMAP4_Tunnel): pass
 
 class IMAPServer:




[Prev in Thread] Current Thread [Next in Thread]