Browse code

- 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 authored on 21/02/2008 11:09:23
Showing 5 changed files
... ...
@@ -111,6 +111,21 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
111 111
 					group_name, def[i].name);
112 112
 			goto error;
113 113
 		}
114
+
115
+		if (def[i].type & CFG_ATOMIC) {
116
+			if (CFG_VAR_MASK(def[i].type) != CFG_VAR_INT) {
117
+				LOG(L_ERR, "ERROR: register_cfg_def(): %s.%s: atomic change is allowed "
118
+						"only for integer types\n",
119
+						group_name, def[i].name);
120
+				goto error;
121
+			}
122
+			if (def[i].on_set_child_cb) {
123
+				LOG(L_ERR, "ERROR: register_cfg_def(): %s.%s: per-child process callback "
124
+						"does not work together with atomic change\n",
125
+						group_name, def[i].name);
126
+				goto error;
127
+			}
128
+		}
114 129
 	}
115 130
 
116 131
 	/* minor validation */
... ...
@@ -34,19 +34,25 @@
34 34
 
35 35
 #include "../str.h"
36 36
 
37
+/* variable type */
37 38
 #define CFG_VAR_INT		1U
38 39
 #define CFG_VAR_STRING		2U
39 40
 #define CFG_VAR_STR		3U
40 41
 #define CFG_VAR_POINTER		4U
41 42
 
43
+/* number of bits required for the variable type */
42 44
 #define CFG_INPUT_SHIFT		3
43 45
 
46
+/* input type */
44 47
 #define CFG_INPUT_INT		(CFG_VAR_INT << CFG_INPUT_SHIFT)
45 48
 #define CFG_INPUT_STRING	(CFG_VAR_STRING << CFG_INPUT_SHIFT)
46 49
 #define CFG_INPUT_STR		(CFG_VAR_STR << CFG_INPUT_SHIFT)
47 50
 
48
-#define CFG_VAR_MASK(x)		((x)&(CFG_INPUT_INT-1))
49
-#define CFG_INPUT_MASK(x)	((x)&(~(CFG_INPUT_INT-1)))
51
+#define CFG_VAR_MASK(x)		((x)&((1U<<CFG_INPUT_SHIFT)-1))
52
+#define CFG_INPUT_MASK(x)	((x)&((1U<<(2*CFG_INPUT_SHIFT))-(1U<<CFG_INPUT_SHIFT)))
53
+
54
+/* atomic change is allowed */
55
+#define CFG_ATOMIC		(1U<<(2*CFG_INPUT_SHIFT))
50 56
 
51 57
 typedef int (*cfg_on_change)(void *, str *, void **);
52 58
 typedef void (*cfg_on_set_child)(str *);
... ...
@@ -320,10 +320,17 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
320 320
 		while the new one is prepared */
321 321
 		CFG_WRITER_LOCK();
322 322
 
323
-		/* clone the memory block, and prepare the modification */
324
-		if (!(block = cfg_clone_global())) goto error;
323
+		if (var->def->type & CFG_ATOMIC) {
324
+			/* atomic change is allowed, we can rewrite the value
325
+			directly in the global config */
326
+			p = (*cfg_global)->vars+group->offset+var->offset;
325 327
 
326
-		p = block->vars+group->offset+var->offset;
328
+		} else {
329
+			/* clone the memory block, and prepare the modification */
330
+			if (!(block = cfg_clone_global())) goto error;
331
+
332
+			p = block->vars+group->offset+var->offset;
333
+		}
327 334
 	} else {
328 335
 		/* we are allowed to rewrite the value on-the-fly
329 336
 		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,
373 380
 			replaced[1] = NULL;
374 381
 		}
375 382
 		/* replace the global config with the new one */
376
-		cfg_install_global(block, replaced, child_cb, child_cb);
383
+		if (block) cfg_install_global(block, replaced, child_cb, child_cb);
377 384
 		CFG_WRITER_UNLOCK();
378 385
 	} else {
379 386
 		/* cfg_set() may be called more than once before forking */
... ...
@@ -82,7 +82,7 @@ struct cfg_group_core default_core_cfg = {
82 82
 void	*core_cfg = &default_core_cfg;
83 83
 
84 84
 cfg_def_t core_cfg_def[] = {
85
-	{"debug",	CFG_VAR_INT,	0, 0, 0, 0, "debug level"},
85
+	{"debug",	CFG_VAR_INT|CFG_ATOMIC,	0, 0, 0, 0, "debug level"},
86 86
 #ifdef USE_DST_BLACKLIST
87 87
 	/* blacklist */
88 88
 	{"use_dst_blacklist",	CFG_VAR_INT,	0, 1, use_dst_blacklist_fixup, 0,
... ...
@@ -96,7 +96,7 @@ Each row consists of the following items:
96 96
 
97 97
 - name that will be used by the drivers to refer to the variable
98 98
 - flag indicating the variable and the input type, that is accepted
99
-  by the fixup function
99
+  by the fixup function, and additional optional settings
100 100
 
101 101
   Valid variable types are:
102 102
 	- CFG_VAR_INT		= int
... ...
@@ -109,6 +109,14 @@ Each row consists of the following items:
109 109
 	- CFG_INPUT_STRING	= char*
110 110
 	- CFG_INPUT_STR		= str*
111 111
 
112
+  Optional settings:
113
+	- CFG_ATOMIC		Indicates that atomic change is allowed:
114
+				the variable can be changed at any time,
115
+				there is no need to wait for the SIP
116
+				message processing to finish.
117
+				It can be used only with CFG_VAR_INT type,
118
+				and per-child process callback is not allowed
119
+
112 120
 - minimum value for integers (optional)
113 121
 - maximum value for integers (optional)
114 122
 - fixup function (optional) that is called when the variable is going to be