python: Ensure greater concurrency is wsgidir.
authorFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 Dec 2011 04:46:31 +0000 (05:46 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 Dec 2011 04:52:53 +0000 (05:52 +0100)
python/ashd/wsgidir.py
python3/ashd/wsgidir.py

index 8b473f2..991b9f6 100644 (file)
@@ -55,7 +55,7 @@ class cachedmod(object):
     Additional data attributes can be arbitrarily added for recording
     any meta-data about the module.
     """
     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
         self.lock = threading.Lock()
         self.mod = mod
         self.mtime = mtime
@@ -91,23 +91,28 @@ def getmod(path):
     try:
         if path in modcache:
             entry = modcache[path]
     try:
         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 in mod.__dict__
-        entry = cachedmod(mod, sb.st_mtime)
-        modcache[path] = entry
-        return entry
+        else:
+            entry = cachedmod()
+            modcache[path] = entry
     finally:
         cachelock.release()
     finally:
         cachelock.release()
+    entry.lock.acquire()
+    try:
+        if entry.mod is None or sb.st_mtime > entry.mtime:
+            f = open(path, "r")
+            try:
+                text = f.read()
+            finally:
+                f.close()
+            code = compile(text, path, "exec")
+            mod = types.ModuleType(mangle(path))
+            mod.__file__ = path
+            exec code in mod.__dict__
+            entry.mod = mod
+            entry.mtime = sb.st_mtime
+        return entry
+    finally:
+        entry.lock.release()
 
 def chain(env, startreq):
     path = env["SCRIPT_FILENAME"]
 
 def chain(env, startreq):
     path = env["SCRIPT_FILENAME"]
index d4289a7..031952b 100644 (file)
@@ -37,7 +37,7 @@ must, of course, be importable). When writing such handler functions,
 you will probably want to use the getmod() function in this module.
 """
 
 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"]
 from . import wsgiutil
 
 __all__ = ["application", "wmain", "getmod", "cachedmod"]
@@ -55,7 +55,7 @@ class cachedmod(object):
     Additional data attributes can be arbitrarily added for recording
     any meta-data about the module.
     """
     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
         self.lock = threading.Lock()
         self.mod = mod
         self.mtime = mtime
@@ -90,20 +90,19 @@ def getmod(path):
     with cachelock:
         if path in modcache:
             entry = modcache[path]
     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
 
 def chain(env, startreq):
         return entry
 
 def chain(env, startreq):