Skip to content

Commit 73bd64d

Browse files
helloyiagentzh
authored andcommitted
feature: added public C API for 3rd-party NGINX C modules to register their own shm-based data structures for the Lua land usage (that is, to create custom siblings to lua_shared_dict).
thanks helloyi and doujiang for the patches. Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
1 parent 40b61f4 commit 73bd64d

13 files changed

+752
-46
lines changed

src/api/ngx_http_lua_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ ngx_int_t ngx_http_lua_shared_dict_get(ngx_shm_zone_t *shm_zone,
4646

4747
ngx_shm_zone_t *ngx_http_lua_find_zone(u_char *name_data, size_t name_len);
4848

49+
ngx_shm_zone_t *ngx_http_lua_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
50+
size_t size, void *tag);
51+
4952

5053
#endif /* _NGX_HTTP_LUA_API_H_INCLUDED_ */
5154

src/ngx_http_lua_api.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44
*/
55

66

7+
#ifndef DDEBUG
8+
#define DDEBUG 0
9+
#endif
710
#include "ddebug.h"
811

12+
913
#include "ngx_http_lua_common.h"
1014
#include "api/ngx_http_lua_api.h"
15+
#include "ngx_http_lua_shdict.h"
1116
#include "ngx_http_lua_util.h"
1217

1318

@@ -29,6 +34,10 @@ ngx_http_lua_get_request(lua_State *L)
2934
}
3035

3136

37+
static ngx_int_t ngx_http_lua_shared_memory_init(ngx_shm_zone_t *shm_zone,
38+
void *data);
39+
40+
3241
ngx_int_t
3342
ngx_http_lua_add_package_preload(ngx_conf_t *cf, const char *package,
3443
lua_CFunction func)
@@ -74,4 +83,133 @@ ngx_http_lua_add_package_preload(ngx_conf_t *cf, const char *package,
7483
return NGX_OK;
7584
}
7685

86+
87+
ngx_shm_zone_t *
88+
ngx_http_lua_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size,
89+
void *tag)
90+
{
91+
ngx_http_lua_main_conf_t *lmcf;
92+
ngx_shm_zone_t **zp;
93+
ngx_shm_zone_t *zone;
94+
ngx_http_lua_shm_zone_ctx_t *ctx;
95+
ngx_int_t n;
96+
97+
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module);
98+
if (lmcf == NULL) {
99+
return NULL;
100+
}
101+
102+
if (lmcf->shm_zones == NULL) {
103+
lmcf->shm_zones = ngx_palloc(cf->pool, sizeof(ngx_array_t));
104+
if (lmcf->shm_zones == NULL) {
105+
return NULL;
106+
}
107+
108+
if (ngx_array_init(lmcf->shm_zones, cf->pool, 2,
109+
sizeof(ngx_shm_zone_t *))
110+
!= NGX_OK)
111+
{
112+
return NULL;
113+
}
114+
}
115+
116+
zone = ngx_shared_memory_add(cf, name, (size_t) size, tag);
117+
if (zone == NULL) {
118+
return NULL;
119+
}
120+
121+
if (zone->data) {
122+
ctx = (ngx_http_lua_shm_zone_ctx_t *) zone->data;
123+
return &ctx->zone;
124+
}
125+
126+
n = sizeof(ngx_http_lua_shm_zone_ctx_t);
127+
128+
ctx = ngx_pcalloc(cf->pool, n);
129+
if (ctx == NULL) {
130+
return NULL;
131+
}
132+
133+
ctx->lmcf = lmcf;
134+
ctx->log = &cf->cycle->new_log;
135+
ctx->cycle = cf->cycle;
136+
137+
ngx_memcpy(&ctx->zone, zone, sizeof(ngx_shm_zone_t));
138+
139+
zp = ngx_array_push(lmcf->shm_zones);
140+
if (zp == NULL) {
141+
return NULL;
142+
}
143+
144+
*zp = zone;
145+
146+
/* set zone init */
147+
zone->init = ngx_http_lua_shared_memory_init;
148+
zone->data = ctx;
149+
150+
lmcf->requires_shm = 1;
151+
152+
return &ctx->zone;
153+
}
154+
155+
156+
static ngx_int_t
157+
ngx_http_lua_shared_memory_init(ngx_shm_zone_t *shm_zone, void *data)
158+
{
159+
ngx_http_lua_shm_zone_ctx_t *octx = data;
160+
ngx_shm_zone_t *ozone;
161+
void *odata;
162+
163+
ngx_int_t rc;
164+
volatile ngx_cycle_t *saved_cycle;
165+
ngx_http_lua_main_conf_t *lmcf;
166+
ngx_http_lua_shm_zone_ctx_t *ctx;
167+
ngx_shm_zone_t *zone;
168+
169+
ctx = (ngx_http_lua_shm_zone_ctx_t *) shm_zone->data;
170+
zone = &ctx->zone;
171+
172+
odata = NULL;
173+
if (octx) {
174+
ozone = &octx->zone;
175+
odata = ozone->data;
176+
}
177+
178+
zone->shm = shm_zone->shm;
179+
zone->noreuse = shm_zone->noreuse;
180+
181+
if (zone->init(zone, odata) != NGX_OK) {
182+
return NGX_ERROR;
183+
}
184+
185+
dd("get lmcf");
186+
187+
lmcf = ctx->lmcf;
188+
if (lmcf == NULL) {
189+
return NGX_ERROR;
190+
}
191+
192+
dd("lmcf->lua: %p", lmcf->lua);
193+
194+
lmcf->shm_zones_inited++;
195+
196+
if (lmcf->shm_zones_inited == lmcf->shm_zones->nelts
197+
&& lmcf->init_handler)
198+
{
199+
saved_cycle = ngx_cycle;
200+
ngx_cycle = ctx->cycle;
201+
202+
rc = lmcf->init_handler(ctx->log, lmcf, lmcf->lua);
203+
204+
ngx_cycle = saved_cycle;
205+
206+
if (rc != NGX_OK) {
207+
/* an error happened */
208+
return NGX_ERROR;
209+
}
210+
}
211+
212+
return NGX_OK;
213+
}
214+
77215
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

src/ngx_http_lua_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ struct ngx_http_lua_main_conf_s {
172172

173173
ngx_array_t *shm_zones; /* of ngx_shm_zone_t* */
174174

175+
ngx_array_t *shdict_zones; /* shm zones of "shdict" */
176+
175177
ngx_array_t *preload_hooks; /* of ngx_http_lua_preload_hook_t */
176178

177179
ngx_flag_t postponed_to_rewrite_phase_end;

src/ngx_http_lua_directive.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ngx_http_lua_shdict.h"
2727
#include "ngx_http_lua_ssl_certby.h"
2828
#include "ngx_http_lua_lex.h"
29+
#include "api/ngx_http_lua_api.h"
2930

3031

3132
typedef struct ngx_http_lua_block_parser_ctx_s
@@ -78,13 +79,13 @@ ngx_http_lua_shared_dict(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
7879
ngx_http_lua_shdict_ctx_t *ctx;
7980
ssize_t size;
8081

81-
if (lmcf->shm_zones == NULL) {
82-
lmcf->shm_zones = ngx_palloc(cf->pool, sizeof(ngx_array_t));
83-
if (lmcf->shm_zones == NULL) {
82+
if (lmcf->shdict_zones == NULL) {
83+
lmcf->shdict_zones = ngx_palloc(cf->pool, sizeof(ngx_array_t));
84+
if (lmcf->shdict_zones == NULL) {
8485
return NGX_CONF_ERROR;
8586
}
8687

87-
if (ngx_array_init(lmcf->shm_zones, cf->pool, 2,
88+
if (ngx_array_init(lmcf->shdict_zones, cf->pool, 2,
8889
sizeof(ngx_shm_zone_t *))
8990
!= NGX_OK)
9091
{
@@ -120,10 +121,9 @@ ngx_http_lua_shared_dict(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
120121
ctx->name = name;
121122
ctx->main_conf = lmcf;
122123
ctx->log = &cf->cycle->new_log;
123-
ctx->cycle = cf->cycle;
124124

125-
zone = ngx_shared_memory_add(cf, &name, (size_t) size,
126-
&ngx_http_lua_module);
125+
zone = ngx_http_lua_shared_memory_add(cf, &name, (size_t) size,
126+
&ngx_http_lua_module);
127127
if (zone == NULL) {
128128
return NGX_CONF_ERROR;
129129
}
@@ -140,7 +140,7 @@ ngx_http_lua_shared_dict(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
140140
zone->init = ngx_http_lua_shdict_init_zone;
141141
zone->data = ctx;
142142

143-
zp = ngx_array_push(lmcf->shm_zones);
143+
zp = ngx_array_push(lmcf->shdict_zones);
144144
if (zp == NULL) {
145145
return NGX_CONF_ERROR;
146146
}

src/ngx_http_lua_module.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
821821
* lmcf->init_handler = NULL;
822822
* lmcf->init_src = { 0, NULL };
823823
* lmcf->shm_zones_inited = 0;
824+
* lmcf->shdict_zones = NULL;
824825
* lmcf->preload_hooks = NULL;
825826
* lmcf->requires_header_filter = 0;
826827
* lmcf->requires_body_filter = 0;

src/ngx_http_lua_shdict.c

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ ngx_http_lua_shdict_init_zone(ngx_shm_zone_t *shm_zone, void *data)
8484
ngx_http_lua_shdict_ctx_t *octx = data;
8585

8686
size_t len;
87-
ngx_int_t rc;
88-
volatile ngx_cycle_t *saved_cycle;
8987
ngx_http_lua_shdict_ctx_t *ctx;
90-
ngx_http_lua_main_conf_t *lmcf;
9188

9289
dd("init zone");
9390

@@ -97,15 +94,15 @@ ngx_http_lua_shdict_init_zone(ngx_shm_zone_t *shm_zone, void *data)
9794
ctx->sh = octx->sh;
9895
ctx->shpool = octx->shpool;
9996

100-
goto done;
97+
return NGX_OK;
10198
}
10299

103100
ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
104101

105102
if (shm_zone->shm.exists) {
106103
ctx->sh = ctx->shpool->data;
107104

108-
goto done;
105+
return NGX_OK;
109106
}
110107

111108
ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_lua_shdict_shctx_t));
@@ -134,32 +131,6 @@ ngx_http_lua_shdict_init_zone(ngx_shm_zone_t *shm_zone, void *data)
134131
ctx->shpool->log_nomem = 0;
135132
#endif
136133

137-
done:
138-
139-
dd("get lmcf");
140-
141-
lmcf = ctx->main_conf;
142-
143-
dd("lmcf->lua: %p", lmcf->lua);
144-
145-
lmcf->shm_zones_inited++;
146-
147-
if (lmcf->shm_zones_inited == lmcf->shm_zones->nelts
148-
&& lmcf->init_handler)
149-
{
150-
saved_cycle = ngx_cycle;
151-
ngx_cycle = ctx->cycle;
152-
153-
rc = lmcf->init_handler(ctx->log, lmcf, lmcf->lua);
154-
155-
ngx_cycle = saved_cycle;
156-
157-
if (rc != NGX_OK) {
158-
/* an error happened */
159-
return NGX_ERROR;
160-
}
161-
}
162-
163134
return NGX_OK;
164135
}
165136

@@ -355,8 +326,8 @@ ngx_http_lua_inject_shdict_api(ngx_http_lua_main_conf_t *lmcf, lua_State *L)
355326
ngx_uint_t i;
356327
ngx_shm_zone_t **zone;
357328

358-
if (lmcf->shm_zones != NULL) {
359-
lua_createtable(L, 0, lmcf->shm_zones->nelts /* nrec */);
329+
if (lmcf->shdict_zones != NULL) {
330+
lua_createtable(L, 0, lmcf->shdict_zones->nelts /* nrec */);
360331
/* ngx.shared */
361332

362333
lua_createtable(L, 0 /* narr */, 18 /* nrec */); /* shared mt */
@@ -415,9 +386,9 @@ ngx_http_lua_inject_shdict_api(ngx_http_lua_main_conf_t *lmcf, lua_State *L)
415386
lua_pushvalue(L, -1); /* shared mt mt */
416387
lua_setfield(L, -2, "__index"); /* shared mt */
417388

418-
zone = lmcf->shm_zones->elts;
389+
zone = lmcf->shdict_zones->elts;
419390

420-
for (i = 0; i < lmcf->shm_zones->nelts; i++) {
391+
for (i = 0; i < lmcf->shdict_zones->nelts; i++) {
421392
ctx = zone[i]->data;
422393

423394
lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len);
@@ -2202,6 +2173,7 @@ ngx_http_lua_find_zone(u_char *name_data, size_t name_len)
22022173
ngx_str_t *name;
22032174
ngx_uint_t i;
22042175
ngx_shm_zone_t *zone;
2176+
ngx_http_lua_shm_zone_ctx_t *ctx;
22052177
volatile ngx_list_part_t *part;
22062178

22072179
part = &ngx_cycle->shared_memory.part;
@@ -2227,7 +2199,8 @@ ngx_http_lua_find_zone(u_char *name_data, size_t name_len)
22272199
if (name->len == name_len
22282200
&& ngx_strncmp(name->data, name_data, name_len) == 0)
22292201
{
2230-
return &zone[i];
2202+
ctx = (ngx_http_lua_shm_zone_ctx_t *) zone[i].data;
2203+
return &ctx->zone;
22312204
}
22322205
}
22332206

src/ngx_http_lua_shdict.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,17 @@ typedef struct {
4444
ngx_str_t name;
4545
ngx_http_lua_main_conf_t *main_conf;
4646
ngx_log_t *log;
47-
ngx_cycle_t *cycle;
4847
} ngx_http_lua_shdict_ctx_t;
4948

5049

50+
typedef struct {
51+
ngx_log_t *log;
52+
ngx_http_lua_main_conf_t *lmcf;
53+
ngx_cycle_t *cycle;
54+
ngx_shm_zone_t zone;
55+
} ngx_http_lua_shm_zone_ctx_t;
56+
57+
5158
ngx_int_t ngx_http_lua_shdict_init_zone(ngx_shm_zone_t *shm_zone, void *data);
5259
void ngx_http_lua_shdict_rbtree_insert_value(ngx_rbtree_node_t *temp,
5360
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

t/043-shdict.t

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use Test::Nginx::Socket::Lua;
77

88
#repeat_each(2);
99

10-
plan tests => repeat_each() * (blocks() * 3 + 18);
10+
plan tests => repeat_each() * (blocks() * 3 + 17);
1111

1212
#no_diff();
1313
no_long_string();
@@ -2448,3 +2448,26 @@ GET /test
24482448
--- error_code: 500
24492449
--- error_log
24502450
bad "exptime" argument
2451+
2452+
2453+
2454+
=== TEST 93: duplicate zones
2455+
--- http_config
2456+
lua_shared_dict dogs 1m;
2457+
lua_shared_dict dogs 1m;
2458+
--- config
2459+
location = /test {
2460+
content_by_lua '
2461+
local dogs = ngx.shared.dogs
2462+
ngx.say("error")
2463+
';
2464+
}
2465+
--- request
2466+
GET /test
2467+
--- request_body_unlike
2468+
error
2469+
--- must_die
2470+
--- error_log
2471+
lua_shared_dict "dogs" is already defined as "dogs"
2472+
--- error_log
2473+
[emerg]

0 commit comments

Comments
 (0)