- CFG_ATOMIC flag is introduced: indicates that the variable can
authorMiklos Tirpak <miklos@iptel.org>
Thu, 21 Feb 2008 11:09:23 +0000 (11:09 +0000)
committerMiklos Tirpak <miklos@iptel.org>
Thu, 21 Feb 2008 11:09:23 +0000 (11:09 +0000)
be changed at any time, there is no need to wait for the SIP
message processing to finish

- debug config parameter is changed to CFG_ATOMIC type

cfg/cfg.c
cfg/cfg.h
cfg/cfg_ctx.c
cfg_core.c
doc/cfg.txt

index 4e7a132..c52323c 100644 (file)
--- a/cfg/cfg.c
+++ b/cfg/cfg.c
@@ -111,6 +111,21 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
                                        group_name, def[i].name);
                        goto error;
                }
+
+               if (def[i].type & CFG_ATOMIC) {
+                       if (CFG_VAR_MASK(def[i].type) != CFG_VAR_INT) {
+                               LOG(L_ERR, "ERROR: register_cfg_def(): %s.%s: atomic change is allowed "
+                                               "only for integer types\n",
+                                               group_name, def[i].name);
+                               goto error;
+                       }
+                       if (def[i].on_set_child_cb) {
+                               LOG(L_ERR, "ERROR: register_cfg_def(): %s.%s: per-child process callback "
+                                               "does not work together with atomic change\n",
+                                               group_name, def[i].name);
+                               goto error;
+                       }
+               }
        }
 
        /* minor validation */
index 65d96d5..a1be857 100644 (file)
--- a/cfg/cfg.h
+++ b/cfg/cfg.h
 
 #include "../str.h"
 
+/* variable type */
 #define CFG_VAR_INT            1U
 #define CFG_VAR_STRING         2U
 #define CFG_VAR_STR            3U
 #define CFG_VAR_POINTER                4U
 
+/* number of bits required for the variable type */
 #define CFG_INPUT_SHIFT                3
 
+/* input type */
 #define CFG_INPUT_INT          (CFG_VAR_INT << CFG_INPUT_SHIFT)
 #define CFG_INPUT_STRING       (CFG_VAR_STRING << CFG_INPUT_SHIFT)
 #define CFG_INPUT_STR          (CFG_VAR_STR << CFG_INPUT_SHIFT)
 
-#define CFG_VAR_MASK(x)                ((x)&(CFG_INPUT_INT-1))
-#define CFG_INPUT_MASK(x)      ((x)&(~(CFG_INPUT_INT-1)))
+#define CFG_VAR_MASK(x)                ((x)&((1U<<CFG_INPUT_SHIFT)-1))
+#define CFG_INPUT_MASK(x)      ((x)&((1U<<(2*CFG_INPUT_SHIFT))-(1U<<CFG_INPUT_SHIFT)))
+
+/* atomic change is allowed */
+#define CFG_ATOMIC             (1U<<(2*CFG_INPUT_SHIFT))
 
 typedef int (*cfg_on_change)(void *, str *, void **);
 typedef void (*cfg_on_set_child)(str *);
index b4443a5..f170fd1 100644 (file)
@@ -320,10 +320,17 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
                while the new one is prepared */
                CFG_WRITER_LOCK();
 
-               /* clone the memory block, and prepare the modification */
-               if (!(block = cfg_clone_global())) goto error;
+               if (var->def->type & CFG_ATOMIC) {
+                       /* atomic change is allowed, we can rewrite the value
+                       directly in the global config */
+                       p = (*cfg_global)->vars+group->offset+var->offset;
 
-               p = block->vars+group->offset+var->offset;
+               } else {
+                       /* clone the memory block, and prepare the modification */
+                       if (!(block = cfg_clone_global())) goto error;
+
+                       p = block->vars+group->offset+var->offset;
+               }
        } else {
                /* we are allowed to rewrite the value on-the-fly
                The handle either points to group->vars, or to the
@@ -373,7 +380,7 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
                        replaced[1] = NULL;
                }
                /* replace the global config with the new one */
-               cfg_install_global(block, replaced, child_cb, child_cb);
+               if (block) cfg_install_global(block, replaced, child_cb, child_cb);
                CFG_WRITER_UNLOCK();
        } else {
                /* cfg_set() may be called more than once before forking */
index 72e68ea..cb066d9 100644 (file)
@@ -82,7 +82,7 @@ struct cfg_group_core default_core_cfg = {
 void   *core_cfg = &default_core_cfg;
 
 cfg_def_t core_cfg_def[] = {
-       {"debug",       CFG_VAR_INT,    0, 0, 0, 0, "debug level"},
+       {"debug",       CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, "debug level"},
 #ifdef USE_DST_BLACKLIST
        /* blacklist */
        {"use_dst_blacklist",   CFG_VAR_INT,    0, 1, use_dst_blacklist_fixup, 0,
index a5e45ec..c4da4be 100644 (file)
@@ -96,7 +96,7 @@ Each row consists of the following items:
 
 - name that will be used by the drivers to refer to the variable
 - flag indicating the variable and the input type, that is accepted
-  by the fixup function
+  by the fixup function, and additional optional settings
 
   Valid variable types are:
        - CFG_VAR_INT           = int
@@ -109,6 +109,14 @@ Each row consists of the following items:
        - CFG_INPUT_STRING      = char*
        - CFG_INPUT_STR         = str*
 
+  Optional settings:
+       - CFG_ATOMIC            Indicates that atomic change is allowed:
+                               the variable can be changed at any time,
+                               there is no need to wait for the SIP
+                               message processing to finish.
+                               It can be used only with CFG_VAR_INT type,
+                               and per-child process callback is not allowed
+
 - minimum value for integers (optional)
 - maximum value for integers (optional)
 - fixup function (optional) that is called when the variable is going to be