Skip to content

Commit 7932098

Browse files
committed
Add an RLock around the Locale cache.
Refs #31 (#31)
1 parent c3a5d38 commit 7932098

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

babel/_memoized.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,27 @@ class Memoized(type):
1010
def __new__(mcs, name, bases, dict):
1111
if "_cache" not in dict:
1212
dict["_cache"] = {}
13+
if "_cache_lock" not in dict:
14+
dict["_cache_lock"] = None
1315
return type.__new__(mcs, name, bases, dict)
1416

1517
def __memoized_init__(cls, *args, **kwargs):
18+
lock = cls._cache_lock
1619
if hasattr(cls, "_get_memo_key"):
1720
key = cls._get_memo_key(args, kwargs)
1821
else:
1922
key = (args or None, frozenset(kwargs.items()) or None)
20-
if key not in cls._cache:
21-
cls._cache[key] = type.__call__(cls, *args, **kwargs)
22-
return cls._cache[key]
23+
24+
try:
25+
return cls._cache[key]
26+
except KeyError:
27+
try:
28+
if lock:
29+
lock.acquire()
30+
inst = cls._cache[key] = type.__call__(cls, *args, **kwargs)
31+
return inst
32+
finally:
33+
if lock:
34+
lock.release()
2335

2436
__call__ = __memoized_init__ # This aliasing makes tracebacks more understandable.

babel/core.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
:copyright: (c) 2013 by the Babel Team.
99
:license: BSD, see LICENSE for more details.
1010
"""
11-
1211
import os
12+
import threading
1313

1414
from babel import localedata
1515
from babel._compat import pickle, string_types, with_metaclass
@@ -125,6 +125,9 @@ class Locale(with_metaclass(Memoized)):
125125
#: The dictionary used by the locale cache metaclass.
126126
_cache = {}
127127

128+
#: The lock used for the cache metaclass.
129+
_cache_lock = threading.RLock()
130+
128131
@staticmethod
129132
def _get_memo_key(args, kwargs):
130133
# Getter for a cache key for the Memoized metaclass.

0 commit comments

Comments
 (0)