/offlineimap/head: changeset 474
- offlineimap (3.99.17) unstable; urgency=low - Fixed two potential obscure race conditions in folder/Maildir.py. + Condition 1 involved the gettimeseq() function. This function accesses per-module variables but does not have a lock. It may have been possible for this to have been called in such a way that timeseq was not properly updated. + Condition 2 involved the call to gettimeseq(). Since the timeseq is based on the system clock, we now use the time as reported inside timeseq() rather than outside. This way, we can be assured that the same value is in use both places. - Added debug code to savemessage in folder/Maildir.py to try to track down a mysterious 0-length file bug. -- John Goerzen <jgoerzen@complete.org> Tue, 6 May 2003 09:21:38 -0500
This commit is contained in:
parent
4ab1ebf4a8
commit
b36c52d5af
@ -1,3 +1,19 @@
|
|||||||
|
offlineimap (3.99.17) unstable; urgency=low
|
||||||
|
|
||||||
|
* Fixed two potential obscure race conditions in folder/Maildir.py.
|
||||||
|
+ Condition 1 involved the gettimeseq() function. This function
|
||||||
|
accesses per-module variables but does not have a lock. It may have
|
||||||
|
been possible for this to have been called in such a way that timeseq
|
||||||
|
was not properly updated.
|
||||||
|
+ Condition 2 involved the call to gettimeseq(). Since the timeseq is
|
||||||
|
based on the system clock, we now use the time as reported inside
|
||||||
|
timeseq() rather than outside. This way, we can be assured that the
|
||||||
|
same value is in use both places.
|
||||||
|
* Added debug code to savemessage in folder/Maildir.py to try to track
|
||||||
|
down a mysterious 0-length file bug.
|
||||||
|
|
||||||
|
-- John Goerzen <jgoerzen@complete.org> Tue, 6 May 2003 07:25:38 -0500
|
||||||
|
|
||||||
offlineimap (3.99.16) unstable; urgency=low
|
offlineimap (3.99.16) unstable; urgency=low
|
||||||
|
|
||||||
* This is a 4.0 TRACK release, and may be unstable or in flux!
|
* This is a 4.0 TRACK release, and may be unstable or in flux!
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
from Base import BaseFolder
|
from Base import BaseFolder
|
||||||
from offlineimap import imaputil
|
from offlineimap import imaputil
|
||||||
|
from offlineimap.ui import UIBase
|
||||||
|
from threading import Lock
|
||||||
import os.path, os, re, time, socket, md5
|
import os.path, os, re, time, socket, md5
|
||||||
|
|
||||||
foldermatchre = re.compile(',FMD5=([0-9a-f]{32})')
|
foldermatchre = re.compile(',FMD5=([0-9a-f]{32})')
|
||||||
@ -26,17 +28,22 @@ flagmatchre = re.compile(':.*2,([A-Z]+)')
|
|||||||
|
|
||||||
timeseq = 0
|
timeseq = 0
|
||||||
lasttime = long(0)
|
lasttime = long(0)
|
||||||
|
timelock = Lock()
|
||||||
|
|
||||||
def gettimeseq():
|
def gettimeseq():
|
||||||
global lasttime, timeseq
|
global lasttime, timeseq, timelock
|
||||||
thistime = long(time.time())
|
timelock.acquire()
|
||||||
if thistime == lasttime:
|
try:
|
||||||
timeseq += 1
|
thistime = long(time.time())
|
||||||
return timeseq
|
if thistime == lasttime:
|
||||||
else:
|
timeseq += 1
|
||||||
lasttime = long(time.time())
|
return (thistime, timeseq)
|
||||||
timeseq = 0
|
else:
|
||||||
return timeseq
|
lasttime = thistime
|
||||||
|
timeseq = 0
|
||||||
|
return (thistime, timeseq)
|
||||||
|
finally:
|
||||||
|
timelock.release()
|
||||||
|
|
||||||
class MaildirFolder(BaseFolder):
|
class MaildirFolder(BaseFolder):
|
||||||
def __init__(self, root, name, sep, repository, accountname):
|
def __init__(self, root, name, sep, repository, accountname):
|
||||||
@ -118,6 +125,9 @@ class MaildirFolder(BaseFolder):
|
|||||||
return retval.replace("\r\n", "\n")
|
return retval.replace("\r\n", "\n")
|
||||||
|
|
||||||
def savemessage(self, uid, content, flags):
|
def savemessage(self, uid, content, flags):
|
||||||
|
ui = UIBase.getglobalui()
|
||||||
|
ui.debug('maildir', 'savemessage: called to write with flags %s and content %s' % \
|
||||||
|
(repr(flags), repr(content)))
|
||||||
if uid < 0:
|
if uid < 0:
|
||||||
# We cannot assign a new uid.
|
# We cannot assign a new uid.
|
||||||
return uid
|
return uid
|
||||||
@ -137,9 +147,10 @@ class MaildirFolder(BaseFolder):
|
|||||||
while 1:
|
while 1:
|
||||||
if attempts > 15:
|
if attempts > 15:
|
||||||
raise IOError, "Couldn't write to file %s" % messagename
|
raise IOError, "Couldn't write to file %s" % messagename
|
||||||
|
timeval, timeseq = gettimeseq()
|
||||||
messagename = '%d_%d.%d.%s,U=%d,FMD5=%s' % \
|
messagename = '%d_%d.%d.%s,U=%d,FMD5=%s' % \
|
||||||
(long(time.time()),
|
(timeval,
|
||||||
gettimeseq(),
|
timeseq,
|
||||||
os.getpid(),
|
os.getpid(),
|
||||||
socket.gethostname(),
|
socket.gethostname(),
|
||||||
uid,
|
uid,
|
||||||
@ -150,15 +161,19 @@ class MaildirFolder(BaseFolder):
|
|||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
tmpmessagename = messagename.split(',')[0]
|
tmpmessagename = messagename.split(',')[0]
|
||||||
|
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||||
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
||||||
file.write(content)
|
file.write(content)
|
||||||
file.close()
|
file.close()
|
||||||
|
ui.debug('maildir', 'savemessage: moving from %s to %s' % \
|
||||||
|
(tmpmessagename, messagename))
|
||||||
os.link(os.path.join(tmpdir, tmpmessagename),
|
os.link(os.path.join(tmpdir, tmpmessagename),
|
||||||
os.path.join(newdir, messagename))
|
os.path.join(newdir, messagename))
|
||||||
os.unlink(os.path.join(tmpdir, tmpmessagename))
|
os.unlink(os.path.join(tmpdir, tmpmessagename))
|
||||||
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
||||||
'filename': os.path.join(newdir, messagename)}
|
'filename': os.path.join(newdir, messagename)}
|
||||||
self.savemessageflags(uid, flags)
|
self.savemessageflags(uid, flags)
|
||||||
|
ui.debug('maildir', 'savemessage: returning uid %d' % uid)
|
||||||
return uid
|
return uid
|
||||||
|
|
||||||
def getmessageflags(self, uid):
|
def getmessageflags(self, uid):
|
||||||
|
Loading…
Reference in New Issue
Block a user