summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a335a01)
raw | patch | inline | side by side (parent: a335a01)
author | stefan <stefan@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Fri, 9 Oct 2009 14:00:50 +0000 (14:00 +0000) | ||
committer | stefan <stefan@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Fri, 9 Oct 2009 14:00:50 +0000 (14:00 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4372 57a73879-2fb5-44c3-a270-3262357dd7e2
roundup/cgi/templating.py | patch | blob | history |
index 797cd1370622ee3c900d8cf6d87c80cc1b429e11..b46f9d61b356b35e47a9858f103f15c0abb82d80 100644 (file)
return self.templates[src]
# compile the template
- self.templates[src] = pt = RoundupPageTemplate()
+ pt = RoundupPageTemplate()
# use pt_edit so we can pass the content_type guess too
content_type = mimetypes.guess_type(filename)[0] or 'text/html'
pt.pt_edit(open(src).read(), content_type)
pt.id = filename
pt.mtime = stime
+ # Add it to the cache. We cannot do this until the template
+ # is fully initialized, as we could otherwise have a race
+ # condition when running with multiple threads:
+ #
+ # 1. Thread A notices the template is not in the cache,
+ # adds it, but has not yet set "mtime".
+ #
+ # 2. Thread B notices the template is in the cache, checks
+ # "mtime" (above) and crashes.
+ #
+ # Since Python dictionary access is atomic, as long as we
+ # insert "pt" only after it is fully initialized, we avoid
+ # this race condition. It's possible that two separate
+ # threads will both do the work of initializing the template,
+ # but the risk of wasted work is offset by avoiding a lock.
+ self.templates[src] = pt
return pt
def __getitem__(self, name):