Module: sip-router
Branch: tirpi/cfg_framework_multivalue
Commit: 92f85d59c0bd582b396d09c509a78902c8ccffab
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=92f85d5…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Sep 28 11:44:29 2010 +0200
cfg framework: apply the additional variable list
The additional variable list which is linked to the groups
is applied when the config is shmized. During this process,
the array of group instances is created, the values are fixed-up,
the changes are applied to each instance, and the list is freed.
Any change after the config is shmized is directly made in the
memory block as opposed to using the list.
(The list is necessary at the beginning because not even shm_malloc
is available, and the number of group instances is not known.)
---
cfg/cfg_ctx.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
cfg/cfg_ctx.h | 7 ++
cfg/cfg_struct.c | 102 +++++++++++++++++++++++++++++++-
cfg/cfg_struct.h | 3 +
4 files changed, 286 insertions(+), 1 deletions(-)
Diff: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commitdiff;h=92f…
Module: sip-router
Branch: tirpi/cfg_framework_multivalue
Commit: eddc94d703afb2685ffd6162ddd29a4fef464c2d
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=eddc94d…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Mon Sep 27 16:03:13 2010 +0200
cfg framework: group instance support before forking
The new group instances, and their variables are stored
in a list which is linked to the group before the config is
shmized. After all the variables are known, this list can
be changed to memory blocks.
---
cfg/cfg_ctx.c | 14 +++---
cfg/cfg_struct.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
cfg/cfg_struct.h | 10 ++++
3 files changed, 150 insertions(+), 6 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index 5fa961d..e94d678 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -332,8 +332,8 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str *va
but an additional instance of a variable needs to be added to the group.
Add this instance to the linked list of variables, they
will be fixed later. */
- /* TODO */
- return -1;
+ return new_add_var(group_name, *group_id, var_name,
+ val, val_type);
}
/* look-up the group and the variable */
@@ -686,7 +686,7 @@ int cfg_set_delayed(cfg_ctx_t *ctx, str *group_name, unsigned int *group_id, str
&& var->def->on_set_child_cb
&& var->def->type & CFG_CB_ONLY_ONCE
) {
- LOG(L_ERR, "ERROR: cfg_set_now(): This variable does not support muliple values.\n");
+ LOG(L_ERR, "ERROR: cfg_set_delayed(): This variable does not support muliple values.\n");
goto error0;
}
@@ -1427,9 +1427,11 @@ int cfg_add_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
}
if (!cfg_shmized) {
- /* TODO: Add a new fake variable belonging to
- the additional group instance to the linked list. */
- return -1;
+ /* Add a new variable without any value to
+ the linked list of additional values. This variable
+ will force a new group instance to be created. */
+ return new_add_var(group_name, group_id, NULL /* var_name */,
+ NULL /* val */, 0 /* type */);
}
if (!(group = cfg_lookup_group(group_name->s, group_name->len))) {
diff --git a/cfg/cfg_struct.c b/cfg/cfg_struct.c
index d34ed06..aa4c005 100644
--- a/cfg/cfg_struct.c
+++ b/cfg/cfg_struct.c
@@ -56,6 +56,10 @@ cfg_child_cb_t **cfg_child_cb_first = NULL; /* first item of the per-child proce
cfg_child_cb_t **cfg_child_cb_last = NULL; /* last item of the above list */
cfg_child_cb_t *cfg_child_cb = NULL; /* pointer to the previously executed cb */
+
+/* forward declarations */
+static void del_add_var_list(cfg_group_t *group);
+
/* creates a new cfg group, and adds it to the linked list */
cfg_group_t *cfg_new_group(char *name, int name_len,
int num, cfg_mapping_t *mapping,
@@ -298,6 +302,8 @@ static void cfg_destory_groups(unsigned char *block)
pointers are just set to static variables */
if (mapping) pkg_free(mapping);
}
+ /* Delete the additional variable list */
+ del_add_var_list(group);
group2 = group->next;
pkg_free(group);
@@ -824,3 +830,129 @@ void cfg_child_cb_free(cfg_child_cb_t *child_cb_first)
shm_free(cb);
}
}
+
+/* Allocate memory for a new additional variable
+ * and link it to a configuration group.
+ * type==0 results in creating a new group instance with the default values.
+ * The group is created with CFG_GROUP_UNKNOWN type if it does not exist.
+ * Note: this function is usable only before the configuration is shmized.
+ */
+int new_add_var(str *group_name, unsigned int group_id, str *var_name,
+ void *val, unsigned int type)
+{
+ cfg_group_t *group;
+ cfg_add_var_t *add_var = NULL, **add_var_p;
+ int len;
+
+ LOG(L_DBG, "DEBUG: new_add_var(): declaring a new variable instance %.*s[%u].%.*s\n",
+ group_name->len, group_name->s,
+ group_id,
+ var_name->len, var_name->s);
+
+ if (cfg_shmized) {
+ LOG(L_ERR, "ERROR: new_add_var(): too late, the configuration has already been shmized\n");
+ goto error;
+ }
+
+ group = cfg_lookup_group(group_name->s, group_name->len);
+ if (!group) {
+ /* create a new group with NULL values, it will be filled in later */
+ group = cfg_new_group(group_name->s, group_name->len,
+ 0 /* num */, NULL /* mapping */,
+ NULL /* vars */, 0 /* size */, NULL /* handle */);
+
+ if (!group)
+ goto error;
+ /* It is not yet known whether the group will be static or dynamic */
+ group->dynamic = CFG_GROUP_UNKNOWN;
+ }
+
+ add_var = (cfg_add_var_t *)pkg_malloc(sizeof(cfg_add_var_t) +
+ (type ? (var_name->len - 1) : 0));
+ if (!add_var) {
+ LOG(L_ERR, "ERROR: new_add_var(): Not enough memory\n");
+ goto error;
+ }
+ memset(add_var, 0, sizeof(cfg_add_var_t) +
+ (type ? (var_name->len - 1) : 0));
+
+ add_var->group_id = group_id;
+ if (type) {
+ add_var->name_len = var_name->len;
+ memcpy(add_var->name, var_name->s, var_name->len);
+
+ switch (type) {
+ case CFG_VAR_INT:
+ add_var->val.i = (int)(long)val;
+ break;
+
+ case CFG_VAR_STR:
+ len = ((str *)val)->len;
+ add_var->val.s.s = (char *)pkg_malloc(sizeof(char) * len);
+ if (!add_var->val.s.s) {
+ LOG(L_ERR, "ERROR: new_add_var(): Not enough memory\n");
+ goto error;
+ }
+ add_var->val.s.len = len;
+ memcpy(add_var->val.s.s, ((str *)val)->s, len);
+ break;
+
+ case CFG_VAR_STRING:
+ len = strlen((char *)val);
+ add_var->val.ch = (char *)pkg_malloc(sizeof(char) * (len + 1));
+ if (!add_var->val.ch) {
+ LOG(L_ERR, "ERROR: new_add_var(): Not enough memory\n");
+ goto error;
+ }
+ memcpy(add_var->val.ch, (char *)val, len);
+ add_var->val.ch[len] = '\0';
+ break;
+
+ default:
+ LOG(L_ERR, "ERROR: new_add_var(): unsupported value type: %u\n",
+ type);
+ goto error;
+ }
+ add_var->type = type;
+ }
+
+ /* order the list by group_id, it will be easier to count the group instances */
+ for( add_var_p = &group->add_var;
+ *add_var_p && ((*add_var_p)->group_id < group_id);
+ add_var_p = &((*add_var_p)->next));
+
+ add_var->next = *add_var_p;
+ *add_var_p = add_var;
+
+ return 0;
+
+error:
+ if (!type)
+ LOG(L_ERR, "ERROR: new_add_var(): failed to add the additional group instance: %.*s[%u]\n",
+ group_name->len, group_name->s, group_id);
+ else
+ LOG(L_ERR, "ERROR: new_add_var(): failed to add the additional variable instance: %.*s[%u].%.*s\n",
+ group_name->len, group_name->s, group_id,
+ var_name->len, var_name->s);
+
+ if (add_var)
+ pkg_free(add_var);
+ return -1;
+}
+
+/* delete the additional variable list */
+static void del_add_var_list(cfg_group_t *group) {
+ cfg_add_var_t *add_var, *add_var2;
+
+ add_var = group->add_var;
+ while (add_var) {
+ add_var2 = add_var->next;
+ if ((add_var->type == CFG_VAR_STR) && add_var->val.s.s)
+ pkg_free(add_var->val.s.s);
+ else if ((add_var->type == CFG_VAR_STRING) && add_var->val.ch)
+ pkg_free(add_var->val.ch);
+ pkg_free(add_var);
+ add_var = add_var2;
+ }
+ group->add_var = NULL;
+}
diff --git a/cfg/cfg_struct.h b/cfg/cfg_struct.h
index 37d56ca..9f7b9fc 100644
--- a/cfg/cfg_struct.h
+++ b/cfg/cfg_struct.h
@@ -52,6 +52,7 @@ typedef struct _cfg_add_var {
unsigned int type; /*!< type == 0 is also valid, it indicates that the group
must be created with the default values */
union {
+ char *ch;
str s;
int i;
} val;
@@ -433,4 +434,13 @@ cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name,
/* free the memory allocated for a child cb list */
void cfg_child_cb_free(cfg_child_cb_t *child_cb_first);
+/* Allocate memory for a new additional variable
+ * and link it to a configuration group.
+ * type==0 results in creating a new group instance with the default values.
+ * The group is created with CFG_GROUP_UNKNOWN type if it does not exist.
+ * Note: this function is usable only before the configuration is shmized.
+ */
+int new_add_var(str *group_name, unsigned int group_id, str *var_name,
+ void *val, unsigned int type);
+
#endif /* _CFG_STRUCT_H */
Module: sip-router
Branch: tirpi/cfg_framework_multivalue
Commit: fd958ea045b82ba1a29e917e47fb9eed146bf5f2
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fd958ea…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Sep 21 14:42:55 2010 +0200
cfg framework: CFG_GROUP_UNKNOWN group type
group->dynamic can take 3 values from now:
- CFG_GROUP_STATIC: static group declared by a module or the core
- CFG_GROUP_DYNAMIC: dynamic group declared from the script
- CFG_GROUP_UNKNOWN: not yet known group type. Such group can exist if
additional group instances are set in the group, but the group
itself has not been declared yet. This is the case
for instance if the group instance is set from the script
but the group is declared from a mod_init function.
Variable name is added to struct _cfg_add_var. The variables may not be
known when additional group instances need to be added, hence, they
can be referred only by name.
---
cfg/cfg.c | 31 +++++++++++++++++++------------
cfg/cfg_ctx.c | 2 +-
cfg/cfg_script.c | 8 +++++---
cfg/cfg_struct.c | 25 +++++++++++++++++++++----
cfg/cfg_struct.h | 20 +++++++++++++++++---
5 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/cfg/cfg.c b/cfg/cfg.c
index c718f5a..88a34b2 100644
--- a/cfg/cfg.c
+++ b/cfg/cfg.c
@@ -43,6 +43,7 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
{
int i, num, size, group_name_len;
cfg_mapping_t *mapping = NULL;
+ cfg_group_t *group;
int types;
/* check the number of the variables */
@@ -142,18 +143,24 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
group_name_len = strlen(group_name);
/* check for duplicates */
- if (cfg_lookup_group(group_name, group_name_len)) {
- LOG(L_ERR, "ERROR: register_cfg_def(): "
- "configuration group has been already declared: %s\n",
- group_name);
- goto error;
+ if ((group = cfg_lookup_group(group_name, group_name_len))) {
+ if (group->dynamic != CFG_GROUP_UNKNOWN) {
+ /* conflict with another module/core group, or with a dynamic group */
+ LOG(L_ERR, "ERROR: register_cfg_def(): "
+ "configuration group has been already declared: %s\n",
+ group_name);
+ goto error;
+ }
+ /* An empty group is found which does not have any variable yet */
+ cfg_set_group(group, num, mapping, values, size, handle);
+ } else {
+ /* create a new group
+ I will allocate memory in shm mem for the variables later in a single block,
+ when we know the size of all the registered groups. */
+ if (!(group = cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle)))
+ goto error;
}
-
- /* create a new group
- I will allocate memory in shm mem for the variables later in a single block,
- when we know the size of all the registered groups. */
- if (!cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle))
- goto error;
+ group->dynamic = CFG_GROUP_STATIC;
/* The cfg variables are ready to use, let us set the handle
before passing the new definitions to the drivers.
@@ -226,7 +233,7 @@ void **cfg_get_handle(char *gname)
cfg_group_t *group;
group = cfg_lookup_group(gname, strlen(gname));
- if (!group || group->dynamic) return NULL;
+ if (!group || (group->dynamic != CFG_GROUP_STATIC)) return NULL;
return group->handle;
}
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index 94f5878..5fa961d 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -77,7 +77,7 @@ int cfg_register_ctx(cfg_ctx_t **handle, cfg_on_declare on_declare_cb)
) {
/* dynamic groups are not ready, the callback
will be called later when the group is fixed-up */
- if (group->dynamic) continue;
+ if (group->dynamic != CFG_GROUP_STATIC) continue;
gname.s = group->name;
gname.len = group->name_len;
diff --git a/cfg/cfg_script.c b/cfg/cfg_script.c
index 8340206..58b6cd9 100644
--- a/cfg/cfg_script.c
+++ b/cfg/cfg_script.c
@@ -56,14 +56,14 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
/* the group may have been already declared */
group = cfg_lookup_group(gname, gname_len);
if (group) {
- if (group->dynamic == 0) {
+ if (group->dynamic == CFG_GROUP_STATIC) {
/* the group has been already declared by a module or by the core */
LOG(L_ERR, "ERROR: new_cfg_script_var(): "
"configuration group has been already declared: %s\n",
gname);
return NULL;
}
- /* the dynamic group is found */
+ /* the dynamic or empty group is found */
/* verify that the variable does not exist */
for ( var = (cfg_script_var_t *)group->vars;
var;
@@ -76,6 +76,8 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
return NULL;
}
}
+ if (group->dynamic == CFG_GROUP_UNKNOWN)
+ group->dynamic = CFG_GROUP_DYNAMIC;
} else {
/* create a new group with NULL values, we will fix it later,
@@ -85,7 +87,7 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
NULL /* vars */, 0 /* size */, NULL /* handle */);
if (!group) goto error;
- group->dynamic = 1;
+ group->dynamic = CFG_GROUP_DYNAMIC;
}
switch (type) {
diff --git a/cfg/cfg_struct.c b/cfg/cfg_struct.c
index 9d5f008..d34ed06 100644
--- a/cfg/cfg_struct.c
+++ b/cfg/cfg_struct.c
@@ -98,6 +98,18 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
return group;
}
+/* Set the values of an existing cfg group. */
+void cfg_set_group(cfg_group_t *group,
+ int num, cfg_mapping_t *mapping,
+ char *vars, int size, void **handle)
+{
+ group->num = num;
+ group->mapping = mapping;
+ group->vars = vars;
+ group->size = size;
+ group->handle = handle;
+}
+
/* clones a string to shared memory
* (src and dst can be the same)
*/
@@ -200,7 +212,7 @@ int cfg_shmize(void)
block = (cfg_block_t*)shm_malloc(sizeof(cfg_block_t)+size-1);
if (!block) {
- LOG(L_ERR, "ERROR: cfg_clone_str(): not enough shm memory\n");
+ LOG(L_ERR, "ERROR: cfg_shmize(): not enough shm memory\n");
goto error;
}
memset(block, 0, sizeof(cfg_block_t)+size-1);
@@ -211,13 +223,13 @@ int cfg_shmize(void)
group;
group=group->next
) {
- if (group->dynamic == 0) {
+ if (group->dynamic == CFG_GROUP_STATIC) {
/* clone the strings to shm mem */
if (cfg_shmize_strings(group)) goto error;
/* copy the values to the new block */
memcpy(CFG_GROUP_DATA(block, group), group->vars, group->size);
- } else {
+ } else if (group->dynamic == CFG_GROUP_DYNAMIC) {
/* The group was declared with NULL values,
* we have to fix it up.
* The fixup function takes care about the values,
@@ -232,6 +244,11 @@ int cfg_shmize(void)
cfg_notify_drivers(group->name, group->name_len,
group->mapping->def);
*(group->handle) = NULL;
+ } else {
+ LOG(L_ERR, "ERROR: cfg_shmize(): Configuration group is declared "
+ "without any variable: %.*s\n",
+ group->name_len, group->name);
+ goto error;
}
}
/* try to fixup the selects that failed to be fixed-up previously */
@@ -273,7 +290,7 @@ static void cfg_destory_groups(unsigned char *block)
if (old_string) shm_free(old_string);
}
- if (group->dynamic) {
+ if (group->dynamic == CFG_GROUP_DYNAMIC) {
/* the group was dynamically allocated */
cfg_script_destroy(group);
} else {
diff --git a/cfg/cfg_struct.h b/cfg/cfg_struct.h
index 5f1fa0a..37d56ca 100644
--- a/cfg/cfg_struct.h
+++ b/cfg/cfg_struct.h
@@ -48,13 +48,19 @@
* an array.
*/
typedef struct _cfg_add_var {
- unsigned int type;
+ struct _cfg_add_var *next;
+ unsigned int type; /*!< type == 0 is also valid, it indicates that the group
+ must be created with the default values */
union {
str s;
int i;
} val;
unsigned int group_id; /*!< Id of the group instance */
- struct _cfg_add_var *next;
+ int name_len; /*!< Name of the variable. The variable may not be known,
+ for example the additional group value is set in the script
+ before the cfg group is declared. Hence, the pointer cannot
+ be stored here. */
+ char name[1];
} cfg_add_var_t;
/*! \brief structure used for variable - pointer mapping */
@@ -68,6 +74,9 @@ typedef struct _cfg_mapping {
unsigned int flag; /*!< flag indicating the state of the variable */
} cfg_mapping_t;
+/*! \brief type of the group */
+enum { CFG_GROUP_UNKNOWN = 0, CFG_GROUP_DYNAMIC, CFG_GROUP_STATIC };
+
/*! \brief linked list of registered groups */
typedef struct _cfg_group {
int num; /*!< number of variables within the group */
@@ -93,7 +102,7 @@ typedef struct _cfg_group {
unsigned char dynamic; /*!< indicates whether the variables within the group
are dynamically allocated or not */
struct _cfg_group *next;
- int name_len;
+ int name_len;
char name[1];
} cfg_group_t;
@@ -236,6 +245,11 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
int num, cfg_mapping_t *mapping,
char *vars, int size, void **handle);
+/* Set the values of an existing cfg group. */
+void cfg_set_group(cfg_group_t *group,
+ int num, cfg_mapping_t *mapping,
+ char *vars, int size, void **handle);
+
/* copy the variables to shm mem */
int cfg_shmize(void);
Module: sip-router
Branch: master
Commit: 2f95266d695532fd5ade1cd45b61c61055577d62
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2f95266…
Author: Juha Heinanen <jh(a)tutpro.com>
Committer: Juha Heinanen <jh(a)tutpro.com>
Date: Tue Sep 28 08:28:49 2010 +0300
modules/lcr: README improvement and a new script
- Added a paragraph on lcr weights.
- Added a script that can be used to determine probabilities
corresponding to a set of weights.
---
modules/lcr/README | 9 ++++++-
modules/lcr/doc/lcr_admin.xml | 11 +++++++-
modules/lcr/utils/lcr_weight_test.php | 43 +++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/modules/lcr/README b/modules/lcr/README
index 44b9f1f..8fa8a98 100644
--- a/modules/lcr/README
+++ b/modules/lcr/README
@@ -230,7 +230,14 @@ Chapter 1. Admin Guide
expression (see 'man pcresyntax' for syntax), an empty string, or NULL.
An empty or NULL from pattern or prefix matches anything. Smaller
priority value means higher priority (highest priority value being 0
- and lowest being 255). Weight is an integer value from 1 to 254.
+ and lowest being 255).
+
+ Weight is an integer value from 1 to 254. Weight implementation is
+ fast, but unfair favoring larger weight values at the expense smaller
+ ones. For example, if two gateways have weights 1 and 2, probability
+ that the gateway with weight 1 is tried first is 1/4, not 1/3. A script
+ is provided in lcr/utils directory that can be used to check the
+ probabilities resulting from a given set of weight values.
The function next_gw() can then be used to select one gateway at a time
for forwarding. Upon each call, unless "dont_strip_of_tag" flag is set,
diff --git a/modules/lcr/doc/lcr_admin.xml b/modules/lcr/doc/lcr_admin.xml
index ab0b45e..562a7c0 100644
--- a/modules/lcr/doc/lcr_admin.xml
+++ b/modules/lcr/doc/lcr_admin.xml
@@ -66,8 +66,15 @@
pcresyntax' for syntax), an empty string, or NULL. An empty or
NULL from pattern or prefix matches anything.
Smaller priority value means higher priority (highest priority
- value being 0 and lowest being 255). Weight is an integer value
- from 1 to 254.
+ value being 0 and lowest being 255).
+ </para>
+ <para>
+ Weight is an integer value from 1 to 254. Weight implementation is
+ fast, but unfair favoring larger weight values at the expense smaller
+ ones. For example, if two gateways have weights 1 and 2, probability
+ that the gateway with weight 1 is tried first is 1/4, not 1/3.
+ A script is provided in lcr/utils directory that can be used to
+ check the probabilities resulting from a given set of weight values.
</para>
<para>
The function <emphasis>next_gw()</emphasis> can then be used to
diff --git a/modules/lcr/utils/lcr_weight_test.php b/modules/lcr/utils/lcr_weight_test.php
new file mode 100755
index 0000000..53c9319
--- /dev/null
+++ b/modules/lcr/utils/lcr_weight_test.php
@@ -0,0 +1,43 @@
+#!/usr/bin/php
+<?php
+
+ // This script can be used to find out actual probabilities
+ // that correspond to a list of LCR gateway weights.
+
+if ($argc < 2) {
+ echo "Usage: lcr_weight_test.php <list of weights (integers 1-254)>\n";
+ exit;
+ }
+
+$iters = 10000;
+
+$rands = array();
+for ($i = 1; $i <= $iters; $i++) {
+ $elem = array();
+ for ($j = 1; $j < $argc; $j++) {
+ $elem["$j"] = $argv[$j] * (rand() >> 8);
+ }
+ $rands[] = $elem;
+ }
+
+$sorted = array();
+foreach ($rands as $rand) {
+ asort($rand);
+ $sorted[] = $rand;
+ }
+
+$counts = array();
+for ($j = 1; $j < $argc; $j++) {
+ $counts["$j"] = 0;
+ }
+
+foreach ($sorted as $rand) {
+ end($rand);
+ $counts[key($rand)]++;
+ }
+
+for ($j = 1; $j < $argc; $j++) {
+ echo "weight " . $argv[$j] . " probability " . $counts["$j"]/$iters . "\n";
+ }
+
+?>
Module: sip-router
Branch: master
Commit: e8e372698904c6afae4952d0291b051b4116bbd8
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e8e3726…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Mon Sep 27 21:51:16 2010 +0200
debugger: some fixes in documentation
---
modules/debugger/README | 17 ++++++++++-------
modules/debugger/doc/debugger_admin.xml | 18 ++++++++++--------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/modules/debugger/README b/modules/debugger/README
index ce05b89..8e55a64 100644
--- a/modules/debugger/README
+++ b/modules/debugger/README
@@ -96,12 +96,13 @@ Chapter 1. Admin Guide
the config.
Debugging can be done from local or remote host via RPC interface
- (e.g., XMLRPC, sercmd).
+ (e.g., XMLRPC, sercmd, siremis).
The framework to set breakpoints on specific actions and config lines
- is not exported to RPC yet, right now each action has an breakpoint.
- The breakpoint can be enabled/disabled at runtime. Also the config
- running trace can be enabled/disabled at runtime.
+ is not exported to RPC yet. Each action can be accompanied by an
+ breakpoint or you can use dbg_breakpoint() function to set a breakpoint
+ at certain line. Global breakpoint can be enabled/disabled at runtime.
+ Also the config running trace can be enabled/disabled at runtime.
When the SIP router process is stopped at a breakpoint, you can
investigate the values of any pseudo-varaibles. Note that some of
@@ -139,6 +140,8 @@ Chapter 1. Admin Guide
3.1. cfgtrace (int)
Control whether config running trace is enabled or disabled at startup.
+ You can change the value at runtime without restart, globally or per
+ process.
Default value is “0” (disabled).
@@ -149,7 +152,7 @@ modparam("debugger", "cfgtrace", 1)
3.2. breakpoint (int)
- Control whether every line (for now) breakpoint is enabled or disabled
+ Control whether every line (global) breakpoint is enabled or disabled
at startup.
Default value is “0” (disabled).
@@ -224,7 +227,7 @@ modparam("debugger", "step_loops", 100)
4.1. dbg_breakpoint(mode)
- Achor a breakpoint at that line in config. Mode specifies whether the
+ Anchor a breakpoint at that line in config. Mode specifies whether the
breakpoint is enabled (1) or disabled (0) at startup.
Note that this version does not export this anchors to RPC for
@@ -282,7 +285,7 @@ if($si=="10.0.0.10")
Parameters:
* _cmd_ : inner command, see next section for the list of available
values.
- * _pid_ : pid for which to apply the inner command. If it missing,
+ * _pid_ : pid for which to apply the inner command. If it is missing,
then will be applied for all processes.
* _params_ : extra params specific for each inner command.
diff --git a/modules/debugger/doc/debugger_admin.xml b/modules/debugger/doc/debugger_admin.xml
index 30fb574..78d5582 100644
--- a/modules/debugger/doc/debugger_admin.xml
+++ b/modules/debugger/doc/debugger_admin.xml
@@ -24,13 +24,14 @@
</para>
<para>
Debugging can be done from local or remote host via RPC interface (e.g.,
- XMLRPC, sercmd).
+ XMLRPC, sercmd, siremis).
</para>
<para>
The framework to set breakpoints on specific actions and config lines
- is not exported to RPC yet, right now each action has an breakpoint. The
- breakpoint can be enabled/disabled at runtime. Also the config running
- trace can be enabled/disabled at runtime.
+ is not exported to RPC yet. Each action can be accompanied by an
+ breakpoint or you can use dbg_breakpoint() function to set a breakpoint
+ at certain line. Global breakpoint can be enabled/disabled at runtime.
+ Also the config running trace can be enabled/disabled at runtime.
</para>
<para>
When the SIP router process is stopped at a breakpoint, you can
@@ -77,7 +78,8 @@
<title><varname>cfgtrace</varname> (int)</title>
<para>
Control whether config running trace is enabled or disabled
- at startup.
+ at startup. You can change the value at runtime without
+ restart, globally or per process.
</para>
<para>
<emphasis>
@@ -97,7 +99,7 @@ modparam("debugger", "cfgtrace", 1)
<section>
<title><varname>breakpoint</varname> (int)</title>
<para>
- Control whether every line (for now) breakpoint is enabled
+ Control whether every line (global) breakpoint is enabled
or disabled at startup.
</para>
<para>
@@ -228,7 +230,7 @@ modparam("debugger", "step_loops", 100)
<function moreinfo="none">dbg_breakpoint(mode)</function>
</title>
<para>
- Achor a breakpoint at that line in config. Mode specifies
+ Anchor a breakpoint at that line in config. Mode specifies
whether the breakpoint is enabled (1) or disabled (0) at startup.
</para>
<para>
@@ -321,7 +323,7 @@ if($si=="10.0.0.10")
the list of available values.</para>
</listitem>
<listitem><para>_pid_ : pid for which to apply the inner command.
- If it missing, then will be applied for all processes.</para>
+ If it is missing, then will be applied for all processes.</para>
</listitem>
<listitem><para>_params_ : extra params specific for each inner
command.</para>