Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev ][Date Next ][Thread Prev ][Thread Next ][Date Index ][Thread Index ]
Re: perl_set var sub '.. и пере конфигурация
On Sat, 6 May 2006, Alex Tutubalin wrote:
уж не знаю, бага это или фича, но при использовании
perl_set $variable 'sub {...}'; не получается поменять
эту самую sub и переконфигурироваться через SIGHUP,
приходится останавливать/запускать (наверное,
апгрейд бинарника тоже поможет)
0.3.44
Да, есть такая проблема, если перл собран без multiplicity или трэдов.
Прилагаемый патч решает эту проблему, а также устраняет часть memory leaks
при переконфигурировании. Немного утечек остаётся, пока не могу понять -
моё это или перловое.
Игорь Сысоев
http://sysoev.ru --- src/http/modules/perl/ngx_http_perl_module.c Thu Apr 20 12:52:16 2006
+++ src/http/modules/perl/ngx_http_perl_module.c Sat May 6 22:48:50 2006
@@ -51,6 +51,8 @@
static PerlInterpreter *
ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
ngx_log_t *log);
+static ngx_int_t ngx_http_perl_run_requires(ngx_array_t *requires,
+ ngx_log_t *log);
static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv);
static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv);
@@ -67,7 +69,10 @@
static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post,
void *data);
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
static void ngx_http_perl_cleanup_perl(void *data);
+#endif
+static void ngx_http_perl_cleanup_sv(void *data);
static ngx_conf_post_handler_pt ngx_http_perl_interp_max_p =
@@ -394,22 +399,6 @@
dTHXa(ctx->perl);
-#if 0
-
- ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv);
-
- if (sv == &PL_sv_undef) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "eval_pv(\"%V\") failed", handler);
- return NGX_ERROR;
- }
-
- if (sv == NULL) {
- sv = newSVpvn((char *) handler->data, handler->len);
- }
-
-#endif
-
sv = newSVpvn((char *) handler->data, handler->len);
rc = ngx_http_perl_call_handler(aTHX_ r, sv,
¶ms[NGX_HTTP_PERL_SSI_ARG],
@@ -470,13 +459,18 @@
static char *
ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
{
- ngx_pool_cleanup_t *cln;
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+ ngx_pool_cleanup_t *cln;
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NGX_CONF_ERROR;
}
+#else
+ static PerlInterpreter *perl;
+#endif
+
#ifdef NGX_PERL_MODULES
if (pmcf->modules.data == NULL) {
pmcf->modules.data = NGX_PERL_MODULES;
@@ -489,6 +483,20 @@
}
}
+#if !(NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
+ if (perl) {
+ if (ngx_http_perl_run_requires(&pmcf->requires, cf->log) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ pmcf->perl = perl;
+
+ return NGX_CONF_OK;
+ }
+
+#endif
+
PERL_SYS_INIT(&ngx_argc, &ngx_argv);
pmcf->perl = ngx_http_perl_create_interpreter(pmcf, cf->log);
@@ -498,9 +506,17 @@
return NGX_CONF_ERROR;
}
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
cln->handler = ngx_http_perl_cleanup_perl;
cln->data = pmcf->perl;
+#else
+
+ perl = pmcf->perl;
+
+#endif
+
return NGX_CONF_OK;
}
@@ -511,10 +527,6 @@
{
int n;
char *embedding[6];
- char **script;
- STRLEN len;
- ngx_str_t err;
- ngx_uint_t i;
PerlInterpreter *perl;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter");
@@ -583,22 +595,8 @@
goto fail;
}
- script = pmcf->requires.elts;
- for (i = 0; i < pmcf->requires.nelts; i++) {
- require_pv(script[i]);
-
- if (SvTRUE(ERRSV)) {
-
- err.data = (u_char *) SvPV(ERRSV, len);
- for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
- /* void */
- }
- err.len = len + 1;
-
- ngx_log_error(NGX_LOG_EMERG, log, 0,
- "require_pv(\"%s\") failed: \"%V\"", script[i],
&err);
- goto fail;
- }
+ if (ngx_http_perl_run_requires(&pmcf->requires, log) != NGX_OK) {
+ goto fail;
}
}
@@ -617,6 +615,38 @@
}
+static ngx_int_t
+ngx_http_perl_run_requires(ngx_array_t *requires, ngx_log_t *log)
+{
+ char **script;
+ STRLEN len;
+ ngx_str_t err;
+ ngx_uint_t i;
+
+ script = requires->elts;
+ for (i = 0; i < requires->nelts; i++) {
+
+ require_pv(script[i]);
+
+ if (SvTRUE(ERRSV)) {
+
+ err.data = (u_char *) SvPV(ERRSV, len);
+ for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
+ /* void */
+ }
+ err.len = len + 1;
+
+ ngx_log_error(NGX_LOG_EMERG, log, 0,
+ "require_pv(\"%s\") failed: \"%V\"", script[i],
&err);
+
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
#if (__INTEL_COMPILER)
/*
* disable 'declaration hides parameter "my_perl"' warning for ENTER and LEAVE
@@ -740,11 +770,8 @@
}
}
- if (ngx_strncmp(p, "sub ", 4) == 0
- || ngx_strncmp(p, "use ", 4) == 0)
- {
+ if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {
*sv = eval_pv((char *) p, FALSE);
-
return;
}
@@ -805,10 +832,12 @@
}
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
static void
ngx_http_perl_cleanup_perl(void *data)
{
- PerlInterpreter *perl = data;
+ PerlInterpreter *perl = data;
(void) perl_destruct(perl);
@@ -817,6 +846,17 @@
PERL_SYS_TERM();
}
+#endif
+
+
+static void
+ngx_http_perl_cleanup_sv(void *data)
+{
+ SV *sv = data;
+
+ SvREFCNT_dec(sv);
+}
+
static ngx_int_t
ngx_http_perl_preconfiguration(ngx_conf_t *cf)
@@ -908,6 +948,7 @@
ngx_http_perl_loc_conf_t *plcf = conf;
ngx_str_t *value;
+ ngx_pool_cleanup_t *cln;
ngx_http_core_loc_conf_t *clcf;
ngx_http_perl_main_conf_t *pmcf;
@@ -927,6 +968,11 @@
}
}
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
plcf->handler = value[1];
{
@@ -947,6 +993,9 @@
}
+ cln->handler = ngx_http_perl_cleanup_sv;
+ cln->data = plcf->sub;
+
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_perl_handler;
@@ -959,6 +1008,7 @@
{
ngx_int_t index;
ngx_str_t *value;
+ ngx_pool_cleanup_t *cln;
ngx_http_variable_t *v;
ngx_http_perl_variable_t *pv;
ngx_http_perl_main_conf_t *pmcf;
@@ -997,6 +1047,11 @@
}
}
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
pv->handler = value[2];
{
@@ -1016,6 +1071,9 @@
}
}
+
+ cln->handler = ngx_http_perl_cleanup_sv;
+ cln->data = pv->sub;
v->get_handler = ngx_http_perl_variable;
v->data = (uintptr_t) pv;