My previous commit ensured that we called the DESTROY hook but we
wouldn't properly call the atexit hook. Now when you start uWSGI as
instructed in that commit you'll get this:
* localhost:1234?0:
$$: Calling DESTROY
* localhost:1234?1:
*** psgix.harakiri.commit requested ***
...The work of process 523 is done. Seeya!
523: Calling the atexit hook
523: Calling DESTROY
* Ctrl+C (or stop):
^CSIGINT/SIGQUIT received...killing workers...
696: Calling the atexit hook
Before this change we wouldn't call the atexit hook when
psgix.harakiri.commit was requested by calling localhost:1234?1.
To make this work I removed the "if busy do not run atexit hooks"
condition added in 1.4-rc2-246-g499202e. Of course uWSGI is going to
think the worker is "busy", it's busy being destroyed, that doesn't mean
we should skip running the atexit hooks.
We'll still skip them under the "if hijacked do not run atexit hooks"
condition added in that commit, and the "managing atexit in async mode
is a real pain" condition added in 1.0.1-289-gd7e8523. Maybe those are
further bugs that need to be solved, but I don't know how to test those
modes.
Now we'll also call PERL_SET_CONTEXT() and PERL_SYS_TERM() appropriately
during destruction. Note that the latter should only be called once even
if you have multiple interpreters.
Before this we'd just exit(0) and let the OS clean up after us, but
e.g. with post-buffering=1 we'll end up with a temporary file in /tmp
that we won't clean up when we exit unless DESTROY is called.
This resulted in us leaking files in /tmp if we ever had a request where
the last request before a harakiri was a POST request with a body we'd
buffer to /tmp.
We'd have similar leaks in any user-defined code that required DESTROY
to run.
Aside from this I'm still not very comfortable with what this whole code
here in psgi_plugin.c and psgi_loader.c is doing when managing the
interpreter(s). It:
* Doesn't consistently call PERL_SET_CONTEXT() as described in "perldoc
perlembed".
* Nothing calls PERL_SYS_TERM() either.
* Should we be calling uwsgi_perl_free_stashes() here too?
To test this:
UWSGI_PROFILE=psgi python uwsgiconfig.py --build
./uwsgi --master --http-socket localhost:1234 --psgi t/perl/test_harakiri.psgi
Then elsewhere:
curl 'localhost:1234?0'
curl 'localhost:1234?1'
Both of those should emit "Calling DESTROY".
It can be reproduced by enabling the Perl debugger inside a PSGI application:
{
package DB;
sub DB { }
sub sub { &$sub }
}
$^P = 0x73f;
sub { [200, ['Content-Type' => 'text/plain'], ['Hello World']] }
For every request the following warnings are emitted:
Attempt to free unreferenced scalar: SV 0xfea6e8, Perl interpreter: 0xd534a0.
Attempt to free unreferenced scalar: SV 0xfea718, Perl interpreter: 0xd534a0.
where the unreferenced scalars are the uwsgi::input/uwsgi::error instances
created in build_psgi_env.
The calling convention for Perl subroutines is that the values pushed on the
stack must be mortalized in the callee, and if the caller wants to retain them,
it must do a SvREFCNT_inc to undo the effect of the mortalization.
Before this patch XS_input/XS_error were not mortalizing the value, and
uwsgi_perl_obj_new was not incrementing the reference count, so the two bugs
balanced each other.
When running under debugger, Perl forwards all function/method calls to
DB::sub, which causes a mortal copy of the return value of
uwsgi::input/error::new to be pushed on the stack. The value is cleared by the
FREETMPS at the end of uwsgi_perl_obj_new, and the freed value is added to the
environment hash. The warning is emitted at the end of the request when the
environment hash is freed and Perl notices that some of the values has been
already freed.
newRV(sv_newmortal()) is equivalent to newRV_noinc(newSV(0)): the former
creates a new SV with refcount 1, schedules a decrement "soon" (the
mortalization) and increments the refcount, the net result is a refcount of 1,
which is what the latter does.
According to http://ceph.com/docs/master/rados/api/librados/ rados_write Returns: 0 on success, negative error code on failure. When using <= comparsion, PUT method always ends with ISE 500.
Extends the logfile plugin sntax to accept a key value string.
Supported values are:
- logfile, the actual file name of the log file (mandatory)
- backupname, the file name of the rotated log
- maxsize, the size in bytes that triggers rotation
maxsize is mandatory if you want rotation, if you omit backupname the logfile with a
timestamp appended would be used as file name.
Example:
logger = staticlogger file:logfile=%dstatic.log,backupname=%dstatic.log.old,maxsize=1500
log-route = staticlogger app: -1|req: -1
will create a file based logger called static logger that would log
all the static requests to a file called static.log, which would be
rotated each 1500 bytes to a file named static.log.old
Fixes#542
Introduce a couple of helpers to reduce duplicated code.
Before:
text data bss dec hex filename
9742 180 0 9922 26c2 plugins/rpc/rpc_plugin.o
After:
text data bss dec hex filename
9230 180 0 9410 24c2 plugins/rpc/rpc_plugin.o
My compiler inlines so uwsgi_rpc_get_remote it does make difference
in practice still it makes the code prettier.