]> git.kaiwu.me - nginx.git/commitdiff
Perl: added PERL_SET_INTERP().
authorMaxim Dounin <mdounin@mdounin.ru>
Wed, 7 Dec 2016 16:03:19 +0000 (19:03 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Wed, 7 Dec 2016 16:03:19 +0000 (19:03 +0300)
For Perl compiled with threads, without PERL_SET_INTERP() the PL_curinterp
remains set to the first interpreter created (that is, one created at
original start).  As a result after a reload Perl thinks that operations
are done withing a thread, and, most notably, denies to change environment.

For example, the following code properly works on original start,
but fails after a reload:

    perl 'sub {
        my $r = shift;

        $r->send_http_header("text/plain");

        $ENV{TZ} = "UTC";
        $r->print("tz: " . $ENV{TZ} . " (localtime " . (localtime()) . ")\n");
        $ENV{TZ} = "Europe/Moscow";
        $r->print("tz: " . $ENV{TZ} . " (localtime " . (localtime()) . ")\n");

        return OK;
    }';

To fix this, PERL_SET_INTERP() added anywhere where PERL_SET_CONTEXT()
was previously used.

Note that PERL_SET_INTERP() doesn't seem to be documented anywhere.
Yet it is used in some other software, and also seems to be the only
solution possible.

src/http/modules/perl/ngx_http_perl_module.c

index f9a9a84c05172f633e46bb84544a50981dcb0933..279631974b43e9ae70a5508d941737d61e29792e 100644 (file)
@@ -207,6 +207,7 @@ ngx_http_perl_handle_request(ngx_http_request_t *r)
 
     dTHXa(pmcf->perl);
     PERL_SET_CONTEXT(pmcf->perl);
+    PERL_SET_INTERP(pmcf->perl);
 
     if (ctx->next == NULL) {
         plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module);
@@ -322,6 +323,7 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
     dTHXa(pmcf->perl);
     PERL_SET_CONTEXT(pmcf->perl);
+    PERL_SET_INTERP(pmcf->perl);
 
     rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL,
                                     &pv->handler, &value);
@@ -387,6 +389,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
 
     dTHXa(pmcf->perl);
     PERL_SET_CONTEXT(pmcf->perl);
+    PERL_SET_INTERP(pmcf->perl);
 
 #if 0
 
@@ -568,6 +571,7 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
 
     dTHXa(perl);
     PERL_SET_CONTEXT(perl);
+    PERL_SET_INTERP(perl);
 
     perl_construct(perl);
 
@@ -828,6 +832,7 @@ ngx_http_perl_cleanup_perl(void *data)
     PerlInterpreter  *perl = data;
 
     PERL_SET_CONTEXT(perl);
+    PERL_SET_INTERP(perl);
 
     (void) perl_destruct(perl);
 
@@ -936,6 +941,7 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     dTHXa(pmcf->perl);
     PERL_SET_CONTEXT(pmcf->perl);
+    PERL_SET_INTERP(pmcf->perl);
 
     ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub);
 
@@ -1007,6 +1013,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     dTHXa(pmcf->perl);
     PERL_SET_CONTEXT(pmcf->perl);
+    PERL_SET_INTERP(pmcf->perl);
 
     ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub);
 
@@ -1039,6 +1046,7 @@ ngx_http_perl_init_worker(ngx_cycle_t *cycle)
     if (pmcf) {
         dTHXa(pmcf->perl);
         PERL_SET_CONTEXT(pmcf->perl);
+        PERL_SET_INTERP(pmcf->perl);
 
         /* set worker's $$ */