Use PL_sv_yes & PL_sv_no instead of newSViv(1) & newSViv(0) for bools
as they're interpreter globals that don't need to be created everytime.
Added a test and refactored the tests that were added with a1e30157,
all .t files in t/perl are now ran under all major perl versions with
and without threading when t/perl/run is invoked.
On my box, psgi_plugin.o went from 62,296 bytes to 62,208 bytes. Not a
huge saving I'll grant you, but every little helps :-)
Commit ff9bab4b fixed support for sending IO like handles or GLOBs
via sendfile by first calling fileno on them. This was checked
by calling Scalar::Util::reftype on the reference first, as per
https://metacpan.org/pod/PSGI#Body . This may be sane in pure
perl, but there are better methods in XS/C than string evalling
some Perl, which will eventually also call some XS/C.
This commit introduces more robust checking of whether we have a
"real" filehandle, and also introduces a test that chucks a bunch
of different scalars and references at uWSGI to make sure it doesn't
choke. I wasn't sure how to hook this test up to travis, or wether
that's even desireable, so just left the test in what I believe to
be the right directories.
Because this commit massively simplifies the code, it also had an
effect on object size, on my machine (x64, GCC 4.9), psgi_plugin.o
went from 63360 bytes to 62296 bytes.
The indentation level of the ->getline for loop has been left at
its original level, which is now incorrect, to make the diff
easier to read. A whitespace cleanup commit could follow.
In related news, does anyone know the purpose of the three other
use lines in psgi_loader.c, two of them were added back in 2011
by cf08972e, but I can't work out what their inclusion has to do
with memleak hunting.
Basically I would love to remove these lines as I don't believe
they're needed for uWSGI to function, and if apps running under
uWSGI need them, they should load them themselves.
Also related, would more PSGI refactorings be welcome? I get the
impression that Perl is a bit of a second class citizen in uWSGI
these days, and as both an avid user of uWSGI+PSGI and a hobby XS
developer, I'd love to clean up more of the PSGI plugin.
This should make it easier to understand why a worker is shutting down.
* Modify `goodbye_cruel_world` to accept a `reason` format string and
varargs.
* Modify calls to the above function to include a verbose reason string.
* Modify the `gbcw_hook` used by the Gevent plugin to adhere to the new
API.
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.
preliminary api for language-independent body read
another step
completed body read language independent implementation
ported gevent to the new read/write api
ported websockets to the new read/write api
removed channels subsystem
removed channels subsystem
ported lua to the new read/write api
fixed post-buffering
readline is still broken
improved request body readline
very difficult test for readline()/read() combo passed
other improvements in postbuffering/read/readline
ported --http-socket to the new api
added X-Forwarded-SSL management
removed old api
more refactoring
ported the RACK plugin to the new api
ported psgi plugin to the new api
defintely removed clustering
simpified ifdel hell
simpified ifdef hell
removed useless configuration options