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+
4864typedef 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
5471typedef void (* ngx_http_c_func_app_handler )(ngx_http_c_func_ctx_t * );
@@ -81,6 +98,7 @@ typedef struct {
8198static ngx_int_t ngx_http_c_func_pre_configuration (ngx_conf_t * cf );
8299static ngx_int_t ngx_http_c_func_post_configuration (ngx_conf_t * cf );
83100static 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);
85103static void * ngx_http_c_func_create_main_conf (ngx_conf_t * cf );
86104static 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
130148void * ngx_http_c_func_palloc (ngx_http_c_func_ctx_t * ctx , size_t size );
131149void * 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
136160void 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 */
151175static 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+
218320static char *
219321ngx_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
381499static ngx_int_t
382500ngx_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
9941126void
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
9991213void
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
10041225void
0 commit comments