Skip to content

Commit 4fbbe68

Browse files
committed
update new feature share memory and cache feature between process and apps
1 parent d8226d3 commit 4fbbe68

File tree

4 files changed

+261
-22
lines changed

4 files changed

+261
-22
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,16 @@ extern void ngx_http_c_func_write_resp(
170170
const char* resp_content
171171
);
172172

173+
// Shared Memory and Cache Scope
174+
extern void ngx_http_c_func_shmtx_lock(void *shared_mem);
175+
extern void ngx_http_c_func_shmtx_unlock(void *shared_mem);
176+
extern void* ngx_http_c_func_shm_alloc(void *shared_mem, size_t size);
177+
extern void ngx_http_c_func_shm_free(void *shared_mem, void *ptr);
178+
extern void* ngx_http_c_func_cache_get(void *shared_mem, const char* key);
179+
extern void* ngx_http_c_func_cache_put(void *shared_mem, const char* key, void* value);
180+
extern void* ngx_http_c_func_cache_new(void *shared_mem, const char* key, size_t size);
181+
extern void ngx_http_c_func_cache_remove(void *shared_mem, const char* key);
182+
173183
```
174184
175185
## Interface break down details

config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ngx_feature_incs="#include <ngx_http_c_func_module.h>"
2424
ngx_feature_path=
2525
ngx_feature_libs=
2626
# ngx_feature_exit_if_not_found=yes
27-
ngx_feature_test="int ngx_http_c_func_module_current_version_=ngx_http_c_func_module_version_3;"
27+
ngx_feature_test="int ngx_http_c_func_module_current_version_=ngx_http_c_func_module_version_4;"
2828
. auto/feature
2929

3030
if [ $ngx_found != yes ]; then

src/ngx_http_c_func_module.c

Lines changed: 237 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,27 @@
4545
* Configs
4646
*
4747
*/
48+
typedef struct {
49+
ngx_str_node_t sn;
50+
void *value;
51+
} ngx_http_c_func_http_cache_value_node_t;
52+
53+
typedef struct {
54+
ngx_rbtree_t rbtree;
55+
ngx_rbtree_node_t sentinel;
56+
ngx_slab_pool_t *shpool;
57+
} ngx_http_c_func_http_shm_t;
58+
59+
typedef struct {
60+
ngx_str_t name;
61+
ngx_http_c_func_http_shm_t *shared_mem;
62+
} ngx_http_c_func_http_shm_ctx_t;
63+
4864
typedef struct {
4965
ngx_flag_t is_ssl_support;
5066
ngx_flag_t is_module_enabled;
51-
ngx_atomic_t *multi_processes_lock;
67+
ngx_flag_t is_cache_defined;
68+
ngx_http_c_func_http_shm_ctx_t *shm_ctx;
5269
} ngx_http_c_func_main_conf_t;
5370

5471
typedef void (*ngx_http_c_func_app_handler)(ngx_http_c_func_ctx_t*);
@@ -81,6 +98,7 @@ typedef struct {
8198
static ngx_int_t ngx_http_c_func_pre_configuration(ngx_conf_t *cf);
8299
static ngx_int_t ngx_http_c_func_post_configuration(ngx_conf_t *cf);
83100
static char* ngx_http_c_func_validation_check_and_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
101+
static char* ngx_http_c_func_set_c_func_shm(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
84102
// static char *ngx_http_c_func_srv_post_conf_handler(ngx_conf_t *cf, void *data, void *conf);
85103
static void *ngx_http_c_func_create_main_conf(ngx_conf_t *cf);
86104
static char *ngx_http_c_func_init_main_conf(ngx_conf_t *cf, void *conf);
@@ -130,8 +148,14 @@ void* ngx_http_c_func_get_query_param(ngx_http_c_func_ctx_t *ctx, const char *ke
130148
void* ngx_http_c_func_palloc(ngx_http_c_func_ctx_t *ctx, size_t size);
131149
void* ngx_http_c_func_pcalloc(ngx_http_c_func_ctx_t *ctx, size_t size);
132150

133-
void ngx_http_c_func_process_lock(ngx_http_c_func_ctx_t *ctx);
134-
void ngx_http_c_func_process_unlock(ngx_http_c_func_ctx_t *ctx);
151+
void ngx_http_c_func_shmtx_lock(void *shared_mem);
152+
void ngx_http_c_func_shmtx_unlock(void *shared_mem);
153+
void* ngx_http_c_func_shm_alloc(void *shared_mem, size_t size);
154+
void ngx_http_c_func_shm_free(void *shared_mem, void *ptr);
155+
void* ngx_http_c_func_cache_get(void *shared_mem, const char* key);
156+
void* ngx_http_c_func_cache_put(void *shared_mem, const char* key, void* value);
157+
void* ngx_http_c_func_cache_new(void *shared_mem, const char* key, size_t size);
158+
void ngx_http_c_func_cache_remove(void *shared_mem, const char* key);
135159

136160
void ngx_http_c_func_write_resp(
137161
ngx_http_c_func_ctx_t *ctx,
@@ -149,6 +173,14 @@ void ngx_http_c_func_write_resp(
149173
* This module provided directive.
150174
*/
151175
static ngx_command_t ngx_http_c_func_commands[] = {
176+
{
177+
ngx_string("ngx_http_c_func_shm_size"),
178+
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
179+
ngx_http_c_func_set_c_func_shm,
180+
NGX_HTTP_MAIN_CONF_OFFSET,
181+
0,
182+
NULL
183+
},
152184
{
153185
ngx_string("ngx_http_c_func_link_lib"),
154186
NGX_HTTP_SRV_CONF | NGX_CONF_TAKE1,
@@ -215,6 +247,76 @@ ngx_module_t ngx_http_c_func_module = {
215247
NGX_MODULE_V1_PADDING
216248
};
217249

250+
ngx_int_t
251+
ngx_http_c_func_shm_cache_init(ngx_shm_zone_t *shm_zone, void *data)
252+
{
253+
size_t len;
254+
ngx_http_c_func_http_shm_ctx_t *oshm = data;
255+
ngx_http_c_func_http_shm_ctx_t *nshm = shm_zone->data;
256+
ngx_slab_pool_t *shpool;
257+
258+
if (oshm) {
259+
shm_zone->data = oshm;
260+
return NGX_OK;
261+
}
262+
263+
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
264+
265+
if (shm_zone->shm.exists) {
266+
shm_zone->data = shpool->data;
267+
return NGX_OK;
268+
}
269+
270+
271+
nshm->shared_mem = ngx_slab_alloc(shpool, sizeof(ngx_http_c_func_http_shm_t));
272+
ngx_rbtree_init(&nshm->shared_mem->rbtree, &nshm->shared_mem->sentinel, ngx_str_rbtree_insert_value);
273+
274+
nshm->shared_mem->shpool = shpool;
275+
276+
len = sizeof(" in nginx c function session shared cache \"\"") + shm_zone->shm.name.len;
277+
278+
nshm->shared_mem->shpool->log_ctx = ngx_slab_alloc(nshm->shared_mem->shpool, len);
279+
if (nshm->shared_mem->shpool->log_ctx == NULL) {
280+
return NGX_ERROR;
281+
}
282+
283+
ngx_sprintf(nshm->shared_mem->shpool->log_ctx, " in nginx c function session shared cache \"%V\"%Z",
284+
&shm_zone->shm.name);
285+
286+
nshm->shared_mem->shpool->log_nomem = 0;
287+
288+
return NGX_OK;
289+
}
290+
291+
static char*
292+
ngx_http_c_func_set_c_func_shm(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
293+
ngx_str_t *values;
294+
ngx_http_c_func_main_conf_t *mcf = conf;
295+
ngx_shm_zone_t *shm_zone;
296+
ngx_int_t pg_size;
297+
298+
values = cf->args->elts;
299+
300+
pg_size = ngx_parse_size(&values[1]);
301+
302+
if (pg_size == NGX_ERROR) {
303+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", "Invalid cache size, please specify like 1m,1g and etc.");
304+
return NGX_CONF_ERROR;
305+
}
306+
307+
308+
shm_zone = ngx_shared_memory_add(cf, &mcf->shm_ctx->name, pg_size, &ngx_http_c_func_module);
309+
if (shm_zone == NULL) {
310+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", "Unable to allocate apps defined size");
311+
return NGX_CONF_ERROR;
312+
}
313+
mcf->is_cache_defined = 1;
314+
shm_zone->init = ngx_http_c_func_shm_cache_init;
315+
shm_zone->data = mcf->shm_ctx;
316+
317+
return NGX_CONF_OK;
318+
}
319+
218320
static char*
219321
ngx_http_c_func_validation_check_and_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
220322
ngx_str_t *values;
@@ -349,7 +451,7 @@ ngx_http_c_func_proceed_init_calls(ngx_cycle_t* cycle, ngx_http_c_func_srv_conf
349451
/*** Init the apps ***/
350452
ngx_http_c_func_ctx_t new_ctx; //config request
351453
new_ctx.__log__ = cycle->log;
352-
new_ctx.__process_lock__ = (void*)mcf->multi_processes_lock;
454+
new_ctx.shared_mem = (void*)mcf->shm_ctx->shared_mem;
353455
func(&new_ctx);
354456
}
355457

@@ -375,13 +477,29 @@ ngx_http_c_func_post_configuration(ngx_conf_t *cf) {
375477

376478
*h = ngx_http_c_func_rewrite_handler;
377479
}
480+
481+
/*** Default Init for shm with 1M if pool is empty***/
482+
if (mcf != NULL && !mcf->is_cache_defined ) {
483+
ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "%s", "Init Default Share memory with 1k");
484+
ngx_str_t default_size = ngx_string("1M");
485+
486+
ngx_shm_zone_t *shm_zone = ngx_shared_memory_add(cf, &mcf->shm_ctx->name, ngx_parse_size(&default_size), &ngx_http_c_func_module);
487+
if (shm_zone == NULL) {
488+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", "Unable to allocate size");
489+
return NGX_ERROR;
490+
}
491+
492+
shm_zone->init = ngx_http_c_func_shm_cache_init;
493+
shm_zone->data = mcf->shm_ctx;
494+
}
495+
378496
return NGX_OK;
379497
}
380498

381499
static ngx_int_t
382500
ngx_http_c_func_pre_configuration(ngx_conf_t *cf) {
383501

384-
#ifndef ngx_http_c_func_module_version_3
502+
#ifndef ngx_http_c_func_module_version_4
385503
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", "the latest ngx_http_c_func_module.h not found in the c header path, \
386504
please copy latest ngx_http_c_func_module.h to your /usr/include or /usr/local/include or relavent header search path \
387505
with read and write permission.");
@@ -401,6 +519,7 @@ ngx_http_c_func_module_init(ngx_cycle_t *cycle) {
401519
ngx_http_conf_ctx_t *ctx = (ngx_http_conf_ctx_t *)ngx_get_conf(cycle->conf_ctx, ngx_http_module);
402520

403521
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
522+
404523
cscfp = cmcf->servers.elts;
405524

406525
for (s = 0; s < cmcf->servers.nelts; s++) {
@@ -468,6 +587,7 @@ ngx_http_c_func_module_init(ngx_cycle_t *cycle) {
468587
continue;
469588
}
470589
}
590+
471591
return NGX_OK;
472592
}
473593

@@ -533,7 +653,7 @@ ngx_http_c_func_process_exit(ngx_cycle_t *cycle) {
533653
} else {
534654
ngx_http_c_func_ctx_t new_ctx; //config request
535655
new_ctx.__log__ = cycle->log;
536-
new_ctx.__process_lock__ = (void*)mcf->multi_processes_lock;
656+
new_ctx.shared_mem = (void*)mcf->shm_ctx->shared_mem;
537657
func(&new_ctx);
538658
}
539659
} else {
@@ -576,7 +696,12 @@ ngx_http_c_func_master_exit(ngx_cycle_t *cycle) {
576696
return;
577697
}
578698

579-
munmap((void*)cfunmcf->multi_processes_lock, sizeof(*(cfunmcf->multi_processes_lock)));
699+
// if (cfunmcf->shm_ctx && cfunmcf->shm_ctx->shared_mem) {
700+
// if (cfunmcf->shm_ctx->shared_mem->shpool && cfunmcf->shm_ctx->shared_mem->shpool->log_ctx) {
701+
// ngx_slab_free(cfunmcf->shm_ctx->shared_mem->shpool, cfunmcf->shm_ctx->shared_mem->shpool->log_ctx);
702+
// }
703+
// ngx_slab_free(cfunmcf->shm_ctx->shared_mem->shpool, cfunmcf->shm_ctx->shared_mem);
704+
// }
580705

581706
ngx_log_error(NGX_LOG_DEBUG, cycle->log, 0, "ngx-http-c-func module Exiting ");
582707
}
@@ -589,6 +714,17 @@ ngx_http_c_func_create_main_conf(ngx_conf_t *cf) {
589714
return NGX_CONF_ERROR;
590715
}
591716

717+
mcf->shm_ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_c_func_http_shm_ctx_t));
718+
719+
if (mcf->shm_ctx == NULL) {
720+
return NGX_CONF_ERROR;
721+
}
722+
723+
ngx_str_set(& mcf->shm_ctx->name , "ngx_c_function_shm_cache");
724+
725+
mcf->shm_ctx->shared_mem = NULL;
726+
727+
mcf->is_cache_defined = 0;
592728
mcf->is_module_enabled = 0;
593729

594730
#if(NGX_SSL || NGX_OPENSSL)
@@ -597,10 +733,6 @@ ngx_http_c_func_create_main_conf(ngx_conf_t *cf) {
597733
mcf->is_ssl_support = 0;
598734
#endif
599735

600-
mcf->multi_processes_lock = mmap(NULL, sizeof(*(mcf->multi_processes_lock)), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
601-
602-
*mcf->multi_processes_lock = 0;
603-
604736
return mcf;
605737
}
606738

@@ -714,7 +846,7 @@ ngx_http_c_func_content_handler(ngx_http_request_t *r) {
714846
ngx_http_c_func_ctx_t new_ctx;
715847
new_ctx.__r__ = r;
716848
new_ctx.__log__ = r->connection->log;
717-
new_ctx.__process_lock__ = (void*)mcf->multi_processes_lock;
849+
new_ctx.shared_mem = (void*)mcf->shm_ctx->shared_mem;
718850

719851
/***Set to default incase link library does not return anything ***/
720852
new_ctx.__rc__ = NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -992,13 +1124,102 @@ ngx_http_c_func_pcalloc(ngx_http_c_func_ctx_t *ctx, size_t size) {
9921124
}
9931125

9941126
void
995-
ngx_http_c_func_process_lock(ngx_http_c_func_ctx_t *ctx) {
996-
ngx_spinlock((ngx_atomic_t*) ctx->__process_lock__, 1, 2048);
1127+
ngx_http_c_func_shmtx_lock(void *shared_mem) {
1128+
ngx_shmtx_lock(&((ngx_http_c_func_http_shm_t*)shared_mem)->shpool->mutex);
1129+
// ngx_spinlock((ngx_atomic_t*) ctx->__shm_t__->multi_processes_lock, 1, 2048);
1130+
}
1131+
1132+
void
1133+
ngx_http_c_func_shmtx_unlock(void *shared_mem) {
1134+
ngx_shmtx_unlock(&((ngx_http_c_func_http_shm_t*)shared_mem)->shpool->mutex);
1135+
// ngx_unlock((ngx_atomic_t*) ctx->__shm_t__);
1136+
}
1137+
1138+
void*
1139+
ngx_http_c_func_shm_alloc(void *shared_mem, size_t size) {
1140+
return ngx_slab_alloc_locked(((ngx_http_c_func_http_shm_t*)shared_mem)->shpool, size);
1141+
}
1142+
1143+
void
1144+
ngx_http_c_func_shm_free(void *shared_mem, void *ptr) {
1145+
ngx_slab_free_locked(((ngx_http_c_func_http_shm_t*)shared_mem)->shpool, ptr);
1146+
// ngx_spinlock((ngx_atomic_t*) ctx->__shm_t__->multi_processes_lock, 1, 2048);
1147+
}
1148+
1149+
void*
1150+
ngx_http_c_func_cache_get(void *shared_mem, const char* key) {
1151+
ngx_str_t str_key = ngx_string(key);
1152+
uint32_t hash = ngx_crc32_long(str_key.data, str_key.len);
1153+
ngx_http_c_func_http_shm_t *_cache = (ngx_http_c_func_http_shm_t *)shared_mem;
1154+
ngx_http_c_func_http_cache_value_node_t *cvnt = (ngx_http_c_func_http_cache_value_node_t *)
1155+
ngx_str_rbtree_lookup(&_cache->rbtree, &str_key, hash);
1156+
if (cvnt) {
1157+
return cvnt->value;
1158+
} else {
1159+
return NULL;
1160+
}
1161+
}
1162+
1163+
/***
1164+
*
1165+
* return old_value if found, else update cache and return new value
1166+
*/
1167+
void*
1168+
ngx_http_c_func_cache_put(void *shared_mem, const char* key, void* value) {
1169+
void *old_value;
1170+
ngx_str_t str_key = ngx_string(key);
1171+
uint32_t hash = ngx_crc32_long(str_key.data, str_key.len);
1172+
ngx_http_c_func_http_shm_t *_cache = (ngx_http_c_func_http_shm_t *)shared_mem;
1173+
ngx_http_c_func_http_cache_value_node_t *cvnt = (ngx_http_c_func_http_cache_value_node_t *)
1174+
ngx_str_rbtree_lookup(&_cache->rbtree, &str_key, hash);
1175+
if (cvnt) {
1176+
old_value = cvnt->value;
1177+
cvnt->value = value;
1178+
return old_value;
1179+
} else {
1180+
cvnt = (ngx_http_c_func_http_cache_value_node_t *)
1181+
ngx_slab_alloc_locked(_cache->shpool, sizeof(ngx_http_c_func_http_cache_value_node_t));
1182+
if (cvnt == NULL) {
1183+
return NULL;
1184+
}
1185+
cvnt->value = value;
1186+
cvnt->sn.node.key = hash;
1187+
ngx_str_set(&cvnt->sn.str , key);
1188+
ngx_rbtree_insert(&_cache->rbtree, &cvnt->sn.node);
1189+
return NULL;
1190+
}
1191+
}
1192+
1193+
void*
1194+
ngx_http_c_func_cache_new(void *shared_mem, const char* key, size_t size) {
1195+
ngx_str_t str_key = ngx_string(key);
1196+
uint32_t hash = ngx_crc32_long(str_key.data, str_key.len);
1197+
ngx_http_c_func_http_shm_t *_cache = (ngx_http_c_func_http_shm_t *)shared_mem;
1198+
1199+
ngx_http_c_func_http_cache_value_node_t *cvnt = (ngx_http_c_func_http_cache_value_node_t *)
1200+
ngx_slab_alloc_locked(_cache->shpool, sizeof(ngx_http_c_func_http_cache_value_node_t));
1201+
1202+
if (cvnt == NULL) {
1203+
return NULL;
1204+
}
1205+
1206+
cvnt->value = ngx_slab_alloc_locked(_cache->shpool, size);
1207+
cvnt->sn.node.key = hash;
1208+
ngx_str_set(&cvnt->sn.str , key);
1209+
ngx_rbtree_insert(&_cache->rbtree, &cvnt->sn.node);
1210+
return cvnt->value;
9971211
}
9981212

9991213
void
1000-
ngx_http_c_func_process_unlock(ngx_http_c_func_ctx_t *ctx) {
1001-
ngx_unlock((ngx_atomic_t*) ctx->__process_lock__);
1214+
ngx_http_c_func_cache_remove(void *shared_mem, const char* key) {
1215+
ngx_str_t str_key = ngx_string(key);
1216+
uint32_t hash = ngx_crc32_long(str_key.data, str_key.len);
1217+
ngx_http_c_func_http_shm_t *_cache = (ngx_http_c_func_http_shm_t *)shared_mem;
1218+
ngx_http_c_func_http_cache_value_node_t *cvnt = (ngx_http_c_func_http_cache_value_node_t *)
1219+
ngx_str_rbtree_lookup(&_cache->rbtree, &str_key, hash);
1220+
1221+
if (cvnt)
1222+
ngx_rbtree_delete(&_cache->rbtree, &cvnt->sn.node);
10021223
}
10031224

10041225
void

0 commit comments

Comments
 (0)