Skip to content

Commit

Permalink
version 1.3
Browse files Browse the repository at this point in the history
- added no-op counter declarations (see updated docs)
- fixed segfaults when merging conf levels with references to run-time
  variables with upper conf levels without such references
  • Loading branch information
lyokha committed Apr 3, 2019
1 parent 8356562 commit 68049cb
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 48 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ an operation — *set* or *inc* (i.e. increment). The third argument —
an integer (possibly negative) or a variable (possibly negated), is optional,
its default value is *1*.

Starting from version *1.3* of the module, directive `counter` may declare
*no-op* counters such as

```nginx
counter $cnt_name3;
```

This is the exact equivalent of directive `counter` with option `inc 0` which
can be used to declare variable `$cnt_name3` as a counter with the appropriate
variable handler while avoiding access to the shared memory in the run-time.

*Early counters* are updated before *rewrite* directives and can be used to mark
entry points before any *rewrites* and *ifs*. They are allowed only on
*location* level.
Expand Down Expand Up @@ -102,7 +113,7 @@ cnt_1 = 4 | cnt_2 = 2
```

A single counter can be declared both as normal and early if none of the merged
location configuration hierarchies contains both the types simultaneously.
location configuration hierarchies contains both types simultaneously.

Sharing between virtual servers
-------------------------------
Expand Down
110 changes: 63 additions & 47 deletions ngx_http_custom_counters_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* Description: nginx module for shared custom counters
*
* Version: 1.2
* Version: 1.3
* Created: 04.08.2016 14:00:10
* Revision: none
* Compiler: gcc
Expand Down Expand Up @@ -121,7 +121,7 @@ static ngx_int_t ngx_http_cnt_update(ngx_http_request_t *r, ngx_uint_t early);
static ngx_command_t ngx_http_cnt_commands[] = {

{ ngx_string("counter"),
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE23,
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE123,
ngx_http_cnt_counter,
NGX_HTTP_LOC_CONF_OFFSET,
0,
Expand Down Expand Up @@ -281,20 +281,7 @@ ngx_http_cnt_create_srv_conf(ngx_conf_t *cf)
static void *
ngx_http_cnt_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_cnt_loc_conf_t *lcf;

lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cnt_loc_conf_t));
if (lcf == NULL) {
return NULL;
}

if (ngx_array_init(&lcf->cnt_data, cf->pool, 1,
sizeof(ngx_http_cnt_data_t)) != NGX_OK)
{
return NULL;
}

return lcf;
return ngx_pcalloc(cf->pool, sizeof(ngx_http_cnt_loc_conf_t));
}


Expand Down Expand Up @@ -334,7 +321,7 @@ ngx_http_cnt_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_array_t child_data;
ngx_http_cnt_rt_vars_data_t *rt_var;

if (prev->cnt_data.nelts == 0 && conf->cnt_data.nelts == 0) {
if (prev->cnt_data.nelts == 0) {
return NGX_CONF_OK;
}

Expand All @@ -353,18 +340,20 @@ ngx_http_cnt_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
*cnt_data = prev_cnt_data[i];
size = cnt_data->rt_vars.nelts;
if (ngx_array_init(&cnt_data->rt_vars, cf->pool, size,
sizeof(ngx_http_cnt_rt_vars_data_t)) != NGX_OK)
{
return NGX_CONF_ERROR;
}
for (j = 0; j < size; j++) {
rt_var = ngx_array_push(&cnt_data->rt_vars);
if (rt_var == NULL) {
if (size > 0) {
if (ngx_array_init(&cnt_data->rt_vars, cf->pool, size,
sizeof(ngx_http_cnt_rt_vars_data_t)) != NGX_OK)
{
return NGX_CONF_ERROR;
}
*rt_var = ((ngx_http_cnt_rt_vars_data_t *)
prev_cnt_data[i].rt_vars.elts)[j];
for (j = 0; j < size; j++) {
rt_var = ngx_array_push(&cnt_data->rt_vars);
if (rt_var == NULL) {
return NGX_CONF_ERROR;
}
*rt_var = ((ngx_http_cnt_rt_vars_data_t *)
prev_cnt_data[i].rt_vars.elts)[j];
}
}
}

Expand Down Expand Up @@ -536,9 +525,20 @@ ngx_http_cnt_counter_impl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
ngx_http_cnt_rt_vars_data_t *rt_var;
ngx_http_cnt_shm_data_t *shm_data;
ngx_int_t idx = NGX_ERROR, v_idx;
ngx_int_t val = 1;
ngx_http_cnt_op_e op = ngx_http_cnt_op_inc;
ngx_int_t val;
ngx_uint_t negative = 0;

if (lcf->cnt_data.nalloc == 0
&& ngx_array_init(&lcf->cnt_data, cf->pool, 1,
sizeof(ngx_http_cnt_data_t)) != NGX_OK)
{
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"failed to allocate memory for custom counters in "
"location configuration data");
return NGX_CONF_ERROR;
}

mcf = ngx_http_conf_get_module_main_conf(cf,
ngx_http_custom_counters_module);
scf = ngx_http_conf_get_module_srv_conf(cf,
Expand Down Expand Up @@ -704,11 +704,9 @@ ngx_http_cnt_counter_impl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
}
}

if (ngx_array_init(&cnt_data.rt_vars, cf->pool, 1,
sizeof(ngx_http_cnt_rt_vars_data_t)) != NGX_OK)
{
return NGX_CONF_ERROR;
}
val = cf->args->nelts == 2 ? 0 : 1;

ngx_memzero(&cnt_data.rt_vars, sizeof(ngx_array_t));

if (cf->args->nelts == 4) {
if (value[3].len > 1 && value[3].data[0] == '-') {
Expand All @@ -723,6 +721,11 @@ ngx_http_cnt_counter_impl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
if (val == NGX_ERROR) {
return NGX_CONF_ERROR;
}
if (ngx_array_init(&cnt_data.rt_vars, cf->pool, 1,
sizeof(ngx_http_cnt_rt_vars_data_t)) != NGX_OK)
{
return NGX_CONF_ERROR;
}
rt_var = ngx_array_push(&cnt_data.rt_vars);
if (rt_var == NULL) {
return NGX_CONF_ERROR;
Expand All @@ -743,18 +746,21 @@ ngx_http_cnt_counter_impl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
}
}

if (value[2].len == 3 && ngx_strncmp(value[2].data, "set", 3) == 0) {
cnt_data.op = ngx_http_cnt_op_set;
} else if (value[2].len == 3 && ngx_strncmp(value[2].data, "inc", 3) == 0) {
cnt_data.op = ngx_http_cnt_op_inc;
} else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"unknown counter operation: \"%V\"", &value[2]);
return NGX_CONF_ERROR;
if (cf->args->nelts > 2) {
if (value[2].len == 3 && ngx_strncmp(value[2].data, "set", 3) == 0) {
op = ngx_http_cnt_op_set;
} else if (value[2].len != 3
|| ngx_strncmp(value[2].data, "inc", 3) != 0)
{
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"unknown counter operation: \"%V\"", &value[2]);
return NGX_CONF_ERROR;
}
}

cnt_data.self = v_idx;
cnt_data.idx = idx;
cnt_data.op = op;
cnt_data.value = val;
cnt_data.early = early;

Expand Down Expand Up @@ -806,7 +812,7 @@ ngx_http_cnt_merge(ngx_conf_t *cf, ngx_array_t *dst,
{
ngx_http_cnt_data_t *data = dst->elts;

ngx_uint_t i;
ngx_uint_t i, size;
ngx_http_cnt_data_t *new_data;
ngx_http_cnt_rt_vars_data_t *rt_var;
ngx_int_t idx = NGX_ERROR;
Expand Down Expand Up @@ -836,13 +842,23 @@ ngx_http_cnt_merge(ngx_conf_t *cf, ngx_array_t *dst,
new_data->op = ngx_http_cnt_op_set;
}
new_data->value += cnt_data->value;
for (i = 0; i < cnt_data->rt_vars.nelts; i++) {
rt_var = ngx_array_push(&new_data->rt_vars);
if (rt_var == NULL) {
size = cnt_data->rt_vars.nelts;
if (size > 0) {
if (new_data->rt_vars.nalloc == 0
&& ngx_array_init(&new_data->rt_vars, cf->pool, size,
sizeof(ngx_http_cnt_rt_vars_data_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
*rt_var = ((ngx_http_cnt_rt_vars_data_t *)
cnt_data->rt_vars.elts)[i];
for (i = 0; i < size; i++) {
rt_var = ngx_array_push(&new_data->rt_vars);
if (rt_var == NULL) {
return NGX_CONF_ERROR;
}
*rt_var = ((ngx_http_cnt_rt_vars_data_t *)
cnt_data->rt_vars.elts)[i];
}
}
} else {
*new_data = *cnt_data;
Expand Down

0 comments on commit 68049cb

Please sign in to comment.