Wrap all config writers in write_config_wait
authorJack Miller <jack@codezen.org>
Tue, 21 Jul 2015 15:58:49 +0000 (10:58 -0500)
committerJack Miller <jack@codezen.org>
Tue, 21 Jul 2015 16:09:15 +0000 (11:09 -0500)
This resolves the case in which a config_lock write holder calls
prot_config separately and the config_lock.release at the end of
prot_config doesn't actually full unlock config_lock. Now everything in
config.py that hold write will wait for completion.

canto_curses/config.py

index 7129458..324ecc7 100644 (file)
@@ -70,6 +70,16 @@ story_needed_attrs = [ "title" ]
 
 CURRENT_CONFIG_VERSION = 1
 
+def write_config_wait(fn):
+    def _wcw(self, *args, **kwargs):
+        config_lock.acquire_write()
+        try:
+            return fn(self, *args, **kwargs)
+        finally:
+            if config_lock.release_write():
+                self.clear_wait()
+    return _wcw
+
 class CantoCursesConfig(SubThread):
 
     # The object init just sets up the default settings, doesn't
@@ -823,7 +833,7 @@ class CantoCursesConfig(SubThread):
     # We use strtags to validate tag order, and also to populate the
     # TagUpdater()
 
-    @write_lock(config_lock)
+    @write_config_wait
     def prot_listtags(self, tags):
         self.vars["strtags"] = tags
         self.config["tagorder"] = tags
@@ -853,12 +863,11 @@ class CantoCursesConfig(SubThread):
     # Note that changes are the only ones propagated through hooks because they
     # are a superset of deletions (i.e. a deletion counts as a change).
 
+    @write_config_wait
     def prot_configs(self, given, write = False):
         log.debug("prot_configs given:\n%s\n", json.dumps(given, indent=4, sort_keys=True))
         changes = {}
 
-        config_lock.acquire_write()
-
         if "tags" in given:
             for tag in list(given["tags"].keys()):
                 ntc = given["tags"][tag]
@@ -940,13 +949,9 @@ class CantoCursesConfig(SubThread):
 
         self.initd = True
 
-        config_lock.release_write()
-
-        self.clear_wait()
-
     # Process new tags.
 
-    @write_lock(config_lock)
+    @write_config_wait
     def prot_newtags(self, tags):
 
         if not self.initd:
@@ -994,7 +999,7 @@ class CantoCursesConfig(SubThread):
 
         self.eval_tags()
 
-    @write_lock(config_lock)
+    @write_config_wait
     def prot_deltags(self, tags):
         if not self.initd:
             for tag in tags:
@@ -1021,7 +1026,7 @@ class CantoCursesConfig(SubThread):
         if changes:
             self.set_conf(c)
 
-    @write_lock(config_lock)
+    @write_config_wait
     def eval_tags(self):
         prevtags = self.vars["curtags"]
 
@@ -1115,7 +1120,7 @@ class CantoCursesConfig(SubThread):
                 return eval(repr(f), {}, {})
         return None
 
-    @write_lock(config_lock)
+    @write_config_wait
     def set_opt(self, option, value):
         c = self.get_conf()
         assign_to_dict(c, option, value)
@@ -1129,7 +1134,7 @@ class CantoCursesConfig(SubThread):
             return None
         return value
 
-    @write_lock(config_lock)
+    @write_config_wait
     def set_tag_opt(self, tag, option, value):
         tc = self.get_tag_conf(tag)
         assign_to_dict(tc, option, value)
@@ -1143,7 +1148,7 @@ class CantoCursesConfig(SubThread):
             return None
         return value
 
-    @write_lock(config_lock)
+    @write_config_wait
     def switch_tags(self, tag1, tag2):
         c = self.get_conf()