you will probably want to use the getmod() function in this module.
"""
-import os, threading, types
+import os, threading, types, importlib
from . import wsgiutil
__all__ = ["application", "wmain", "getmod", "cachedmod"]
Additional data attributes can be arbitrarily added for recording
any meta-data about the module.
"""
- def __init__(self, mod, mtime):
+ def __init__(self, mod = None, mtime = -1):
self.lock = threading.Lock()
self.mod = mod
self.mtime = mtime
about the module. See its documentation for details.
"""
sb = os.stat(path)
- cachelock.acquire()
- try:
+ with cachelock:
if path in modcache:
entry = modcache[path]
- if sb.st_mtime <= entry.mtime:
- return entry
-
- f = open(path)
- try:
- text = f.read()
- finally:
- f.close()
- code = compile(text, path, "exec")
- mod = types.ModuleType(mangle(path))
- mod.__file__ = path
- exec(code, mod.__dict__)
- entry = cachedmod(mod, sb.st_mtime)
- modcache[path] = entry
+ else:
+ entry = cachedmod()
+ modcache[path] = entry
+ with entry.lock:
+ if entry.mod is None or sb.st_mtime > entry.mtime:
+ with open(path, "rb") as f:
+ text = f.read()
+ code = compile(text, path, "exec")
+ mod = types.ModuleType(mangle(path))
+ mod.__file__ = path
+ exec(code, mod.__dict__)
+ entry.mod = mod
+ entry.mtime = sb.st_mtime
return entry
- finally:
- cachelock.release()
def chain(env, startreq):
path = env["SCRIPT_FILENAME"]
mod = getmod(path)
entry = None
if mod is not None:
- mod.lock.acquire()
- try:
+ with mod.lock:
if hasattr(mod, "entry"):
entry = mod.entry
else:
elif hasattr(mod.mod, "application"):
entry = mod.mod.application
mod.entry = entry
- finally:
- mod.lock.release()
if entry is not None:
return entry(env, startreq)
return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "Invalid WSGI handler.")