Sfoglia il codice sorgente

- CFG_ATOMIC flag is introduced: indicates that the variable can
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

Miklos Tirpak 17 anni fa
parent
commit
0d96457be7
5 ha cambiato i file con 44 aggiunte e 8 eliminazioni
  1. 15 0
      cfg/cfg.c
  2. 8 2
      cfg/cfg.h
  3. 11 4
      cfg/cfg_ctx.c
  4. 1 1
      cfg_core.c
  5. 9 1
      doc/cfg.txt

+ 15 - 0
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 */

+ 8 - 2
cfg/cfg.h

@@ -34,19 +34,25 @@
 
 #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 *);

+ 11 - 4
cfg/cfg_ctx.c

@@ -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 */

+ 1 - 1
cfg_core.c

@@ -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,

+ 9 - 1
doc/cfg.txt

@@ -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