mirror of
https://github.com/openresty/openresty.git
synced 2024-10-13 00:29:41 +00:00
Compare commits
135 Commits
Author | SHA1 | Date | |
---|---|---|---|
b03099b386 | |||
cbfbd19460 | |||
e921c6e9b1 | |||
365c7d9d9e | |||
5d01a5e0b4 | |||
e478681308 | |||
e254c3d0c1 | |||
dbccee1418 | |||
efe10e532c | |||
6343d26c17 | |||
8ffd932b20 | |||
6cb4ae0de3 | |||
6c8f4f87ba | |||
d7f84c9079 | |||
4f2bf44aba | |||
a4640d68f1 | |||
69803153aa | |||
b488540a2f | |||
b37d406423 | |||
dc03e7641b | |||
2900286149 | |||
b1c3587c50 | |||
5163293260 | |||
1815637613 | |||
fd667d6369 | |||
ae8e36ae77 | |||
e2a735c481 | |||
7571924cd2 | |||
abd91310df | |||
edcdb450f4 | |||
ed140425aa | |||
949ad066d6 | |||
a0e7a6a9fa | |||
45700de84a | |||
8269bbfb3a | |||
6c5e27c40e | |||
d7d0d17a2f | |||
be80ceb08b | |||
e2fa208541 | |||
7321a6af98 | |||
6973ad7234 | |||
5c57aed170 | |||
4253dd2b90 | |||
381697b884 | |||
97901f3357 | |||
09ca92f51f | |||
bf0e5bdef0 | |||
961eb11536 | |||
697bb0a08c | |||
9455250873 | |||
5429150ab6 | |||
8d76d5910f | |||
9fa2d93c6b | |||
99f0618218 | |||
7c274e056e | |||
8d8a2529ad | |||
2369d00d46 | |||
e9c8fb30f2 | |||
e63984f81d | |||
7ce3d4e881 | |||
20c164f5e7 | |||
568d1e0e5d | |||
0e9ed23bf5 | |||
d3506c60aa | |||
f05b909f11 | |||
b321c89392 | |||
c47aef193f | |||
d6a8907fc0 | |||
bf47ba9529 | |||
b603282bd6 | |||
a6c3a0f21e | |||
7123e4f0df | |||
a924c2d9aa | |||
05dc2dc32a | |||
8091435d3f | |||
d4d2397011 | |||
c7ec3e0b5b | |||
b01018e897 | |||
9ef51f89be | |||
853c13c46f | |||
33cf50beae | |||
d2e85ffb13 | |||
64971a1336 | |||
57924dc487 | |||
592aa6fec5 | |||
5edc89c7be | |||
665faf0aea | |||
07dc137193 | |||
20a6484f71 | |||
e4af1abdc3 | |||
6229590201 | |||
5ca7a403b9 | |||
d915ad9427 | |||
d0b0e7e1fc | |||
57984e23f8 | |||
03ec98a39e | |||
63e116b90b | |||
a98bfe8325 | |||
7af6c9b12c | |||
9dd706ad03 | |||
2589f0d3c1 | |||
0e2f55d2a0 | |||
6160254ec8 | |||
d836ee1e8e | |||
fb040b60db | |||
7f5a1fa7e4 | |||
7a2e4881b8 | |||
bdaea38b7d | |||
741ff983e8 | |||
a9cada5c27 | |||
1b197fb27a | |||
86be514b1c | |||
3041624fbc | |||
de75e4d7ed | |||
107847d6fd | |||
36bafb83ed | |||
f4ca954418 | |||
6f8aba9da3 | |||
2436ab0b8c | |||
c05b97fcad | |||
6dd13af2a1 | |||
aa6c86f46a | |||
74940ddd15 | |||
7d9e51e1b3 | |||
e4cfb92295 | |||
7f9675a005 | |||
71ece286fa | |||
54c2766d1c | |||
3da92ac16c | |||
463a6a14ee | |||
5f7f678876 | |||
753ef7074b | |||
8c6b0f77af | |||
52962f3fc9 | |||
0e31ce1662 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -66,6 +66,7 @@ util/blog-rows.sql
|
||||
util/comments.sql
|
||||
util/posts.sql
|
||||
ngx_openresty-*
|
||||
openresty-*
|
||||
work/
|
||||
reindex
|
||||
t/*.t_
|
||||
@ -73,3 +74,4 @@ upload
|
||||
upload-win32
|
||||
html_out/
|
||||
TODO
|
||||
doc/LuaJIT-2.1/changes.pod
|
||||
|
6
Makefile
6
Makefile
@ -3,12 +3,12 @@
|
||||
all:
|
||||
./util/mirror-tarballs
|
||||
|
||||
test: all
|
||||
test:
|
||||
prove -r t
|
||||
|
||||
try-luajit: all
|
||||
cd ngx_openresty-`./util/ver` && ./configure --with-luajit
|
||||
cd openresty-`./util/ver` && ./configure --with-luajit
|
||||
|
||||
try-lua: all
|
||||
cd ngx_openresty-`./util/ver` && ./configure && $(MAKE)
|
||||
cd openresty-`./util/ver` && ./configure && $(MAKE)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
Name
|
||||
====
|
||||
|
||||
ngx_openresty - Turning Nginx into a Full-Fledged Scriptable Web Platform
|
||||
OpenResty - Turning Nginx into a Full-Fledged Scriptable Web Platform
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
@ -17,7 +17,7 @@ Table of Contents
|
||||
Description
|
||||
===========
|
||||
|
||||
ngx_openresty is a full-fledged web application server by bundling the standard nginx core,
|
||||
OpenResty is a full-fledged web application server by bundling the standard nginx core,
|
||||
lots of 3rd-party nginx modules, as well as most of their external dependencies.
|
||||
|
||||
This bundle is maintained Yichun Zhang (agentzh).
|
||||
@ -27,20 +27,21 @@ that all these modules are played well together.
|
||||
|
||||
The bundled software components are copyrighted by the respective copyright holders.
|
||||
|
||||
The homepage for this project is http://openresty.org.
|
||||
The homepage for this project is on [openresty.org](https://openresty.org/).
|
||||
|
||||
For Users
|
||||
---------
|
||||
|
||||
Visit http://openresty.org/#Download to download the latest bundle tarball, and
|
||||
follow the installation instructions in the page http://openresty.org/#Installation.
|
||||
Visit the [download page](https://openresty.org/en/download.html) on the `openresty.org` web site
|
||||
to download the latest bundle tarball, and
|
||||
follow the installation instructions in the [installation page](https://openresty.org/en/installation.html).
|
||||
|
||||
For Bundle Maintainers
|
||||
----------------------
|
||||
|
||||
The bundle's source is at the following git repository:
|
||||
|
||||
https://github.com/openresty/ngx_openresty
|
||||
https://github.com/openresty/openresty
|
||||
|
||||
To reproduce the bundle tarball, just do
|
||||
|
||||
@ -50,13 +51,12 @@ make
|
||||
|
||||
at the top of the bundle source tree.
|
||||
|
||||
Please note that you may need to install some extra dependencies, like `perl`, `dos2unix` and
|
||||
the Perl CPAN mdoule `Markdown::Pod`. On Fedora 22, for example, installing the dependencies
|
||||
Please note that you may need to install some extra dependencies, like `perl` and `dos2unix`.
|
||||
On Fedora 22, for example, installing the dependencies
|
||||
is as simple as running the following commands:
|
||||
|
||||
```bash
|
||||
sudo dnf install perl dos2unix
|
||||
sudo cpan Markdown::Pod
|
||||
```
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
@ -79,7 +79,7 @@ Report Bugs
|
||||
|
||||
You're very welcome to report issues on GitHub:
|
||||
|
||||
https://github.com/agentzh/ngx_openresty/issues
|
||||
https://github.com/openresty/openresty/issues
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
||||
@ -88,7 +88,7 @@ Copyright & License
|
||||
|
||||
The bundle itself is licensed under the 2-clause BSD license.
|
||||
|
||||
Copyright (c) 2011-2015, Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
|
||||
Copyright (c) 2011-2016, Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
|
||||
|
||||
This module is licensed under the terms of the BSD license.
|
||||
|
||||
|
@ -73,7 +73,7 @@
|
||||
<a href="site-binary.tar.gz">Compiled form (.tar.gz)</a>
|
||||
</li>
|
||||
<li class="module-list-item">
|
||||
<a target="_blank" href="http://github.com/agentzh/ngx_openresty/tree/master/demo/[% blog_owner == 'agentzh' ? "Blog" : "Blog2" %]/">
|
||||
<a target="_blank" href="http://github.com/openresty/openresty/tree/master/demo/[% blog_owner == 'agentzh' ? "Blog" : "Blog2" %]/">
|
||||
Source code (Git)
|
||||
</a>
|
||||
</li>
|
||||
|
201
doc/LuaJIT-2.1/README.pod
Normal file
201
doc/LuaJIT-2.1/README.pod
Normal file
@ -0,0 +1,201 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is a B<Just-In-Time Compiler> (JIT) for the E<rchevron> Lua
|
||||
programming language. Lua is a powerful, dynamic and light-weight
|
||||
programming language. It may be embedded or used as a general-purpose,
|
||||
stand-alone language.
|
||||
|
||||
LuaJIT is Copyright E<copy> 2005-2016 Mike Pall, released under the
|
||||
E<rchevron> MIT open source license.
|
||||
|
||||
=head2 Compatibility
|
||||
|
||||
Windows
|
||||
|
||||
Linux
|
||||
|
||||
BSD
|
||||
|
||||
OSX
|
||||
|
||||
POSIX
|
||||
|
||||
Embedded
|
||||
|
||||
Android
|
||||
|
||||
iOS
|
||||
|
||||
PS3
|
||||
|
||||
PS4
|
||||
|
||||
PS Vita
|
||||
|
||||
Xbox 360
|
||||
|
||||
Xbox One
|
||||
|
||||
GCC
|
||||
|
||||
Clang
|
||||
|
||||
LLVM
|
||||
|
||||
MSVC
|
||||
|
||||
x86
|
||||
|
||||
x64
|
||||
|
||||
ARM
|
||||
|
||||
ARM64
|
||||
|
||||
PPC
|
||||
|
||||
MIPS32
|
||||
|
||||
MIPS64
|
||||
|
||||
Lua 5.1
|
||||
|
||||
API+ABI
|
||||
|
||||
+ JIT
|
||||
|
||||
+ BitOp
|
||||
|
||||
+ FFI
|
||||
|
||||
Drop-in
|
||||
|
||||
DLL/.so
|
||||
|
||||
=head2 Overview
|
||||
|
||||
3x
|
||||
|
||||
- 100x
|
||||
|
||||
115 KB
|
||||
|
||||
VM
|
||||
|
||||
90 KB
|
||||
|
||||
JIT
|
||||
|
||||
63 KLOC
|
||||
|
||||
C
|
||||
|
||||
24 KLOC
|
||||
|
||||
ASM
|
||||
|
||||
11 KLOC
|
||||
|
||||
Lua
|
||||
|
||||
LuaJIT has been successfully used as a B<scripting middleware> in
|
||||
games, appliances, network and graphics apps, numerical simulations,
|
||||
trading platforms and many other specialty applications. It scales from
|
||||
embedded devices, smartphones, desktops up to server farms. It combines
|
||||
high flexibility with E<rchevron> high performance and an unmatched
|
||||
B<low memory footprint>.
|
||||
|
||||
LuaJIT has been in continuous development since 2005. It's widely
|
||||
considered to be B<one of the fastest dynamic language
|
||||
implementations>. It has outperformed other dynamic languages on many
|
||||
cross-language benchmarks since its first release E<mdash> often by a
|
||||
substantial margin.
|
||||
|
||||
For B<LuaJIT 2.0>, the whole VM has been rewritten from the ground up
|
||||
and relentlessly optimized for performance. It combines a B<high-speed
|
||||
interpreter>, written in assembler, with a B<state-of-the-art JIT
|
||||
compiler>.
|
||||
|
||||
An innovative B<trace compiler> is integrated with advanced, SSA-based
|
||||
optimizations and highly tuned code generation backends. A substantial
|
||||
reduction of the overhead associated with dynamic languages allows it
|
||||
to break into the performance range traditionally reserved for offline,
|
||||
static language compilers.
|
||||
|
||||
=head2 More ...
|
||||
|
||||
Please select a sub-topic in the navigation bar to learn more about
|
||||
LuaJIT.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file luajit.html
|
||||
# 8082 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
83
doc/LuaJIT-2.1/contact.pod
Normal file
83
doc/LuaJIT-2.1/contact.pod
Normal file
@ -0,0 +1,83 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Contact
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
Please send general questions to the E<rchevron> LuaJIT mailing list.
|
||||
You can also send any questions you have directly to me:
|
||||
|
||||
Contact info in image
|
||||
|
||||
=head2 Copyright
|
||||
|
||||
All documentation is Copyright E<copy> 2005-2016 Mike Pall.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file contact.html
|
||||
# 2813 bytes of input
|
||||
#Wed Jun 29 13:18:14 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
176
doc/LuaJIT-2.1/ext_c_api.pod
Normal file
176
doc/LuaJIT-2.1/ext_c_api.pod
Normal file
@ -0,0 +1,176 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Lua/C API Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT
|
||||
include directory must be in the compiler search path (C<-II<path>>) to
|
||||
be able to include the required header for C code:
|
||||
|
||||
#include "luajit.h"
|
||||
|
||||
Or for C++ code:
|
||||
|
||||
#include "lua.hpp"
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, mode)> E<mdash> Control VM
|
||||
|
||||
This is a C API extension to allow control of the VM from C code. The
|
||||
full prototype of C<LuaJIT_setmode> is:
|
||||
|
||||
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
|
||||
|
||||
The returned status is either success (C<1>) or failure (C<0>). The
|
||||
second argument is either C<0> or a stack index (similar to the other
|
||||
Lua/C API functions).
|
||||
|
||||
The third argument specifies the mode, which is 'or'ed with a flag. The
|
||||
flag can be C<LUAJIT_MODE_OFF> to turn a feature on, C<LUAJIT_MODE_ON>
|
||||
to turn a feature off, or C<LUAJIT_MODE_FLUSH> to flush cached code.
|
||||
|
||||
The following modes are defined:
|
||||
|
||||
=head2 C<luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)>
|
||||
|
||||
Turn the whole JIT compiler on or off or flush the whole cache of
|
||||
compiled code.
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)>
|
||||
|
||||
C<luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)>
|
||||
|
||||
C<luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)>
|
||||
|
||||
This sets the mode for the function at the stack index C<idx> or the
|
||||
parent of the calling function (C<idx = 0>). It either enables JIT
|
||||
compilation for a function, disables it and flushes any already
|
||||
compiled code or only flushes already compiled code. This applies
|
||||
recursively to all sub-functions of the function with
|
||||
C<LUAJIT_MODE_ALLFUNC> or only to the sub-functions with
|
||||
C<LUAJIT_MODE_ALLSUBFUNC>.
|
||||
|
||||
=head2 luaJIT_setmode(L, trace,
|
||||
|
||||
LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)
|
||||
|
||||
Flushes the specified root trace and all of its side traces from the
|
||||
cache. The code for the trace will be retained as long as there are any
|
||||
other traces which link to it.
|
||||
|
||||
=head2 C<luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)>
|
||||
|
||||
This mode defines a wrapper function for calls to C functions. If
|
||||
called with C<LUAJIT_MODE_ON>, the stack index at C<idx> must be a
|
||||
C<lightuserdata> object holding a pointer to the wrapper function. From
|
||||
now on all C functions are called through the wrapper function. If
|
||||
called with C<LUAJIT_MODE_OFF> this mode is turned off and all C
|
||||
functions are directly called.
|
||||
|
||||
The wrapper function can be used for debugging purposes or to catch and
|
||||
convert foreign exceptions. But please read the section on C++
|
||||
exception interoperability first. Recommended usage can be seen in this
|
||||
C++ code excerpt:
|
||||
|
||||
#include <exception>
|
||||
#include "lua.hpp"
|
||||
|
||||
// Catch C++ exceptions and convert them to Lua error messages.
|
||||
// Customize as needed for your own exception classes.
|
||||
static int wrap_exceptions(lua_State *L, lua_CFunction f)
|
||||
{
|
||||
try {
|
||||
return f(L); // Call wrapped function and return result.
|
||||
} catch (const char *s) { // Catch and convert exceptions.
|
||||
lua_pushstring(L, s);
|
||||
} catch (std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
} catch (...) {
|
||||
lua_pushliteral(L, "caught (...)");
|
||||
}
|
||||
return lua_error(L); // Rethrow as a Lua error.
|
||||
}
|
||||
|
||||
static int myinit(lua_State *L)
|
||||
{
|
||||
...
|
||||
// Define wrapper function and enable it.
|
||||
lua_pushlightuserdata(L, (void *)wrap_exceptions);
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
|
||||
lua_pop(L, 1);
|
||||
...
|
||||
}
|
||||
|
||||
Note that you can only define B<a single global wrapper function>, so
|
||||
be careful when using this mechanism from multiple C++ modules. Also
|
||||
note that this mechanism is not without overhead.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_c_api.html
|
||||
# 6042 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_18) because it has super-phrasal elements (`br_3) as children.
|
285
doc/LuaJIT-2.1/ext_ffi.pod
Normal file
285
doc/LuaJIT-2.1/ext_ffi.pod
Normal file
@ -0,0 +1,285 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
The FFI library allows B<calling external C functions> and B<using C
|
||||
data structures> from pure Lua code.
|
||||
|
||||
The FFI library largely obviates the need to write tedious manual Lua/C
|
||||
bindings in C. No need to learn a separate binding language E<mdash>
|
||||
B<it parses plain C declarations!> These can be cut-n-pasted from C
|
||||
header files or reference manuals. It's up to the task of binding large
|
||||
libraries without the need for dealing with fragile binding generators.
|
||||
|
||||
The FFI library is tightly integrated into LuaJIT (it's not available
|
||||
as a separate module). The code generated by the JIT-compiler for
|
||||
accesses to C data structures from Lua code is on par with the code a C
|
||||
compiler would generate. Calls to C functions can be inlined in
|
||||
JIT-compiled code, unlike calls to functions bound via the classic
|
||||
Lua/C API.
|
||||
|
||||
This page gives a short introduction to the usage of the FFI library.
|
||||
I<Please use the FFI sub-topics in the navigation bar to learn more.>
|
||||
|
||||
=head2 Motivating Example: Calling External C Functions
|
||||
|
||||
It's really easy to call an external C library function:
|
||||
|
||||
â
|
||||
â¡
|
||||
|
||||
|
||||
â¢local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
int printf(const char *fmt, ...);
|
||||
]]
|
||||
ffi.C.printf("Hello %s!", "world")
|
||||
|
||||
So, let's pick that apart:
|
||||
|
||||
Load the FFI library.
|
||||
|
||||
Add a C declaration for the function. The part inside the
|
||||
double-brackets (in green) is just standard C syntax.
|
||||
|
||||
Call the named C function E<mdash> Yes, it's that simple!
|
||||
|
||||
Actually, what goes on behind the scenes is far from simple: makes use
|
||||
of the standard C library namespace C<ffi.C>. Indexing this namespace
|
||||
with a symbol name (C<"printf">) automatically binds it to the standard
|
||||
C library. The result is a special kind of object which, when called,
|
||||
runs the C<printf> function. The arguments passed to this function are
|
||||
automatically converted from Lua objects to the corresponding C types.
|
||||
|
||||
Ok, so maybe the use of C<printf()> wasn't such a spectacular example.
|
||||
You could have done that with C<io.write()> and C<string.format()>,
|
||||
too. But you get the idea ...
|
||||
|
||||
So here's something to pop up a message box on Windows:
|
||||
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
int MessageBoxA(void *w, const char *txt, const char *cap, int type);
|
||||
]]
|
||||
ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
|
||||
|
||||
Bing! Again, that was far too easy, no?
|
||||
|
||||
Compare this with the effort required to bind that function using the
|
||||
classic Lua/C API: create an extra C file, add a C function that
|
||||
retrieves and checks the argument types passed from Lua and calls the
|
||||
actual C function, add a list of module functions and their names, add
|
||||
a C<luaopen_*> function and register all module functions, compile and
|
||||
link it into a shared library (DLL), move it to the proper path, add
|
||||
Lua code that loads the module aaaand ... finally call the binding
|
||||
function. Phew!
|
||||
|
||||
=head2 Motivating Example: Using C Data Structures
|
||||
|
||||
The FFI library allows you to create and access C data structures. Of
|
||||
course the main use for this is for interfacing with C functions. But
|
||||
they can be used stand-alone, too.
|
||||
|
||||
Lua is built upon high-level data types. They are flexible, extensible
|
||||
and dynamic. That's why we all love Lua so much. Alas, this can be
|
||||
inefficient for certain tasks, where you'd really want a low-level data
|
||||
type. E.g. a large array of a fixed structure needs to be implemented
|
||||
with a big table holding lots of tiny tables. This imposes both a
|
||||
substantial memory overhead as well as a performance overhead.
|
||||
|
||||
Here's a sketch of a library that operates on color images plus a
|
||||
simple benchmark. First, the plain Lua version:
|
||||
|
||||
local floor = math.floor
|
||||
|
||||
local function image_ramp_green(n)
|
||||
local img = {}
|
||||
local f = 255/(n-1)
|
||||
for i=1,n do
|
||||
img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=1,n do
|
||||
local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
|
||||
This creates a table with 160.000 pixels, each of which is a table
|
||||
holding four number values in the range of 0-255. First an image with a
|
||||
green ramp is created (1D for simplicity), then the image is converted
|
||||
to greyscale 1000 times. Yes, that's silly, but I was in need of a
|
||||
simple example ...
|
||||
|
||||
And here's the FFI version. The modified parts have been marked in
|
||||
bold:
|
||||
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
â¢
|
||||
â£
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¢
|
||||
â¤local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;
|
||||
]]
|
||||
|
||||
local function image_ramp_green(n)
|
||||
local img = ffi.new("rgba_pixel[?]", n)
|
||||
local f = 255/(n-1)
|
||||
for i=0,n-1 do
|
||||
img[i].green = i*f
|
||||
img[i].alpha = 255
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=0,n-1 do
|
||||
local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
|
||||
Ok, so that wasn't too difficult:
|
||||
|
||||
First, load the FFI library and declare the low-level data type. Here
|
||||
we choose a C<struct> which holds four byte fields, one for each
|
||||
component of a 4x8 bit RGBA pixel.
|
||||
|
||||
Creating the data structure with C<ffi.new()> is straightforward
|
||||
E<mdash> the C<'?'> is a placeholder for the number of elements of a
|
||||
variable-length array.
|
||||
|
||||
C arrays are zero-based, so the indexes have to run from C<0> to
|
||||
C<n-1>. One might want to allocate one more element instead to simplify
|
||||
converting legacy code.
|
||||
|
||||
Since C<ffi.new()> zero-fills the array by default, we only need to set
|
||||
the green and the alpha fields.
|
||||
|
||||
The calls to C<math.floor()> can be omitted here, because
|
||||
floating-point numbers are already truncated towards zero when
|
||||
converting them to an integer. This happens implicitly when the number
|
||||
is stored in the fields of each pixel.
|
||||
|
||||
Now let's have a look at the impact of the changes: first, memory
|
||||
consumption for the image is down from 22 Megabytes to 640 Kilobytes
|
||||
(400*400*4 bytes). That's a factor of 35x less! So, yes, tables do have
|
||||
a noticeable overhead. BTW: The original program would consume 40
|
||||
Megabytes in plain Lua (on x64).
|
||||
|
||||
Next, performance: the pure Lua version runs in 9.57 seconds (52.9
|
||||
seconds with the Lua interpreter) and the FFI version runs in 0.48
|
||||
seconds on my machine (YMMV). That's a factor of 20x faster (110x
|
||||
faster than the Lua interpreter).
|
||||
|
||||
The avid reader may notice that converting the pure Lua version over to
|
||||
use array indexes for the colors (C<[1]> instead of C<.red>, C<[2]>
|
||||
instead of C<.green> etc.) ought to be more compact and faster. This is
|
||||
certainly true (by a factor of ~1.7x). Switching to a struct-of-arrays
|
||||
would help, too.
|
||||
|
||||
However the resulting code would be less idiomatic and rather
|
||||
error-prone. And it still doesn't get even close to the performance of
|
||||
the FFI version of the code. Also, high-level data structures cannot be
|
||||
easily passed to other C functions, especially I/O functions, without
|
||||
undue conversion penalties.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi.html
|
||||
# 10336 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
503
doc/LuaJIT-2.1/ext_ffi_api.pod
Normal file
503
doc/LuaJIT-2.1/ext_ffi_api.pod
Normal file
@ -0,0 +1,503 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 C<ffi.*> API Functions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
This page describes the API functions provided by the FFI library in
|
||||
detail. It's recommended to read through the introduction and the FFI
|
||||
tutorial first.
|
||||
|
||||
=head2 Glossary
|
||||
|
||||
=over
|
||||
|
||||
=item * B<cdecl> E<mdash> An abstract C type declaration (a Lua
|
||||
string).
|
||||
|
||||
=item * B<ctype> E<mdash> A C type object. This is a special kind of
|
||||
B<cdata> returned by C<ffi.typeof()>. It serves as a B<cdata>
|
||||
constructor when called.
|
||||
|
||||
=item * B<cdata> E<mdash> A C data object. It holds a value of the
|
||||
corresponding B<ctype>.
|
||||
|
||||
=item * B<ct> E<mdash> A C type specification which can be used for
|
||||
most of the API functions. Either a B<cdecl>, a B<ctype> or a B<cdata>
|
||||
serving as a template type.
|
||||
|
||||
=item * B<cb> E<mdash> A callback object. This is a C data object
|
||||
holding a special function pointer. Calling this function from C code
|
||||
runs an associated Lua function.
|
||||
|
||||
=item * B<VLA> E<mdash> A variable-length array is declared with a C<?>
|
||||
instead of the number of elements, e.g. C<"int[?]">. The number of
|
||||
elements (C<nelem>) must be given when it's created.
|
||||
|
||||
=item * B<VLS> E<mdash> A variable-length struct is a C<struct> C type
|
||||
where the last element is a B<VLA>. The same rules for declaration and
|
||||
creation apply.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Declaring and Accessing External Symbols
|
||||
|
||||
External symbols must be declared first and can then be accessed by
|
||||
indexing a C library namespace, which automatically binds the symbol to
|
||||
a specific library.
|
||||
|
||||
=head2 C<ffi.cdef(def)>
|
||||
|
||||
Adds multiple C declarations for types or external symbols (named
|
||||
variables or functions). C<def> must be a Lua string. It's recommended
|
||||
to use the syntactic sugar for string arguments as follows:
|
||||
|
||||
ffi.cdef[[
|
||||
typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
|
||||
int dofoo(foo_t *f, int n); /* Declare an external C function. */
|
||||
]]
|
||||
|
||||
The contents of the string (the part in green above) must be a sequence
|
||||
of C declarations, separated by semicolons. The trailing semicolon for
|
||||
a single declaration may be omitted.
|
||||
|
||||
Please note that external symbols are only I<declared>, but they are
|
||||
I<not bound> to any specific address, yet. Binding is achieved with C
|
||||
library namespaces (see below).
|
||||
|
||||
C declarations are not passed through a C pre-processor, yet. No
|
||||
pre-processor tokens are allowed, except for C<#pragma pack>. Replace
|
||||
C<#define> in existing C header files with C<enum>, C<static const> or
|
||||
C<typedef> and/or pass the files through an external C pre-processor
|
||||
(once). Be careful not to include unneeded or redundant declarations
|
||||
from unrelated header files.
|
||||
|
||||
=head2 C<ffi.C>
|
||||
|
||||
This is the default C library namespace E<mdash> note the uppercase
|
||||
C<'C'>. It binds to the default set of symbols or libraries on the
|
||||
target system. These are more or less the same as a C compiler would
|
||||
offer by default, without specifying extra link libraries.
|
||||
|
||||
On POSIX systems, this binds to symbols in the default or global
|
||||
namespace. This includes all exported symbols from the executable and
|
||||
any libraries loaded into the global namespace. This includes at least
|
||||
C<libc>, C<libm>, C<libdl> (on Linux), C<libgcc> (if compiled with
|
||||
GCC), as well as any exported symbols from the Lua/C API provided by
|
||||
LuaJIT itself.
|
||||
|
||||
On Windows systems, this binds to symbols exported from the C<*.exe>,
|
||||
the C<lua51.dll> (i.e. the Lua/C API provided by LuaJIT itself), the C
|
||||
runtime library LuaJIT was linked with (C<msvcrt*.dll>),
|
||||
C<kernel32.dll>, C<user32.dll> and C<gdi32.dll>.
|
||||
|
||||
=head2 C<clib = ffi.load(name [,global])>
|
||||
|
||||
This loads the dynamic library given by C<name> and returns a new C
|
||||
library namespace which binds to its symbols. On POSIX systems, if
|
||||
C<global> is C<true>, the library symbols are loaded into the global
|
||||
namespace, too.
|
||||
|
||||
If C<name> is a path, the library is loaded from this path. Otherwise
|
||||
C<name> is canonicalized in a system-dependent way and searched in the
|
||||
default search path for dynamic libraries:
|
||||
|
||||
On POSIX systems, if the name contains no dot, the extension C<.so> is
|
||||
appended. Also, the C<lib> prefix is prepended if necessary. So
|
||||
C<ffi.load("z")> looks for C<"libz.so"> in the default shared library
|
||||
search path.
|
||||
|
||||
On Windows systems, if the name contains no dot, the extension C<.dll>
|
||||
is appended. So C<ffi.load("ws2_32")> looks for C<"ws2_32.dll"> in the
|
||||
default DLL search path.
|
||||
|
||||
=head2 Creating cdata Objects
|
||||
|
||||
The following API functions create cdata objects (C<type()> returns
|
||||
C<"cdata">). All created cdata objects are garbage collected.
|
||||
|
||||
=head2 cdata = ffi.new(ct [,nelem] [,init...])
|
||||
|
||||
cdata = I<ctype>([nelem,] [init...])
|
||||
|
||||
Creates a cdata object for the given C<ct>. VLA/VLS types require the
|
||||
C<nelem> argument. The second syntax uses a ctype as a constructor and
|
||||
is otherwise fully equivalent.
|
||||
|
||||
The cdata object is initialized according to the rules for
|
||||
initializers, using the optional C<init> arguments. Excess initializers
|
||||
cause an error.
|
||||
|
||||
Performance notice: if you want to create many objects of one kind,
|
||||
parse the cdecl only once and get its ctype with C<ffi.typeof()>. Then
|
||||
use the ctype as a constructor repeatedly.
|
||||
|
||||
Please note that an anonymous C<struct> declaration implicitly creates
|
||||
a new and distinguished ctype every time you use it for C<ffi.new()>.
|
||||
This is probably B<not> what you want, especially if you create more
|
||||
than one cdata object. Different anonymous C<structs> are not
|
||||
considered assignment-compatible by the C standard, even though they
|
||||
may have the same fields! Also, they are considered different types by
|
||||
the JIT-compiler, which may cause an excessive number of traces. It's
|
||||
strongly suggested to either declare a named C<struct> or C<typedef>
|
||||
with C<ffi.cdef()> or to create a single ctype object for an anonymous
|
||||
C<struct> with C<ffi.typeof()>.
|
||||
|
||||
=head2 C<ctype = ffi.typeof(ct)>
|
||||
|
||||
Creates a ctype object for the given C<ct>.
|
||||
|
||||
This function is especially useful to parse a cdecl only once and then
|
||||
use the resulting ctype object as a constructor.
|
||||
|
||||
=head2 C<cdata = ffi.cast(ct, init)>
|
||||
|
||||
Creates a scalar cdata object for the given C<ct>. The cdata object is
|
||||
initialized with C<init> using the "cast" variant of the C type
|
||||
conversion rules.
|
||||
|
||||
This functions is mainly useful to override the pointer compatibility
|
||||
checks or to convert pointers to addresses or vice versa.
|
||||
|
||||
=head2 C<ctype = ffi.metatype(ct, metatable)>
|
||||
|
||||
Creates a ctype object for the given C<ct> and associates it with a
|
||||
metatable. Only C<struct>/C<union> types, complex numbers and vectors
|
||||
are allowed. Other types may be wrapped in a C<struct>, if needed.
|
||||
|
||||
The association with a metatable is permanent and cannot be changed
|
||||
afterwards. Neither the contents of the C<metatable> nor the contents
|
||||
of an C<__index> table (if any) may be modified afterwards. The
|
||||
associated metatable automatically applies to all uses of this type, no
|
||||
matter how the objects are created or where they originate from. Note
|
||||
that pre-defined operations on types have precedence (e.g. declared
|
||||
field names cannot be overriden).
|
||||
|
||||
All standard Lua metamethods are implemented. These are called
|
||||
directly, without shortcuts and on any mix of types. For binary
|
||||
operations, the left operand is checked first for a valid ctype
|
||||
metamethod. The C<__gc> metamethod only applies to C<struct>/C<union>
|
||||
types and performs an implicit C<ffi.gc()> call during creation of an
|
||||
instance.
|
||||
|
||||
=head2 C<cdata = ffi.gc(cdata, finalizer)>
|
||||
|
||||
Associates a finalizer with a pointer or aggregate cdata object. The
|
||||
cdata object is returned unchanged.
|
||||
|
||||
This function allows safe integration of unmanaged resources into the
|
||||
automatic memory management of the LuaJIT garbage collector. Typical
|
||||
usage:
|
||||
|
||||
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
|
||||
...
|
||||
p = nil -- Last reference to p is gone.
|
||||
-- GC will eventually run finalizer: ffi.C.free(p)
|
||||
|
||||
A cdata finalizer works like the C<__gc> metamethod for userdata
|
||||
objects: when the last reference to a cdata object is gone, the
|
||||
associated finalizer is called with the cdata object as an argument.
|
||||
The finalizer can be a Lua function or a cdata function or cdata
|
||||
function pointer. An existing finalizer can be removed by setting a
|
||||
C<nil> finalizer, e.g. right before explicitly deleting a resource:
|
||||
|
||||
ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
|
||||
|
||||
=head2 C Type Information
|
||||
|
||||
The following API functions return information about C types. They are
|
||||
most useful for inspecting cdata objects.
|
||||
|
||||
=head2 C<size = ffi.sizeof(ct [,nelem])>
|
||||
|
||||
Returns the size of C<ct> in bytes. Returns C<nil> if the size is not
|
||||
known (e.g. for C<"void"> or function types). Requires C<nelem> for
|
||||
VLA/VLS types, except for cdata objects.
|
||||
|
||||
=head2 C<align = ffi.alignof(ct)>
|
||||
|
||||
Returns the minimum required alignment for C<ct> in bytes.
|
||||
|
||||
=head2 C<ofs [,bpos,bsize] = ffi.offsetof(ct, field)>
|
||||
|
||||
Returns the offset (in bytes) of C<field> relative to the start of
|
||||
C<ct>, which must be a C<struct>. Additionally returns the position and
|
||||
the field size (in bits) for bit fields.
|
||||
|
||||
=head2 C<status = ffi.istype(ct, obj)>
|
||||
|
||||
Returns C<true> if C<obj> has the C type given by C<ct>. Returns
|
||||
C<false> otherwise.
|
||||
|
||||
C type qualifiers (C<const> etc.) are ignored. Pointers are checked
|
||||
with the standard pointer compatibility rules, but without any special
|
||||
treatment for C<void *>. If C<ct> specifies a C<struct>/C<union>, then
|
||||
a pointer to this type is accepted, too. Otherwise the types must match
|
||||
exactly.
|
||||
|
||||
Note: this function accepts all kinds of Lua objects for the C<obj>
|
||||
argument, but always returns C<false> for non-cdata objects.
|
||||
|
||||
=head2 Utility Functions
|
||||
|
||||
=head2 C<err = ffi.errno([newerr])>
|
||||
|
||||
Returns the error number set by the last C function call which
|
||||
indicated an error condition. If the optional C<newerr> argument is
|
||||
present, the error number is set to the new value and the previous
|
||||
value is returned.
|
||||
|
||||
This function offers a portable and OS-independent way to get and set
|
||||
the error number. Note that only I<some> C functions set the error
|
||||
number. And it's only significant if the function actually indicated an
|
||||
error condition (e.g. with a return value of C<-1> or C<NULL>).
|
||||
Otherwise, it may or may not contain any previously set value.
|
||||
|
||||
You're advised to call this function only when needed and as close as
|
||||
possible after the return of the related C function. The C<errno> value
|
||||
is preserved across hooks, memory allocations, invocations of the JIT
|
||||
compiler and other internal VM activity. The same applies to the value
|
||||
returned by C<GetLastError()> on Windows, but you need to declare and
|
||||
call it yourself.
|
||||
|
||||
=head2 C<str = ffi.string(ptr [,len])>
|
||||
|
||||
Creates an interned Lua string from the data pointed to by C<ptr>.
|
||||
|
||||
If the optional argument C<len> is missing, C<ptr> is converted to a
|
||||
C<"char *"> and the data is assumed to be zero-terminated. The length
|
||||
of the string is computed with C<strlen()>.
|
||||
|
||||
Otherwise C<ptr> is converted to a C<"void *"> and C<len> gives the
|
||||
length of the data. The data may contain embedded zeros and need not be
|
||||
byte-oriented (though this may cause endianess issues).
|
||||
|
||||
This function is mainly useful to convert (temporary) C<"const char *">
|
||||
pointers returned by C functions to Lua strings and store them or pass
|
||||
them to other functions expecting a Lua string. The Lua string is an
|
||||
(interned) copy of the data and bears no relation to the original data
|
||||
area anymore. Lua strings are 8 bit clean and may be used to hold
|
||||
arbitrary, non-character data.
|
||||
|
||||
Performance notice: it's faster to pass the length of the string, if
|
||||
it's known. E.g. when the length is returned by a C call like
|
||||
C<sprintf()>.
|
||||
|
||||
=head2 ffi.copy(dst, src, len)
|
||||
|
||||
ffi.copy(dst, str)
|
||||
|
||||
Copies the data pointed to by C<src> to C<dst>. C<dst> is converted to
|
||||
a C<"void *"> and C<src> is converted to a C<"const void *">.
|
||||
|
||||
In the first syntax, C<len> gives the number of bytes to copy. Caveat:
|
||||
if C<src> is a Lua string, then C<len> must not exceed C<#src+1>.
|
||||
|
||||
In the second syntax, the source of the copy must be a Lua string. All
|
||||
bytes of the string I<plus a zero-terminator> are copied to C<dst>
|
||||
(i.e. C<#src+1> bytes).
|
||||
|
||||
Performance notice: C<ffi.copy()> may be used as a faster (inlinable)
|
||||
replacement for the C library functions C<memcpy()>, C<strcpy()> and
|
||||
C<strncpy()>.
|
||||
|
||||
=head2 C<ffi.fill(dst, len [,c])>
|
||||
|
||||
Fills the data pointed to by C<dst> with C<len> constant bytes, given
|
||||
by C<c>. If C<c> is omitted, the data is zero-filled.
|
||||
|
||||
Performance notice: C<ffi.fill()> may be used as a faster (inlinable)
|
||||
replacement for the C library function C<memset(dst, c, len)>. Please
|
||||
note the different order of arguments!
|
||||
|
||||
=head2 Target-specific Information
|
||||
|
||||
=head2 C<status = ffi.abi(param)>
|
||||
|
||||
Returns C<true> if C<param> (a Lua string) applies for the target ABI
|
||||
(Application Binary Interface). Returns C<false> otherwise. The
|
||||
following parameters are currently defined:
|
||||
|
||||
Parameter
|
||||
|
||||
Description
|
||||
|
||||
32bit
|
||||
|
||||
32 bit architecture
|
||||
|
||||
64bit
|
||||
|
||||
64 bit architecture
|
||||
|
||||
le
|
||||
|
||||
Little-endian architecture
|
||||
|
||||
be
|
||||
|
||||
Big-endian architecture
|
||||
|
||||
fpu
|
||||
|
||||
Target has a hardware FPU
|
||||
|
||||
softfp
|
||||
|
||||
softfp calling conventions
|
||||
|
||||
hardfp
|
||||
|
||||
hardfp calling conventions
|
||||
|
||||
eabi
|
||||
|
||||
EABI variant of the standard ABI
|
||||
|
||||
win
|
||||
|
||||
Windows variant of the standard ABI
|
||||
|
||||
gc64
|
||||
|
||||
64 bit GC references
|
||||
|
||||
=head2 C<ffi.os>
|
||||
|
||||
Contains the target OS name. Same contents as C<jit.os>.
|
||||
|
||||
=head2 C<ffi.arch>
|
||||
|
||||
Contains the target architecture name. Same contents as C<jit.arch>.
|
||||
|
||||
=head2 Methods for Callbacks
|
||||
|
||||
The C types for callbacks have some extra methods:
|
||||
|
||||
=head2 C<cb:free()>
|
||||
|
||||
Free the resources associated with a callback. The associated Lua
|
||||
function is unanchored and may be garbage collected. The callback
|
||||
function pointer is no longer valid and must not be called anymore (it
|
||||
may be reused by a subsequently created callback).
|
||||
|
||||
=head2 C<cb:set(func)>
|
||||
|
||||
Associate a new Lua function with a callback. The C type of the
|
||||
callback and the callback function pointer are unchanged.
|
||||
|
||||
This method is useful to dynamically switch the receiver of callbacks
|
||||
without creating a new callback each time and registering it again
|
||||
(e.g. with a GUI library).
|
||||
|
||||
=head2 Extended Standard Library Functions
|
||||
|
||||
The following standard library functions have been extended to work
|
||||
with cdata objects:
|
||||
|
||||
=head2 C<n = tonumber(cdata)>
|
||||
|
||||
Converts a number cdata object to a C<double> and returns it as a Lua
|
||||
number. This is particularly useful for boxed 64 bit integer values.
|
||||
Caveat: this conversion may incur a precision loss.
|
||||
|
||||
=head2 C<s = tostring(cdata)>
|
||||
|
||||
Returns a string representation of the value of 64 bit integers
|
||||
(C<B<">nnnB<LL">> or C<B<">nnnB<ULL">>) or complex numbers
|
||||
(C<B<">reE<plusmn>imB<i">>). Otherwise returns a string representation
|
||||
of the C type of a ctype object (C<B<"ctypeE<lt>>typeB<E<gt>">>) or a
|
||||
cdata object (C<B<"cdataE<lt>>typeB<E<gt>: >address">), unless you
|
||||
override it with a C<__tostring> metamethod (see C<ffi.metatype()>).
|
||||
|
||||
=head2 iter, obj, start = pairs(cdata)
|
||||
|
||||
iter, obj, start = ipairs(cdata)
|
||||
|
||||
Calls the C<__pairs> or C<__ipairs> metamethod of the corresponding
|
||||
ctype.
|
||||
|
||||
=head2 Extensions to the Lua Parser
|
||||
|
||||
The parser for Lua source code treats numeric literals with the
|
||||
suffixes C<LL> or C<ULL> as signed or unsigned 64 bit integers. Case
|
||||
doesn't matter, but uppercase is recommended for readability. It
|
||||
handles decimal (C<42LL>), hexadecimal (C<0x2aLL>) and binary
|
||||
(C<0b101010LL>) literals.
|
||||
|
||||
The imaginary part of complex numbers can be specified by suffixing
|
||||
number literals with C<i> or C<I>, e.g. C<12.5i>. Caveat: you'll need
|
||||
to use C<1i> to get an imaginary part with the value one, since C<i>
|
||||
itself still refers to a variable named C<i>.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi_api.html
|
||||
# 21471 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_157) because it has super-phrasal elements (`br_3, `br_4) as children.
|
||||
# Deleting phrasal "code" element (`tt_113) because it has super-phrasal elements (`br_2) as children.
|
||||
# Deleting phrasal "code" element (`tt_41) because it has super-phrasal elements (`br_1) as children.
|
1387
doc/LuaJIT-2.1/ext_ffi_semantics.pod
Normal file
1387
doc/LuaJIT-2.1/ext_ffi_semantics.pod
Normal file
File diff suppressed because it is too large
Load Diff
640
doc/LuaJIT-2.1/ext_ffi_tutorial.pod
Normal file
640
doc/LuaJIT-2.1/ext_ffi_tutorial.pod
Normal file
@ -0,0 +1,640 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 FFI Tutorial
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
This page is intended to give you an overview of the features of the
|
||||
FFI library by presenting a few use cases and guidelines.
|
||||
|
||||
This page makes no attempt to explain all of the FFI library, though.
|
||||
You'll want to have a look at the ffi.* API function reference and the
|
||||
FFI semantics to learn more.
|
||||
|
||||
=head2 Loading the FFI Library
|
||||
|
||||
The FFI library is built into LuaJIT by default, but it's not loaded
|
||||
and initialized by default. The suggested way to use the FFI library is
|
||||
to add the following to the start of every Lua file that needs one of
|
||||
its functions:
|
||||
|
||||
local ffi = require("ffi")
|
||||
|
||||
Please note this doesn't define an C<ffi> variable in the table of
|
||||
globals E<mdash> you really need to use the local variable. The
|
||||
C<require> function ensures the library is only loaded once.
|
||||
|
||||
Note: If you want to experiment with the FFI from the interactive
|
||||
prompt of the command line executable, omit the C<local>, as it doesn't
|
||||
preserve local variables across lines.
|
||||
|
||||
=head2 Accessing Standard System Functions
|
||||
|
||||
The following code explains how to access standard system functions. We
|
||||
slowly print two lines of dots by sleeping for 10 milliseconds after
|
||||
each dot:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
â¢
|
||||
â£
|
||||
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¥local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
void Sleep(int ms);
|
||||
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
|
||||
]]
|
||||
|
||||
local sleep
|
||||
if ffi.os == "Windows" then
|
||||
function sleep(s)
|
||||
ffi.C.Sleep(s*1000)
|
||||
end
|
||||
else
|
||||
function sleep(s)
|
||||
ffi.C.poll(nil, 0, s*1000)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,160 do
|
||||
io.write("."); io.flush()
|
||||
sleep(0.01)
|
||||
end
|
||||
io.write("\n")
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines the C library functions we're going to use. The part
|
||||
inside the double-brackets (in green) is just standard C syntax. You
|
||||
can usually get this info from the C header files or the documentation
|
||||
provided by each C library or C compiler.
|
||||
|
||||
The difficulty we're facing here, is that there are different standards
|
||||
to choose from. Windows has a simple C<Sleep()> function. On other
|
||||
systems there are a variety of functions available to achieve
|
||||
sub-second sleeps, but with no clear consensus. Thankfully C<poll()>
|
||||
can be used for this task, too, and it's present on most non-Windows
|
||||
systems. The check for C<ffi.os> makes sure we use the Windows-specific
|
||||
function only on Windows systems.
|
||||
|
||||
Here we're wrapping the call to the C function in a Lua function. This
|
||||
isn't strictly necessary, but it's helpful to deal with system-specific
|
||||
issues only in one part of the code. The way we're wrapping it ensures
|
||||
the check for the OS is only done during initialization and not for
|
||||
every call.
|
||||
|
||||
A more subtle point is that we defined our C<sleep()> function (for the
|
||||
sake of this example) as taking the number of seconds, but accepting
|
||||
fractional seconds. Multiplying this by 1000 gets us milliseconds, but
|
||||
that still leaves it a Lua number, which is a floating-point value.
|
||||
Alas, the C<Sleep()> function only accepts an integer value. Luckily
|
||||
for us, the FFI library automatically performs the conversion when
|
||||
calling the function (truncating the FP value towards zero, like in C).
|
||||
|
||||
Some readers will notice that C<Sleep()> is part of C<KERNEL32.DLL> and
|
||||
is also a C<stdcall> function. So how can this possibly work? The FFI
|
||||
library provides the C<ffi.C> default C library namespace, which allows
|
||||
calling functions from the default set of libraries, like a C compiler
|
||||
would. Also, the FFI library automatically detects C<stdcall>
|
||||
functions, so you don't need to declare them as such.
|
||||
|
||||
The C<poll()> function takes a couple more arguments we're not going to
|
||||
use. You can simply use C<nil> to pass a C<NULL> pointer and C<0> for
|
||||
the C<nfds> parameter. Please note that the number C<0> I<does not
|
||||
convert to a pointer value>, unlike in C++. You really have to pass
|
||||
pointers to pointer arguments and numbers to number arguments.
|
||||
|
||||
The page on FFI semantics has all of the gory details about conversions
|
||||
between Lua objects and C types. For the most part you don't have to
|
||||
deal with this, as it's performed automatically and it's carefully
|
||||
designed to bridge the semantic differences between Lua and C.
|
||||
|
||||
Now that we have defined our own C<sleep()> function, we can just call
|
||||
it from plain Lua code. That wasn't so bad, huh? Turning these boring
|
||||
animated dots into a fascinating best-selling game is left as an
|
||||
exercise for the reader. :-)
|
||||
|
||||
=head2 Accessing the zlib Compression Library
|
||||
|
||||
The following code shows how to access the zlib compression library
|
||||
from Lua code. We'll define two convenience wrapper functions that take
|
||||
a string and compress or uncompress it to another string:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
|
||||
â¢
|
||||
|
||||
â£
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
|
||||
â¥
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
â¦local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
unsigned long compressBound(unsigned long sourceLen);
|
||||
int compress2(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen, int level);
|
||||
int uncompress(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen);
|
||||
]]
|
||||
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
|
||||
|
||||
local function compress(txt)
|
||||
local n = zlib.compressBound(#txt)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.compress2(buf, buflen, txt, #txt, 9)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
local function uncompress(comp, n)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.uncompress(buf, buflen, comp, #comp)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
-- Simple test code.
|
||||
local txt = string.rep("abcd", 1000)
|
||||
print("Uncompressed size: ", #txt)
|
||||
local c = compress(txt)
|
||||
print("Compressed size: ", #c)
|
||||
local txt2 = uncompress(c, #txt)
|
||||
assert(txt2 == txt)
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines some of the C functions provided by zlib. For the sake of
|
||||
this example, some type indirections have been reduced and it uses the
|
||||
pre-defined fixed-size integer types, while still adhering to the zlib
|
||||
API/ABI.
|
||||
|
||||
This loads the zlib shared library. On POSIX systems it's named
|
||||
C<libz.so> and usually comes pre-installed. Since C<ffi.load()>
|
||||
automatically adds any missing standard prefixes/suffixes, we can
|
||||
simply load the C<"z"> library. On Windows it's named C<zlib1.dll> and
|
||||
you'll have to download it first from the E<rchevron> zlib site. The
|
||||
check for C<ffi.os> makes sure we pass the right name to C<ffi.load()>.
|
||||
|
||||
First, the maximum size of the compression buffer is obtained by
|
||||
calling the C<zlib.compressBound> function with the length of the
|
||||
uncompressed string. The next line allocates a byte buffer of this
|
||||
size. The C<[?]> in the type specification indicates a variable-length
|
||||
array (VLA). The actual number of elements of this array is given as
|
||||
the 2nd argument to C<ffi.new()>.
|
||||
|
||||
This may look strange at first, but have a look at the declaration of
|
||||
the C<compress2> function from zlib: the destination length is defined
|
||||
as a pointer! This is because you pass in the maximum buffer size and
|
||||
get back the actual length that was used.
|
||||
|
||||
In C you'd pass in the address of a local variable (C<&buflen>). But
|
||||
since there's no address-of operator in Lua, we'll just pass in a
|
||||
one-element array. Conveniently it can be initialized with the maximum
|
||||
buffer size in one step. Calling the actual C<zlib.compress2> function
|
||||
is then straightforward.
|
||||
|
||||
We want to return the compressed data as a Lua string, so we'll use
|
||||
C<ffi.string()>. It needs a pointer to the start of the data and the
|
||||
actual length. The length has been returned in the C<buflen> array, so
|
||||
we'll just get it from there.
|
||||
|
||||
Note that since the function returns now, the C<buf> and C<buflen>
|
||||
variables will eventually be garbage collected. This is fine, because
|
||||
C<ffi.string()> has copied the contents to a newly created (interned)
|
||||
Lua string. If you plan to call this function lots of times, consider
|
||||
reusing the buffers and/or handing back the results in buffers instead
|
||||
of strings. This will reduce the overhead for garbage collection and
|
||||
string interning.
|
||||
|
||||
The C<uncompress> functions does the exact opposite of the C<compress>
|
||||
function. The compressed data doesn't include the size of the original
|
||||
string, so this needs to be passed in. Otherwise no surprises here.
|
||||
|
||||
The code, that makes use of the functions we just defined, is just
|
||||
plain Lua code. It doesn't need to know anything about the LuaJIT FFI
|
||||
E<mdash> the convenience wrapper functions completely hide it.
|
||||
|
||||
One major advantage of the LuaJIT FFI is that you are now able to write
|
||||
those wrappers I<in Lua>. And at a fraction of the time it would cost
|
||||
you to create an extra C module using the Lua/C API. Many of the
|
||||
simpler C functions can probably be used directly from your Lua code,
|
||||
without any wrappers.
|
||||
|
||||
Side note: the zlib API uses the C<long> type for passing lengths and
|
||||
sizes around. But all those zlib functions actually only deal with 32
|
||||
bit values. This is an unfortunate choice for a public API, but may be
|
||||
explained by zlib's history E<mdash> we'll just have to deal with it.
|
||||
|
||||
First, you should know that a C<long> is a 64 bit type e.g. on
|
||||
POSIX/x64 systems, but a 32 bit type on Windows/x64 and on 32 bit
|
||||
systems. Thus a C<long> result can be either a plain Lua number or a
|
||||
boxed 64 bit integer cdata object, depending on the target system.
|
||||
|
||||
Ok, so the C<ffi.*> functions generally accept cdata objects wherever
|
||||
you'd want to use a number. That's why we get a away with passing C<n>
|
||||
to C<ffi.string()> above. But other Lua library functions or modules
|
||||
don't know how to deal with this. So for maximum portability one needs
|
||||
to use C<tonumber()> on returned C<long> results before passing them
|
||||
on. Otherwise the application might work on some systems, but would
|
||||
fail in a POSIX/x64 environment.
|
||||
|
||||
=head2 Defining Metamethods for a C Type
|
||||
|
||||
The following code explains how to define metamethods for a C type. We
|
||||
define a simple point type and add some operations to it:
|
||||
|
||||
Â
|
||||
â
|
||||
|
||||
|
||||
|
||||
â¡
|
||||
|
||||
â¢
|
||||
|
||||
â£
|
||||
|
||||
|
||||
|
||||
â¤
|
||||
|
||||
â¥local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
typedef struct { double x, y; } point_t;
|
||||
]]
|
||||
|
||||
local point
|
||||
local mt = {
|
||||
__add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
|
||||
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
|
||||
__index = {
|
||||
area = function(a) return a.x*a.x + a.y*a.y end,
|
||||
},
|
||||
}
|
||||
point = ffi.metatype("point_t", mt)
|
||||
|
||||
local a = point(3, 4)
|
||||
print(a.x, a.y) --> 3 4
|
||||
print(#a) --> 5
|
||||
print(a:area()) --> 25
|
||||
local b = a + point(0.5, 8)
|
||||
print(#b) --> 12.5
|
||||
|
||||
Here's the step-by-step explanation:
|
||||
|
||||
This defines the C type for a two-dimensional point object.
|
||||
|
||||
We have to declare the variable holding the point constructor first,
|
||||
because it's used inside of a metamethod.
|
||||
|
||||
Let's define an C<__add> metamethod which adds the coordinates of two
|
||||
points and creates a new point object. For simplicity, this function
|
||||
assumes that both arguments are points. But it could be any mix of
|
||||
objects, if at least one operand is of the required type (e.g. adding a
|
||||
point plus a number or vice versa). Our C<__len> metamethod returns the
|
||||
distance of a point to the origin.
|
||||
|
||||
If we run out of operators, we can define named methods, too. Here the
|
||||
C<__index> table defines an C<area> function. For custom indexing
|
||||
needs, one might want to define C<__index> and C<__newindex>
|
||||
I<functions> instead.
|
||||
|
||||
This associates the metamethods with our C type. This only needs to be
|
||||
done once. For convenience, a constructor is returned by
|
||||
C<ffi.metatype()>. We're not required to use it, though. The original C
|
||||
type can still be used e.g. to create an array of points. The
|
||||
metamethods automatically apply to any and all uses of this type.
|
||||
|
||||
Please note that the association with a metatable is permanent and
|
||||
B<the metatable must not be modified afterwards!> Ditto for the
|
||||
C<__index> table.
|
||||
|
||||
Here are some simple usage examples for the point type and their
|
||||
expected results. The pre-defined operations (such as C<a.x>) can be
|
||||
freely mixed with the newly defined metamethods. Note that C<area> is a
|
||||
method and must be called with the Lua syntax for methods: C<a:area()>,
|
||||
not C<a.area()>.
|
||||
|
||||
The C type metamethod mechanism is most useful when used in conjunction
|
||||
with C libraries that are written in an object-oriented style. Creators
|
||||
return a pointer to a new instance and methods take an instance pointer
|
||||
as the first argument. Sometimes you can just point C<__index> to the
|
||||
library namespace and C<__gc> to the destructor and you're done. But
|
||||
often enough you'll want to add convenience wrappers, e.g. to return
|
||||
actual Lua strings or when returning multiple values.
|
||||
|
||||
Some C libraries only declare instance pointers as an opaque C<void *>
|
||||
type. In this case you can use a fake type for all declarations, e.g. a
|
||||
pointer to a named (incomplete) struct will do: C<typedef struct
|
||||
foo_type *foo_handle>. The C side doesn't know what you declare with
|
||||
the LuaJIT FFI, but as long as the underlying types are compatible,
|
||||
everything still works.
|
||||
|
||||
=head2 Translating C Idioms
|
||||
|
||||
Here's a list of common C idioms and their translation to the LuaJIT
|
||||
FFI:
|
||||
|
||||
Idiom
|
||||
|
||||
C code
|
||||
|
||||
Lua code
|
||||
|
||||
Pointer dereference
|
||||
|
||||
C<int *p;>
|
||||
|
||||
x = *p;
|
||||
|
||||
*p = y;
|
||||
|
||||
x = B<p[0]>
|
||||
|
||||
B<p[0]> = y
|
||||
|
||||
Pointer indexing
|
||||
|
||||
C<int i, *p;>
|
||||
|
||||
x = p[i];
|
||||
|
||||
p[i+1] = y;
|
||||
|
||||
x = p[i]
|
||||
|
||||
p[i+1] = y
|
||||
|
||||
Array indexing
|
||||
|
||||
C<int i, a[];>
|
||||
|
||||
x = a[i];
|
||||
|
||||
a[i+1] = y;
|
||||
|
||||
x = a[i]
|
||||
|
||||
a[i+1] = y
|
||||
|
||||
C<struct>/C<union> dereference
|
||||
|
||||
C<struct foo s;>
|
||||
|
||||
x = s.field;
|
||||
|
||||
s.field = y;
|
||||
|
||||
x = s.field
|
||||
|
||||
s.field = y
|
||||
|
||||
C<struct>/C<union> pointer deref.
|
||||
|
||||
C<struct foo *sp;>
|
||||
|
||||
x = sp-E<gt>field;
|
||||
|
||||
sp-E<gt>field = y;
|
||||
|
||||
x = B<s.field>
|
||||
|
||||
B<s.field> = y
|
||||
|
||||
Pointer arithmetic
|
||||
|
||||
C<int i, *p;>
|
||||
|
||||
x = p + i;
|
||||
|
||||
y = p - i;
|
||||
|
||||
x = p + i
|
||||
|
||||
y = p - i
|
||||
|
||||
Pointer difference
|
||||
|
||||
C<int *p1, *p2;>
|
||||
|
||||
C<x = p1 - p2;>
|
||||
|
||||
C<x = p1 - p2>
|
||||
|
||||
Array element pointer
|
||||
|
||||
C<int i, a[];>
|
||||
|
||||
C<x = &a[i];>
|
||||
|
||||
C<x = B<a+i>>
|
||||
|
||||
Cast pointer to address
|
||||
|
||||
C<int *p;>
|
||||
|
||||
C<x = (intptr_t)p;>
|
||||
|
||||
x = tonumber(
|
||||
|
||||
ffi.cast("intptr_t",
|
||||
|
||||
p))
|
||||
|
||||
Functions with outargs
|
||||
|
||||
C<void foo(int *inoutlen);>
|
||||
|
||||
int len = x;
|
||||
|
||||
foo(&len);
|
||||
|
||||
y = len;
|
||||
|
||||
local len =
|
||||
|
||||
ffi.new("int[1]", x)
|
||||
|
||||
foo(len)
|
||||
|
||||
y = len[0]
|
||||
|
||||
Vararg conversions
|
||||
|
||||
C<int printf(char *fmt, ...);>
|
||||
|
||||
printf("%g", 1.0);
|
||||
|
||||
printf("%d", 1);
|
||||
|
||||
printf("%g", 1);
|
||||
|
||||
printf("%d",
|
||||
|
||||
B<ffi.new("int", 1)>)
|
||||
|
||||
=head2 To Cache or Not to Cache
|
||||
|
||||
It's a common Lua idiom to cache library functions in local variables
|
||||
or upvalues, e.g.:
|
||||
|
||||
local byte, char = string.byte, string.char
|
||||
local function foo(x)
|
||||
return char(byte(x)+1)
|
||||
end
|
||||
|
||||
This replaces several hash-table lookups with a (faster) direct use of
|
||||
a local or an upvalue. This is less important with LuaJIT, since the
|
||||
JIT compiler optimizes hash-table lookups a lot and is even able to
|
||||
hoist most of them out of the inner loops. It can't eliminate I<all> of
|
||||
them, though, and it saves some typing for often-used functions. So
|
||||
there's still a place for this, even with LuaJIT.
|
||||
|
||||
The situation is a bit different with C function calls via the FFI
|
||||
library. The JIT compiler has special logic to eliminate I<all of the
|
||||
lookup overhead> for functions resolved from a C library namespace!
|
||||
Thus it's not helpful and actually counter-productive to cache
|
||||
individual C functions like this:
|
||||
|
||||
local funca, funcb = ffi.C.funca, ffi.C.funcb -- Not helpful!
|
||||
local function foo(x, n)
|
||||
for i=1,n do funcb(funca(x, i), 1) end
|
||||
end
|
||||
|
||||
This turns them into indirect calls and generates bigger and slower
|
||||
machine code. Instead you'll want to cache the namespace itself and
|
||||
rely on the JIT compiler to eliminate the lookups:
|
||||
|
||||
local C = ffi.C -- Instead use this!
|
||||
local function foo(x, n)
|
||||
for i=1,n do C.funcb(C.funca(x, i), 1) end
|
||||
end
|
||||
|
||||
This generates both shorter and faster code. So B<don't cache C
|
||||
functions>, but B<do> cache namespaces! Most often the namespace is
|
||||
already in a local variable at an outer scope, e.g. from C<local lib =
|
||||
ffi.load(...)>. Note that copying it to a local variable in the
|
||||
function scope is unnecessary.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_ffi_tutorial.html
|
||||
# 22557 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_100) because it has super-phrasal elements (`br_33, `br_34) as children.
|
||||
# Deleting phrasal "code" element (`tt_99) because it has super-phrasal elements (`br_31, `br_32) as children.
|
||||
# Deleting phrasal "b" element (`b_8) because it has super-phrasal elements (`br_27, `br_28, `br_29) as children.
|
||||
# Deleting phrasal "code" element (`tt_97) because it has super-phrasal elements (`br_27, `br_28, `br_29) as children.
|
||||
# Deleting phrasal "code" element (`tt_96) because it has super-phrasal elements (`br_25, `br_26) as children.
|
||||
# Deleting phrasal "b" element (`b_7) because it has super-phrasal elements (`br_22, `br_23) as children.
|
||||
# Deleting phrasal "code" element (`tt_94) because it has super-phrasal elements (`br_22, `br_23) as children.
|
||||
# Deleting phrasal "code" element (`tt_85) because it has super-phrasal elements (`br_18) as children.
|
||||
# Deleting phrasal "code" element (`tt_84) because it has super-phrasal elements (`br_17) as children.
|
||||
# Deleting phrasal "code" element (`tt_82) because it has super-phrasal elements (`br_15) as children.
|
||||
# Deleting phrasal "code" element (`tt_81) because it has super-phrasal elements (`br_14) as children.
|
||||
# Deleting phrasal "code" element (`tt_77) because it has super-phrasal elements (`br_12) as children.
|
||||
# Deleting phrasal "code" element (`tt_76) because it has super-phrasal elements (`br_11) as children.
|
||||
# Deleting phrasal "code" element (`tt_72) because it has super-phrasal elements (`br_9) as children.
|
||||
# Deleting phrasal "code" element (`tt_71) because it has super-phrasal elements (`br_8) as children.
|
||||
# Deleting phrasal "code" element (`tt_69) because it has super-phrasal elements (`br_6) as children.
|
||||
# Deleting phrasal "code" element (`tt_68) because it has super-phrasal elements (`br_5) as children.
|
||||
# Deleting phrasal "code" element (`tt_66) because it has super-phrasal elements (`br_3) as children.
|
||||
# Deleting phrasal "code" element (`tt_65) because it has super-phrasal elements (`br_2) as children.
|
182
doc/LuaJIT-2.1/ext_jit.pod
Normal file
182
doc/LuaJIT-2.1/ext_jit.pod
Normal file
@ -0,0 +1,182 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 C<jit.*> Library
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
The functions in this built-in module control the behavior of the JIT
|
||||
compiler engine. Note that JIT-compilation is fully automatic E<mdash>
|
||||
you probably won't need to use any of the following functions unless
|
||||
you have special needs.
|
||||
|
||||
=head2 jit.on()
|
||||
|
||||
jit.off()
|
||||
|
||||
Turns the whole JIT compiler on (default) or off.
|
||||
|
||||
These functions are typically used with the command line options C<-j
|
||||
on> or C<-j off>.
|
||||
|
||||
=head2 C<jit.flush()>
|
||||
|
||||
Flushes the whole cache of compiled code.
|
||||
|
||||
=head2 jit.on(func|true [,true|false])
|
||||
|
||||
jit.off(func|true [,true|false])
|
||||
|
||||
jit.flush(func|true [,true|false])
|
||||
|
||||
C<jit.on> enables JIT compilation for a Lua function (this is the
|
||||
default).
|
||||
|
||||
C<jit.off> disables JIT compilation for a Lua function and flushes any
|
||||
already compiled code from the code cache.
|
||||
|
||||
C<jit.flush> flushes the code, but doesn't affect the enable/disable
|
||||
status.
|
||||
|
||||
The current function, i.e. the Lua function calling this library
|
||||
function, can also be specified by passing C<true> as the first
|
||||
argument.
|
||||
|
||||
If the second argument is C<true>, JIT compilation is also enabled,
|
||||
disabled or flushed recursively for all sub-functions of a function.
|
||||
With C<false> only the sub-functions are affected.
|
||||
|
||||
The C<jit.on> and C<jit.off> functions only set a flag which is checked
|
||||
when the function is about to be compiled. They do not trigger
|
||||
immediate compilation.
|
||||
|
||||
Typical usage is C<jit.off(true, true)> in the main chunk of a module
|
||||
to turn off JIT compilation for the whole module for debugging
|
||||
purposes.
|
||||
|
||||
=head2 C<jit.flush(tr)>
|
||||
|
||||
Flushes the root trace, specified by its number, and all of its side
|
||||
traces from the cache. The code for the trace will be retained as long
|
||||
as there are any other traces which link to it.
|
||||
|
||||
=head2 C<status, ... = jit.status()>
|
||||
|
||||
Returns the current status of the JIT compiler. The first result is
|
||||
either C<true> or C<false> if the JIT compiler is turned on or off. The
|
||||
remaining results are strings for CPU-specific features and enabled
|
||||
optimizations.
|
||||
|
||||
=head2 C<jit.version>
|
||||
|
||||
Contains the LuaJIT version string.
|
||||
|
||||
=head2 C<jit.version_num>
|
||||
|
||||
Contains the version number of the LuaJIT core. Version xx.yy.zz is
|
||||
represented by the decimal number xxyyzz.
|
||||
|
||||
=head2 C<jit.os>
|
||||
|
||||
Contains the target OS name: "Windows", "Linux", "OSX", "BSD", "POSIX"
|
||||
or "Other".
|
||||
|
||||
=head2 C<jit.arch>
|
||||
|
||||
Contains the target architecture name: "x86", "x64", "arm", "arm64",
|
||||
"ppc", "mips" or "mips64".
|
||||
|
||||
=head2 C<jit.opt.*> E<mdash> JIT compiler optimization control
|
||||
|
||||
This sub-module provides the backend for the C<-O> command line option.
|
||||
|
||||
You can also use it programmatically, e.g.:
|
||||
|
||||
jit.opt.start(2) -- same as -O2
|
||||
jit.opt.start("-dce")
|
||||
jit.opt.start("hotloop=10", "hotexit=2")
|
||||
|
||||
Unlike in LuaJIT 1.x, the module is built-in and B<optimization is
|
||||
turned on by default!> It's no longer necessary to run
|
||||
C<require("jit.opt").start()>, which was one of the ways to enable
|
||||
optimization.
|
||||
|
||||
=head2 C<jit.util.*> E<mdash> JIT compiler introspection
|
||||
|
||||
This sub-module holds functions to introspect the bytecode, generated
|
||||
traces, the IR and the generated machine code. The functionality
|
||||
provided by this module is still in flux and therefore undocumented.
|
||||
|
||||
The debug modules C<-jbc>, C<-jv> and C<-jdump> make extensive use of
|
||||
these functions. Please check out their source code, if you want to
|
||||
know more.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_jit.html
|
||||
# 5903 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "code" element (`tt_6) because it has super-phrasal elements (`br_2, `br_3) as children.
|
||||
# Deleting phrasal "code" element (`tt_2) because it has super-phrasal elements (`br_1) as children.
|
358
doc/LuaJIT-2.1/ext_profiler.pod
Normal file
358
doc/LuaJIT-2.1/ext_profiler.pod
Normal file
@ -0,0 +1,358 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Profiler
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT has an integrated statistical profiler with very low overhead.
|
||||
It allows sampling the currently executing stack and other parameters
|
||||
in regular intervals.
|
||||
|
||||
The integrated profiler can be accessed from three levels:
|
||||
|
||||
=over
|
||||
|
||||
=item * The bundled high-level profiler, invoked by the C<-jp> command
|
||||
line option.
|
||||
|
||||
=item * A low-level Lua API to control the profiler.
|
||||
|
||||
=item * A low-level C API to control the profiler.
|
||||
|
||||
=back
|
||||
|
||||
=head2 High-Level Profiler
|
||||
|
||||
The bundled high-level profiler offers basic profiling functionality.
|
||||
It generates simple textual summaries or source code annotations. It
|
||||
can be accessed with the C<-jp> command line option or from Lua code by
|
||||
loading the underlying C<jit.p> module.
|
||||
|
||||
To cut to the chase E<mdash> run this to get a CPU usage profile by
|
||||
function name:
|
||||
|
||||
luajit -jp myapp.lua
|
||||
|
||||
It's I<not> a stated goal of the bundled profiler to add every possible
|
||||
option or to cater for special profiling needs. The low-level profiler
|
||||
APIs are documented below. They may be used by third-party authors to
|
||||
implement advanced functionality, e.g. IDE integration or graphical
|
||||
profilers.
|
||||
|
||||
Note: Sampling works for both interpreted and JIT-compiled code. The
|
||||
results for JIT-compiled code may sometimes be surprising. LuaJIT
|
||||
heavily optimizes and inlines Lua code E<mdash> there's no simple
|
||||
one-to-one correspondence between source code lines and the sampled
|
||||
machine code.
|
||||
|
||||
=head2 C<-jp=[options[,output]]>
|
||||
|
||||
The C<-jp> command line option starts the high-level profiler. When the
|
||||
application run by the command line terminates, the profiler stops and
|
||||
writes the results to C<stdout> or to the specified C<output> file.
|
||||
|
||||
The C<options> argument specifies how the profiling is to be performed:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<f> E<mdash> Stack dump: function name, otherwise module:line.
|
||||
This is the default mode.
|
||||
|
||||
=item * C<F> E<mdash> Stack dump: ditto, but dump module:name.
|
||||
|
||||
=item * C<l> E<mdash> Stack dump: module:line.
|
||||
|
||||
=item * C<E<lt>numberE<gt>> E<mdash> stack dump depth (callee E<larr>
|
||||
caller). Default: 1.
|
||||
|
||||
=item * C<-E<lt>numberE<gt>> E<mdash> Inverse stack dump depth (caller
|
||||
E<rarr> callee).
|
||||
|
||||
=item * C<s> E<mdash> Split stack dump after first stack level. Implies
|
||||
depth E<ge> 2 or depth E<le> -2.
|
||||
|
||||
=item * C<p> E<mdash> Show full path for module names.
|
||||
|
||||
=item * C<v> E<mdash> Show VM states.
|
||||
|
||||
=item * C<z> E<mdash> Show zones.
|
||||
|
||||
=item * C<r> E<mdash> Show raw sample counts. Default: show
|
||||
percentages.
|
||||
|
||||
=item * C<a> E<mdash> Annotate excerpts from source code files.
|
||||
|
||||
=item * C<A> E<mdash> Annotate complete source code files.
|
||||
|
||||
=item * C<G> E<mdash> Produce raw output suitable for graphical tools.
|
||||
|
||||
=item * C<mE<lt>numberE<gt>> E<mdash> Minimum sample percentage to be
|
||||
shown. Default: 3%.
|
||||
|
||||
=item * C<iE<lt>numberE<gt>> E<mdash> Sampling interval in
|
||||
milliseconds. Default: 10ms.
|
||||
|
||||
Note: The actual sampling precision is OS-dependent.
|
||||
|
||||
=back
|
||||
|
||||
The default output for C<-jp> is a list of the most CPU consuming spots
|
||||
in the application. Increasing the stack dump depth with (say) C<-jp=2>
|
||||
may help to point out the main callers or callees of hotspots. But
|
||||
sample aggregation is still flat per unique stack dump.
|
||||
|
||||
To get a two-level view (split view) of callers/callees, use C<-jp=s>
|
||||
or C<-jp=-s>. The percentages shown for the second level are relative
|
||||
to the first level.
|
||||
|
||||
To see how much time is spent in each line relative to a function, use
|
||||
C<-jp=fl>.
|
||||
|
||||
To see how much time is spent in different VM states or zones, use
|
||||
C<-jp=v> or C<-jp=z>.
|
||||
|
||||
Combinations of C<v/z> with C<f/F/l> produce two-level views, e.g.
|
||||
C<-jp=vf> or C<-jp=fv>. This shows the time spent in a VM state or zone
|
||||
vs. hotspots. This can be used to answer questions like "Which time
|
||||
consuming functions are only interpreted?" or "What's the garbage
|
||||
collector overhead for a specific function?".
|
||||
|
||||
Multiple options can be combined E<mdash> but not all combinations make
|
||||
sense, see above. E.g. C<-jp=3si4m1> samples three stack levels deep in
|
||||
4ms intervals and shows a split view of the CPU consuming functions and
|
||||
their callers with a 1% threshold.
|
||||
|
||||
Source code annotations produced by C<-jp=a> or C<-jp=A> are always
|
||||
flat and at the line level. Obviously, the source code files need to be
|
||||
readable by the profiler script.
|
||||
|
||||
The high-level profiler can also be started and stopped from Lua code
|
||||
with:
|
||||
|
||||
require("jit.p").start(options, output)
|
||||
...
|
||||
require("jit.p").stop()
|
||||
|
||||
=head2 C<jit.zone> E<mdash> Zones
|
||||
|
||||
Zones can be used to provide information about different parts of an
|
||||
application to the high-level profiler. E.g. a game could make use of
|
||||
an C<"AI"> zone, a C<"PHYS"> zone, etc. Zones are hierarchical,
|
||||
organized as a stack.
|
||||
|
||||
The C<jit.zone> module needs to be loaded explicitly:
|
||||
|
||||
local zone = require("jit.zone")
|
||||
|
||||
=over
|
||||
|
||||
=item * C<zone("name")> pushes a named zone to the zone stack.
|
||||
|
||||
=item * C<zone()> pops the current zone from the zone stack and returns
|
||||
its name.
|
||||
|
||||
=item * C<zone:get()> returns the current zone name or C<nil>.
|
||||
|
||||
=item * C<zone:flush()> flushes the zone stack.
|
||||
|
||||
=back
|
||||
|
||||
To show the time spent in each zone use C<-jp=z>. To show the time
|
||||
spent relative to hotspots use e.g. C<-jp=zf> or C<-jp=fz>.
|
||||
|
||||
=head2 Low-level Lua API
|
||||
|
||||
The C<jit.profile> module gives access to the low-level API of the
|
||||
profiler from Lua code. This module needs to be loaded explicitly:
|
||||
|
||||
local profile = require("jit.profile")
|
||||
|
||||
This module can be used to implement your own higher-level profiler. A
|
||||
typical profiling run starts the profiler, captures stack dumps in the
|
||||
profiler callback, adds them to a hash table to aggregate the number of
|
||||
samples, stops the profiler and then analyzes all of the captured stack
|
||||
dumps. Other parameters can be sampled in the profiler callback, too.
|
||||
But it's important not to spend too much time in the callback, since
|
||||
this may skew the statistics.
|
||||
|
||||
=head2 C<profile.start(mode, cb)> E<mdash> Start profiler
|
||||
|
||||
This function starts the profiler. The C<mode> argument is a string
|
||||
holding options:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<f> E<mdash> Profile with precision down to the function
|
||||
level.
|
||||
|
||||
=item * C<l> E<mdash> Profile with precision down to the line level.
|
||||
|
||||
=item * C<iE<lt>numberE<gt>> E<mdash> Sampling interval in milliseconds
|
||||
(default 10ms). Note: The actual sampling precision is OS-dependent.
|
||||
|
||||
=back
|
||||
|
||||
The C<cb> argument is a callback function which is called with three
|
||||
arguments: C<(thread, samples, vmstate)>. The callback is called on a
|
||||
separate coroutine, the C<thread> argument is the state that holds the
|
||||
stack to sample for profiling. Note: do I<not> modify the stack of that
|
||||
state or call functions on it.
|
||||
|
||||
C<samples> gives the number of accumulated samples since the last
|
||||
callback (usually 1).
|
||||
|
||||
C<vmstate> holds the VM state at the time the profiling timer
|
||||
triggered. This may or may not correspond to the state of the VM when
|
||||
the profiling callback is called. The state is either C<'N'> native
|
||||
(compiled) code, C<'I'> interpreted code, C<'C'> C code, C<'G'> the
|
||||
garbage collector, or C<'J'> the JIT compiler.
|
||||
|
||||
=head2 C<profile.stop()> E<mdash> Stop profiler
|
||||
|
||||
This function stops the profiler.
|
||||
|
||||
=head2 C<dump = profile.dumpstack([thread,] fmt, depth)> E<mdash> Dump
|
||||
stack
|
||||
|
||||
This function allows taking stack dumps in an efficient manner. It
|
||||
returns a string with a stack dump for the C<thread> (coroutine),
|
||||
formatted according to the C<fmt> argument:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<p> E<mdash> Preserve the full path for module names.
|
||||
Otherwise only the file name is used.
|
||||
|
||||
=item * C<f> E<mdash> Dump the function name if it can be derived.
|
||||
Otherwise use module:line.
|
||||
|
||||
=item * C<F> E<mdash> Ditto, but dump module:name.
|
||||
|
||||
=item * C<l> E<mdash> Dump module:line.
|
||||
|
||||
=item * C<Z> E<mdash> Zap the following characters for the last dumped
|
||||
frame.
|
||||
|
||||
=item * All other characters are added verbatim to the output string.
|
||||
|
||||
=back
|
||||
|
||||
The C<depth> argument gives the number of frames to dump, starting at
|
||||
the topmost frame of the thread. A negative number dumps the frames in
|
||||
inverse order.
|
||||
|
||||
The first example prints a list of the current module names and line
|
||||
numbers of up to 10 frames in separate lines. The second example prints
|
||||
semicolon-separated function names for all frames (up to 100) in
|
||||
inverse order:
|
||||
|
||||
print(profile.dumpstack(thread, "l\n", 10))
|
||||
print(profile.dumpstack(thread, "lZ;", -100))
|
||||
|
||||
=head2 Low-level C API
|
||||
|
||||
The profiler can be controlled directly from C code, e.g. for use by
|
||||
IDEs. The declarations are in C<"luajit.h"> (see Lua/C API extensions).
|
||||
|
||||
=head2 C<luaJIT_profile_start(L, mode, cb, data)> E<mdash> Start
|
||||
profiler
|
||||
|
||||
This function starts the profiler. See above for a description of the
|
||||
C<mode> argument.
|
||||
|
||||
The C<cb> argument is a callback function with the following
|
||||
declaration:
|
||||
|
||||
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
|
||||
int samples, int vmstate);
|
||||
|
||||
C<data> is available for use by the callback. C<L> is the state that
|
||||
holds the stack to sample for profiling. Note: do I<not> modify this
|
||||
stack or call functions on this stack E<mdash> use a separate coroutine
|
||||
for this purpose. See above for a description of C<samples> and
|
||||
C<vmstate>.
|
||||
|
||||
=head2 C<luaJIT_profile_stop(L)> E<mdash> Stop profiler
|
||||
|
||||
This function stops the profiler.
|
||||
|
||||
=head2 C<p = luaJIT_profile_dumpstack(L, fmt, depth, len)> E<mdash>
|
||||
Dump stack
|
||||
|
||||
This function allows taking stack dumps in an efficient manner. See
|
||||
above for a description of C<fmt> and C<depth>.
|
||||
|
||||
This function returns a C<const char *> pointing to a private string
|
||||
buffer of the profiler. The C<int *len> argument returns the length of
|
||||
the output string. The buffer is overwritten on the next call and
|
||||
deallocated when the profiler stops. You either need to consume the
|
||||
content immediately or copy it for later use.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file ext_profiler.html
|
||||
# 13135 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
453
doc/LuaJIT-2.1/extensions.pod
Normal file
453
doc/LuaJIT-2.1/extensions.pod
Normal file
@ -0,0 +1,453 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
|
||||
E<rchevron> standard Lua library functions and the full set of
|
||||
E<rchevron> Lua/C API functions.
|
||||
|
||||
LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
|
||||
loader level. This means you can compile a C module against the
|
||||
standard Lua headers and load the same shared library from either Lua
|
||||
or LuaJIT.
|
||||
|
||||
LuaJIT extends the standard Lua VM with new functionality and adds
|
||||
several extension modules. Please note this page is only about
|
||||
I<functional> enhancements and not about performance enhancements, such
|
||||
as the optimized VM, the faster interpreter or the JIT compiler.
|
||||
|
||||
=head2 Extensions Modules
|
||||
|
||||
LuaJIT comes with several built-in extension modules:
|
||||
|
||||
=head2 C<bit.*> E<mdash> Bitwise operations
|
||||
|
||||
LuaJIT supports all bitwise operations as defined by E<rchevron> Lua
|
||||
BitOp:
|
||||
|
||||
bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
|
||||
bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
|
||||
|
||||
This module is a LuaJIT built-in E<mdash> you don't need to download or
|
||||
install Lua BitOp. The Lua BitOp site has full documentation for all
|
||||
E<rchevron> Lua BitOp API functions. The FFI adds support for 64 bit
|
||||
bitwise operations, using the same API functions.
|
||||
|
||||
Please make sure to C<require> the module before using any of its
|
||||
functions:
|
||||
|
||||
local bit = require("bit")
|
||||
|
||||
An already installed Lua BitOp module is ignored by LuaJIT. This way
|
||||
you can use bit operations from both Lua and LuaJIT on a shared
|
||||
installation.
|
||||
|
||||
=head2 C<ffi.*> E<mdash> FFI library
|
||||
|
||||
The FFI library allows calling external C functions and the use of C
|
||||
data structures from pure Lua code.
|
||||
|
||||
=head2 C<jit.*> E<mdash> JIT compiler control
|
||||
|
||||
The functions in this module control the behavior of the JIT compiler
|
||||
engine.
|
||||
|
||||
=head2 C API extensions
|
||||
|
||||
LuaJIT adds some extra functions to the Lua/C API.
|
||||
|
||||
=head2 Profiler
|
||||
|
||||
LuaJIT has an integrated profiler.
|
||||
|
||||
=head2 Enhanced Standard Library Functions
|
||||
|
||||
=head2 C<xpcall(f, err [,args...])> passes arguments
|
||||
|
||||
Unlike the standard implementation in Lua 5.1, C<xpcall()> passes any
|
||||
arguments after the error function to the function which is called in a
|
||||
protected context.
|
||||
|
||||
=head2 C<loadfile()> etc. handle UTF-8 source code
|
||||
|
||||
Non-ASCII characters are handled transparently by the Lua source code
|
||||
parser. This allows the use of UTF-8 characters in identifiers and
|
||||
strings. A UTF-8 BOM is skipped at the start of the source code.
|
||||
|
||||
=head2 C<tostring()> etc. canonicalize NaN and E<plusmn>Inf
|
||||
|
||||
All number-to-string conversions consistently convert non-finite
|
||||
numbers to the same strings on all platforms. NaN results in C<"nan">,
|
||||
positive infinity results in C<"inf"> and negative infinity results in
|
||||
C<"-inf">.
|
||||
|
||||
=head2 C<tonumber()> etc. use builtin string to number conversion
|
||||
|
||||
All string-to-number conversions consistently convert integer and
|
||||
floating-point inputs in decimal, hexadecimal and binary on all
|
||||
platforms. C<strtod()> is I<not> used anymore, which avoids numerous
|
||||
problems with poor C library implementations. The builtin conversion
|
||||
function provides full precision according to the IEEE-754 standard, it
|
||||
works independently of the current locale and it supports hex
|
||||
floating-point numbers (e.g. C<0x1.5p-3>).
|
||||
|
||||
=head2 C<string.dump(f [,strip])> generates portable bytecode
|
||||
|
||||
An extra argument has been added to C<string.dump()>. If set to
|
||||
C<true>, 'stripped' bytecode without debug information is generated.
|
||||
This speeds up later bytecode loading and reduces memory usage. See
|
||||
also the C<-b> command line option.
|
||||
|
||||
The generated bytecode is portable and can be loaded on any
|
||||
architecture that LuaJIT supports, independent of word size or
|
||||
endianess. However the bytecode compatibility versions must match.
|
||||
Bytecode stays compatible for dot releases (x.y.0 E<rarr> x.y.1), but
|
||||
may change with major or minor releases (2.0 E<rarr> 2.1) or between
|
||||
any beta release. Foreign bytecode (e.g. from Lua 5.1) is incompatible
|
||||
and cannot be loaded.
|
||||
|
||||
Note: C<LJ_GC64> mode requires a different frame layout, which implies
|
||||
a different, incompatible bytecode format for ports that use this mode
|
||||
(e.g. ARM64). This may be rectified in the future.
|
||||
|
||||
=head2 C<table.new(narray, nhash)> allocates a pre-sized table
|
||||
|
||||
An extra library function C<table.new()> can be made available via
|
||||
C<require("table.new")>. This creates a pre-sized table, just like the
|
||||
C API equivalent C<lua_createtable()>. This is useful for big tables if
|
||||
the final table size is known and automatic table resizing is too
|
||||
expensive.
|
||||
|
||||
=head2 C<table.clear(tab)> clears a table
|
||||
|
||||
An extra library function C<table.clear()> can be made available via
|
||||
C<require("table.clear")>. This clears all keys and values from a
|
||||
table, but preserves the allocated array/hash sizes. This is useful
|
||||
when a table, which is linked from multiple places, needs to be cleared
|
||||
and/or when recycling a table for use by the same context. This avoids
|
||||
managing backlinks, saves an allocation and the overhead of incremental
|
||||
array/hash part growth.
|
||||
|
||||
Please note this function is meant for very specific situations. In
|
||||
most cases it's better to replace the (usually single) link with a new
|
||||
table and let the GC do its work.
|
||||
|
||||
=head2 Enhanced PRNG for C<math.random()>
|
||||
|
||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||
C<math.random()> and C<math.randomseed()>. The quality of the PRNG
|
||||
results is much superior compared to the standard Lua implementation
|
||||
which uses the platform-specific ANSI rand().
|
||||
|
||||
The PRNG generates the same sequences from the same seeds on all
|
||||
platforms and makes use of all bits in the seed argument.
|
||||
C<math.random()> without arguments generates 52 pseudo-random bits for
|
||||
every call. The result is uniformly distributed between 0.0 and 1.0.
|
||||
It's correctly scaled up and rounded for C<math.random(n [,m])> to
|
||||
preserve uniformity.
|
||||
|
||||
=head2 C<io.*> functions handle 64 bit file offsets
|
||||
|
||||
The file I/O functions in the standard C<io.*> library handle 64 bit
|
||||
file offsets. In particular this means it's possible to open files
|
||||
larger than 2 Gigabytes and to reposition or obtain the current file
|
||||
position for offsets beyond 2 GB (C<fp:seek()> method).
|
||||
|
||||
=head2 C<debug.*> functions identify metamethods
|
||||
|
||||
C<debug.getinfo()> and C<lua_getinfo()> also return information about
|
||||
invoked metamethods. The C<namewhat> field is set to C<"metamethod">
|
||||
and the C<name> field has the name of the corresponding metamethod
|
||||
(e.g. C<"__index">).
|
||||
|
||||
=head2 Fully Resumable VM
|
||||
|
||||
The LuaJIT VM is fully resumable. This means you can yield from a
|
||||
coroutine even across contexts, where this would not possible with the
|
||||
standard Lua 5.1 VM: e.g. you can yield across C<pcall()> and
|
||||
C<xpcall()>, across iterators and across metamethods.
|
||||
|
||||
=head2 Extensions from Lua 5.2
|
||||
|
||||
LuaJIT supports some language and library extensions from Lua 5.2.
|
||||
Features that are unlikely to break existing code are unconditionally
|
||||
enabled:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<goto> and C<::labels::>.
|
||||
|
||||
=item * Hex escapes C<'\x3F'> and C<'\*'> escape in strings.
|
||||
|
||||
=item * C<load(string|reader [, chunkname [,mode [,env]]])>.
|
||||
|
||||
=item * C<loadstring()> is an alias for C<load()>.
|
||||
|
||||
=item * C<loadfile(filename [,mode [,env]])>.
|
||||
|
||||
=item * C<math.log(x [,base])>.
|
||||
|
||||
=item * C<string.rep(s, n [,sep])>.
|
||||
|
||||
=item * C<string.format()>: C<%q> reversible. C<%s> checks
|
||||
C<__tostring>. C<%a> and C<"%A> added.
|
||||
|
||||
=item * String matching pattern C<%g> added.
|
||||
|
||||
=item * C<io.read("*L")>.
|
||||
|
||||
=item * C<io.lines()> and C<file:lines()> process C<io.read()> options.
|
||||
|
||||
=item * C<os.exit(status|true|false [,close])>.
|
||||
|
||||
=item * C<package.searchpath(name, path [, sep [, rep]])>.
|
||||
|
||||
=item * C<package.loadlib(name, "*")>.
|
||||
|
||||
=item * C<debug.getinfo()> returns C<nparams> and C<isvararg> for
|
||||
option C<"u">.
|
||||
|
||||
=item * C<debug.getlocal()> accepts function instead of level.
|
||||
|
||||
=item * C<debug.getlocal()> and C<debug.setlocal()> accept negative
|
||||
indexes for varargs.
|
||||
|
||||
=item * C<debug.getupvalue()> and C<debug.setupvalue()> handle C
|
||||
functions.
|
||||
|
||||
=item * C<debug.upvalueid()> and C<debug.upvaluejoin()>.
|
||||
|
||||
=item * Command line option C<-E>.
|
||||
|
||||
=item * Command line checks C<__tostring> for errors.
|
||||
|
||||
=back
|
||||
|
||||
Other features are only enabled, if LuaJIT is built with
|
||||
C<-DLUAJIT_ENABLE_LUA52COMPAT>:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<goto> is a keyword and not a valid variable name anymore.
|
||||
|
||||
=item * C<break> can be placed anywhere. Empty statements (C<;;>) are
|
||||
allowed.
|
||||
|
||||
=item * C<__lt>, C<__le> are invoked for mixed types.
|
||||
|
||||
=item * C<__len> for tables. C<rawlen()> library function.
|
||||
|
||||
=item * C<pairs()> and C<ipairs()> check for C<__pairs> and
|
||||
C<__ipairs>.
|
||||
|
||||
=item * C<coroutine.running()> returns two results.
|
||||
|
||||
=item * C<table.pack()> and C<table.unpack()> (same as C<unpack()>).
|
||||
|
||||
=item * C<io.write()> and C<file:write()> return file handle instead of
|
||||
C<true>.
|
||||
|
||||
=item * C<os.execute()> and C<pipe:close()> return detailed exit
|
||||
status.
|
||||
|
||||
=item * C<debug.setmetatable()> returns object.
|
||||
|
||||
=item * C<debug.getuservalue()> and C<debug.setuservalue()>.
|
||||
|
||||
=item * Remove C<math.mod()>, C<string.gfind()>.
|
||||
|
||||
=back
|
||||
|
||||
Note: this provides only partial compatibility with Lua 5.2 at the
|
||||
language and Lua library level. LuaJIT is API+ABI-compatible with Lua
|
||||
5.1, which prevents implementing features that would otherwise break
|
||||
the Lua/C API and ABI (e.g. C<_ENV>).
|
||||
|
||||
=head2 Extensions from Lua 5.3
|
||||
|
||||
LuaJIT supports some extensions from Lua 5.3:
|
||||
|
||||
=over
|
||||
|
||||
=item * Unicode escape C<'\u{XX...}'> embeds the UTF-8 encoding in
|
||||
string literals.
|
||||
|
||||
=back
|
||||
|
||||
=head2 C++ Exception Interoperability
|
||||
|
||||
LuaJIT has built-in support for interoperating with C++ exceptions. The
|
||||
available range of features depends on the target platform and the
|
||||
toolchain used to compile LuaJIT:
|
||||
|
||||
Platform
|
||||
|
||||
Compiler
|
||||
|
||||
Interoperability
|
||||
|
||||
POSIX/x64, DWARF2 unwinding
|
||||
|
||||
GCC 4.3+, Clang
|
||||
|
||||
B<Full>
|
||||
|
||||
ARM C<-DLUAJIT_UNWIND_EXTERNAL>
|
||||
|
||||
GCC, Clang
|
||||
|
||||
B<Full>
|
||||
|
||||
Other platforms, DWARF2 unwinding
|
||||
|
||||
GCC, Clang
|
||||
|
||||
B<Limited>
|
||||
|
||||
Windows/x64
|
||||
|
||||
MSVC or WinSDK
|
||||
|
||||
B<Full>
|
||||
|
||||
Windows/x86
|
||||
|
||||
Any
|
||||
|
||||
B<Full>
|
||||
|
||||
Other platforms
|
||||
|
||||
Other compilers
|
||||
|
||||
B<No>
|
||||
|
||||
B<Full interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * C++ exceptions can be caught on the Lua side with C<pcall()>,
|
||||
C<lua_pcall()> etc.
|
||||
|
||||
=item * C++ exceptions will be converted to the generic Lua error
|
||||
C<"C++ exception">, unless you use the C call wrapper feature.
|
||||
|
||||
=item * It's safe to throw C++ exceptions across non-protected Lua
|
||||
frames on the C stack. The contents of the C++ exception object pass
|
||||
through unmodified.
|
||||
|
||||
=item * Lua errors can be caught on the C++ side with C<catch(...)>.
|
||||
The corresponding Lua error message can be retrieved from the Lua
|
||||
stack.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames is safe. C++ destructors
|
||||
will be called.
|
||||
|
||||
=back
|
||||
|
||||
B<Limited interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * C++ exceptions can be caught on the Lua side with C<pcall()>,
|
||||
C<lua_pcall()> etc.
|
||||
|
||||
=item * C++ exceptions will be converted to the generic Lua error
|
||||
C<"C++ exception">, unless you use the C call wrapper feature.
|
||||
|
||||
=item * C++ exceptions will be caught by non-protected Lua frames and
|
||||
are rethrown as a generic Lua error. The C++ exception object will be
|
||||
destroyed.
|
||||
|
||||
=item * Lua errors B<cannot> be caught on the C++ side.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames will B<not> call C++
|
||||
destructors.
|
||||
|
||||
=back
|
||||
|
||||
B<No interoperability> means:
|
||||
|
||||
=over
|
||||
|
||||
=item * It's B<not> safe to throw C++ exceptions across Lua frames.
|
||||
|
||||
=item * C++ exceptions B<cannot> be caught on the Lua side.
|
||||
|
||||
=item * Lua errors B<cannot> be caught on the C++ side.
|
||||
|
||||
=item * Throwing Lua errors across C++ frames will B<not> call C++
|
||||
destructors.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file extensions.html
|
||||
# 16722 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
224
doc/LuaJIT-2.1/faq.pod
Normal file
224
doc/LuaJIT-2.1/faq.pod
Normal file
@ -0,0 +1,224 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Frequently Asked Questions (FAQ)
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Where can I learn more about LuaJIT and Lua?
|
||||
|
||||
=over
|
||||
|
||||
=item * The E<rchevron> LuaJIT mailing list focuses on topics related
|
||||
to LuaJIT.
|
||||
|
||||
=item * The E<rchevron> LuaJIT wiki gathers community resources about
|
||||
LuaJIT.
|
||||
|
||||
=item * News about Lua itself can be found at the E<rchevron> Lua
|
||||
mailing list. The mailing list archives are worth checking out for
|
||||
older postings about LuaJIT.
|
||||
|
||||
=item * The E<rchevron> main Lua.org site has complete E<rchevron>
|
||||
documentation of the language and links to books and papers about Lua.
|
||||
|
||||
=item * The community-managed E<rchevron> Lua Wiki has information
|
||||
about diverse topics.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Where can I learn more about the compiler technology used by
|
||||
LuaJIT?
|
||||
|
||||
I'm planning to write more documentation about the internals of LuaJIT.
|
||||
In the meantime, please use the following Google Scholar searches to
|
||||
find relevant papers:
|
||||
|
||||
Search for: E<rchevron> Trace Compiler
|
||||
|
||||
Search for: E<rchevron> JIT Compiler
|
||||
|
||||
Search for: E<rchevron> Dynamic Language Optimizations
|
||||
|
||||
Search for: E<rchevron> SSA Form
|
||||
|
||||
Search for: E<rchevron> Linear Scan Register Allocation
|
||||
|
||||
Here is a list of the E<rchevron> innovative features in LuaJIT.
|
||||
|
||||
And, you know, reading the source is of course the only way to
|
||||
enlightenment. :-)
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why do I get this error: "attempt to index global 'arg' (a nil
|
||||
value)"?
|
||||
|
||||
Q: My vararg functions fail after switching to LuaJIT!
|
||||
|
||||
LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
|
||||
support the implicit C<arg> parameter for old-style vararg functions
|
||||
from Lua 5.0.
|
||||
|
||||
Please convert your code to the E<rchevron> Lua 5.1 vararg syntax.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why do I get this error: "bad FPU precision"?
|
||||
|
||||
=item Q: I get weird behavior after initializing Direct3D.
|
||||
|
||||
=item Q: Some FPU operations crash after I load a Delphi DLL.
|
||||
|
||||
DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
|
||||
mode by default. This violates the Windows ABI and interferes with the
|
||||
operation of many programs E<mdash> LuaJIT is affected, too. Please
|
||||
make sure you always use the C<D3DCREATE_FPU_PRESERVE> flag when
|
||||
initializing Direct3D.
|
||||
|
||||
Direct3D version 10 or higher do not show this behavior anymore.
|
||||
Consider testing your application with older versions, too.
|
||||
|
||||
Similarly, the Borland/Delphi runtime modifies the FPU control word and
|
||||
enables FP exceptions. Of course this violates the Windows ABI, too.
|
||||
Please check the Delphi docs for the Set8087CW method.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Sometimes Ctrl-C fails to stop my Lua program. Why?
|
||||
|
||||
The interrupt signal handler sets a Lua debug hook. But this is
|
||||
currently ignored by compiled code (this will eventually be fixed). If
|
||||
your program is running in a tight loop and never falls back to the
|
||||
interpreter, the debug hook never runs and can't throw the
|
||||
"interrupted!" error.
|
||||
|
||||
In the meantime you have to press Ctrl-C twice to get stop your
|
||||
program. That's similar to when it's stuck running inside a C function
|
||||
under the Lua interpreter.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Why doesn't my favorite power-patch for Lua apply against
|
||||
LuaJIT?
|
||||
|
||||
Because it's a completely redesigned VM and has very little code in
|
||||
common with Lua anymore. Also, if the patch introduces changes to the
|
||||
Lua semantics, these would need to be reflected everywhere in the VM,
|
||||
from the interpreter up to all stages of the compiler.
|
||||
|
||||
Please use only standard Lua language constructs. For many common needs
|
||||
you can use source transformations or use wrapper or proxy functions.
|
||||
The compiler will happily optimize away such indirections.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?
|
||||
|
||||
Because it's a compiler E<mdash> it needs to generate native machine
|
||||
code. This means the code generator must be ported to each
|
||||
architecture. And the fast interpreter is written in assembler and must
|
||||
be ported, too. This is quite an undertaking.
|
||||
|
||||
The install documentation shows the supported architectures. Other
|
||||
architectures will follow based on sufficient user demand and/or
|
||||
sponsoring.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item Q: When will feature X be added? When will the next version be
|
||||
released?
|
||||
|
||||
When it's ready.
|
||||
|
||||
C'mon, it's open source E<mdash> I'm doing it on my own time and you're
|
||||
getting it for free. You can either contribute a patch or sponsor the
|
||||
development of certain features, if they are important to you.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file faq.html
|
||||
# 7685 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
698
doc/LuaJIT-2.1/install.pod
Normal file
698
doc/LuaJIT-2.1/install.pod
Normal file
@ -0,0 +1,698 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Installation
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT is only distributed as a source package. This page explains how
|
||||
to build and install LuaJIT with different operating systems and C
|
||||
compilers.
|
||||
|
||||
For the impatient (on POSIX systems):
|
||||
|
||||
make && sudo make install
|
||||
|
||||
LuaJIT currently builds out-of-the box on most systems. Here's the
|
||||
compatibility matrix for the supported combinations of operating
|
||||
systems, CPUs and compilers:
|
||||
|
||||
CPU / OS
|
||||
|
||||
Linux or
|
||||
|
||||
Android
|
||||
|
||||
*BSD, Other
|
||||
|
||||
OSX 10.4+ or
|
||||
|
||||
iOS 3.0+
|
||||
|
||||
Windows
|
||||
|
||||
XP/Vista/7
|
||||
|
||||
x86 (32 bit)
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
MSVC, MSVC/EE
|
||||
|
||||
WinSDK
|
||||
|
||||
MinGW, Cygwin
|
||||
|
||||
x64 (64 bit)
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
ORBIS (PS4)
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
MSVC + SDK v7.0
|
||||
|
||||
WinSDK v7.0
|
||||
|
||||
Durango (Xbox One)
|
||||
|
||||
ARMv5+
|
||||
|
||||
ARM9E+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
GCC 4.2+
|
||||
|
||||
PSP2 (PS VITA)
|
||||
|
||||
XCode 5.0+
|
||||
|
||||
Clang
|
||||
|
||||
ARM64
|
||||
|
||||
GCC 4.8+
|
||||
|
||||
XCode 6.0+
|
||||
|
||||
Clang 3.5+
|
||||
|
||||
PPC
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.1 (PS3)
|
||||
|
||||
XEDK (Xbox 360)
|
||||
|
||||
MIPS32
|
||||
|
||||
MIPS64
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
GCC 4.3+
|
||||
|
||||
=head2 Configuring LuaJIT
|
||||
|
||||
The standard configuration should work fine for most installations.
|
||||
Usually there is no need to tweak the settings. The following files
|
||||
hold all user-configurable settings:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<src/luaconf.h> sets some configuration variables.
|
||||
|
||||
=item * C<Makefile> has settings for B<installing> LuaJIT (POSIX only).
|
||||
|
||||
=item * C<src/Makefile> has settings for B<compiling> LuaJIT under
|
||||
POSIX, MinGW or Cygwin.
|
||||
|
||||
=item * C<src/msvcbuild.bat> has settings for compiling LuaJIT with
|
||||
MSVC or WinSDK.
|
||||
|
||||
=back
|
||||
|
||||
Please read the instructions given in these files, before changing any
|
||||
settings.
|
||||
|
||||
=head2 POSIX Systems (Linux, OSX, *BSD etc.)
|
||||
|
||||
=head2 Prerequisites
|
||||
|
||||
Depending on your distribution, you may need to install a package for
|
||||
GCC, the development headers and/or a complete SDK. E.g. on a current
|
||||
Debian/Ubuntu, install C<libc6-dev> with the package manager.
|
||||
|
||||
Download the current source package of LuaJIT (pick the .tar.gz), if
|
||||
you haven't already done so. Move it to a directory of your choice,
|
||||
open a terminal window and change to this directory. Now unpack the
|
||||
archive and change to the newly created directory:
|
||||
|
||||
tar zxf LuaJIT-2.0.4.tar.gz
|
||||
cd LuaJIT-2.0.4
|
||||
|
||||
=head2 Building LuaJIT
|
||||
|
||||
The supplied Makefiles try to auto-detect the settings needed for your
|
||||
operating system and your compiler. They need to be run with GNU Make,
|
||||
which is probably the default on your system, anyway. Simply run:
|
||||
|
||||
make
|
||||
|
||||
This always builds a native binary, depending on the host OS you're
|
||||
running this command on. Check the section on cross-compilation for
|
||||
more options.
|
||||
|
||||
By default, modules are only searched under the prefix C</usr/local>.
|
||||
You can add an extra prefix to the search paths by appending the
|
||||
C<PREFIX> option, e.g.:
|
||||
|
||||
make PREFIX=/home/myself/lj2
|
||||
|
||||
Note for OSX: if the C<MACOSX_DEPLOYMENT_TARGET> environment variable
|
||||
is not set, then it's forced to C<10.4>.
|
||||
|
||||
=head2 Installing LuaJIT
|
||||
|
||||
The top-level Makefile installs LuaJIT by default under C</usr/local>,
|
||||
i.e. the executable ends up in C</usr/local/bin> and so on. You need
|
||||
root privileges to write to this path. So, assuming sudo is installed
|
||||
on your system, run the following command and enter your sudo password:
|
||||
|
||||
sudo make install
|
||||
|
||||
Otherwise specify the directory prefix as an absolute path, e.g.:
|
||||
|
||||
make install PREFIX=/home/myself/lj2
|
||||
|
||||
Obviously the prefixes given during build and installation need to be
|
||||
the same.
|
||||
|
||||
=head2 Windows Systems
|
||||
|
||||
=head2 Prerequisites
|
||||
|
||||
Either install one of the open source SDKs (E<rchevron> MinGW or
|
||||
E<rchevron> Cygwin), which come with a modified GCC plus the required
|
||||
development headers.
|
||||
|
||||
Or install Microsoft's Visual C++ (MSVC). The freely downloadable
|
||||
E<rchevron> Express Edition works just fine, but only contains an x86
|
||||
compiler.
|
||||
|
||||
The freely downloadable E<rchevron> Windows SDK only comes with command
|
||||
line tools, but this is all you need to build LuaJIT. It contains x86
|
||||
and x64 compilers.
|
||||
|
||||
Next, download the source package and unpack it using an archive
|
||||
manager (e.g. the Windows Explorer) to a directory of your choice.
|
||||
|
||||
=head2 Building with MSVC
|
||||
|
||||
Open a "Visual Studio .NET Command Prompt", C<cd> to the directory
|
||||
where you've unpacked the sources and run these commands:
|
||||
|
||||
cd src
|
||||
msvcbuild
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Building with the Windows SDK
|
||||
|
||||
Open a "Windows SDK Command Shell" and select the x86 compiler:
|
||||
|
||||
setenv /release /x86
|
||||
|
||||
Or select the x64 compiler:
|
||||
|
||||
setenv /release /x64
|
||||
|
||||
Then C<cd> to the directory where you've unpacked the sources and run
|
||||
these commands:
|
||||
|
||||
cd src
|
||||
msvcbuild
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Building with MinGW or Cygwin
|
||||
|
||||
Open a command prompt window and make sure the MinGW or Cygwin programs
|
||||
are in your path. Then C<cd> to the directory where you've unpacked the
|
||||
sources and run this command for MinGW:
|
||||
|
||||
mingw32-make
|
||||
|
||||
Or this command for Cygwin:
|
||||
|
||||
make
|
||||
|
||||
Then follow the installation instructions below.
|
||||
|
||||
=head2 Installing LuaJIT
|
||||
|
||||
Copy C<luajit.exe> and C<lua51.dll> (built in the C<src> directory) to
|
||||
a newly created directory (any location is ok). Add C<lua> and
|
||||
C<lua\jit> directories below it and copy all Lua files from the
|
||||
C<src\jit> directory of the distribution to the latter directory.
|
||||
|
||||
There are no hardcoded absolute path names E<mdash> all modules are
|
||||
loaded relative to the directory where C<luajit.exe> is installed (see
|
||||
C<src/luaconf.h>).
|
||||
|
||||
=head2 Cross-compiling LuaJIT
|
||||
|
||||
First, let's clear up some terminology:
|
||||
|
||||
=over
|
||||
|
||||
=item * Host: This is your development system, usually based on a x64
|
||||
or x86 CPU.
|
||||
|
||||
=item * Target: This is the target system you want LuaJIT to run on,
|
||||
e.g. Android/ARM.
|
||||
|
||||
=item * Toolchain: This comprises a C compiler, linker, assembler and a
|
||||
matching C library.
|
||||
|
||||
=item * Host (or system) toolchain: This is the toolchain used to build
|
||||
native binaries for your host system.
|
||||
|
||||
=item * Cross-compile toolchain: This is the toolchain used to build
|
||||
binaries for the target system. They can only be run on the target
|
||||
system.
|
||||
|
||||
=back
|
||||
|
||||
The GNU Makefile-based build system allows cross-compiling on any host
|
||||
for any supported target:
|
||||
|
||||
=over
|
||||
|
||||
=item * Yes, you need a toolchain for both your host I<and> your
|
||||
target!
|
||||
|
||||
=item * Both host and target architectures must have the same pointer
|
||||
size.
|
||||
|
||||
=item * E.g. if you want to cross-compile to a 32 bit target on a 64
|
||||
bit host, you need to install the multilib development package (e.g.
|
||||
C<libc6-dev-i386> on Debian/Ubuntu) and build a 32 bit host part
|
||||
(C<HOST_CC="gcc -m32">).
|
||||
|
||||
=item * 64 bit targets always require compilation on a 64 bit host.
|
||||
|
||||
=back
|
||||
|
||||
You need to specify C<TARGET_SYS> whenever the host OS and the target
|
||||
OS differ, or you'll get assembler or linker errors:
|
||||
|
||||
=over
|
||||
|
||||
=item * E.g. if you're compiling on a Windows or OSX host for embedded
|
||||
Linux or Android, you need to add C<TARGET_SYS=Linux> to the examples
|
||||
below.
|
||||
|
||||
=item * For a minimal target OS, you may need to disable the built-in
|
||||
allocator in C<src/Makefile> and use C<TARGET_SYS=Other>.
|
||||
|
||||
=item * Don't forget to specify the same C<TARGET_SYS> for the install
|
||||
step, too.
|
||||
|
||||
=back
|
||||
|
||||
Here are some examples where host and target have the same CPU:
|
||||
|
||||
# Cross-compile to a 32 bit binary on a multilib x64 OS
|
||||
make CC="gcc -m32"
|
||||
|
||||
# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)
|
||||
make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
|
||||
|
||||
The C<CROSS> prefix allows specifying a standard GNU cross-compile
|
||||
toolchain (Binutils, GCC and a matching libc). The prefix may vary
|
||||
depending on the C<--target> the toolchain was built for (note the
|
||||
C<CROSS> prefix has a trailing C<"-">). The examples below use the
|
||||
canonical toolchain triplets for Linux.
|
||||
|
||||
Since there's often no easy way to detect CPU features at runtime, it's
|
||||
important to compile with the proper CPU or architecture settings:
|
||||
|
||||
=over
|
||||
|
||||
=item * The best way to get consistent results is to specify the
|
||||
correct settings when building the toolchain yourself.
|
||||
|
||||
=item * For a pre-built, generic toolchain add C<-mcpu=...> or
|
||||
C<-march=...> and other necessary flags to C<TARGET_CFLAGS>.
|
||||
|
||||
=item * For ARM it's important to have the correct C<-mfloat-abi=...>
|
||||
setting, too. Otherwise LuaJIT may not run at the full performance of
|
||||
your target CPU.
|
||||
|
||||
=item * For MIPS it's important to select a supported ABI (o32 on
|
||||
MIPS32, n64 on MIPS64) and consistently compile your project either
|
||||
with hard-float or soft-float compiler settings.
|
||||
|
||||
=back
|
||||
|
||||
Here are some examples for targets with a different CPU than the host:
|
||||
|
||||
# ARM soft-float
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mfloat-abi=soft"
|
||||
|
||||
# ARM soft-float ABI with VFP (example for Cortex-A9)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
|
||||
|
||||
# ARM hard-float ABI with VFP (armhf, most modern toolchains)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
|
||||
|
||||
# ARM64
|
||||
make CROSS=aarch64-linux-
|
||||
|
||||
# PPC
|
||||
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
|
||||
|
||||
# MIPS32 big-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mips-linux-
|
||||
# MIPS32 little-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mipsel-linux-
|
||||
|
||||
# MIPS64 big-endian
|
||||
make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
# MIPS64 little-endian
|
||||
make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
|
||||
You can cross-compile for B<Android> using the Android NDK. The
|
||||
environment variables need to match the install locations and the
|
||||
desired target platform. E.g. Android 4.0 corresponds to ABI level 14.
|
||||
For details check the folder C<docs> in the NDK directory.
|
||||
|
||||
Only a few common variations for the different CPUs, ABIs and platforms
|
||||
are listed. Please use your own judgement for which combination you
|
||||
want to build/deploy or which lowest common denominator you want to
|
||||
pick:
|
||||
|
||||
# Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=8
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF $NDKARCH"
|
||||
|
||||
# Android/MIPS, mipsel (MIPS32R1 hard-float), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/mipsel-linux-android-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/mipsel-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-mips"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/x86-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/i686-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
You can cross-compile for B<iOS 3.0+> (iPhone/iPad) using the
|
||||
E<rchevron> iOS SDK:
|
||||
|
||||
Note: B<the JIT compiler is disabled for iOS>, because regular iOS Apps
|
||||
are not allowed to generate code at runtime. You'll only get the
|
||||
performance of the LuaJIT interpreter on iOS. This is still faster than
|
||||
plain Lua, but much slower than the JIT compiler. Please complain to
|
||||
Apple, not me. Or use Android. :-p
|
||||
|
||||
# iOS/ARM (32 bit)
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch armv7 -isysroot $ISDKP"
|
||||
make HOST_CC="clang -m32 -arch i386" CROSS="$(dirname $ICC)/" \
|
||||
TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
|
||||
# iOS/ARM64
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch arm64 -isysroot $ISDKP"
|
||||
make CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
|
||||
=head2 Cross-compiling for consoles
|
||||
|
||||
Building LuaJIT for consoles requires both a supported host compiler
|
||||
(x86 or x64) and a cross-compiler (to PPC or ARM) from the official
|
||||
console SDK.
|
||||
|
||||
Due to restrictions on consoles, the JIT compiler is disabled and only
|
||||
the fast interpreter is built. This is still faster than plain Lua, but
|
||||
much slower than the JIT compiler. The FFI is disabled, too, since it's
|
||||
not very useful in such an environment.
|
||||
|
||||
The following commands build a static library C<libluajit.a>, which can
|
||||
be linked against your game, just like the Lua library.
|
||||
|
||||
To cross-compile for B<PS3> from a Linux host (requires 32 bit GCC,
|
||||
i.e. multilib Linux/x64) or a Windows host (requires 32 bit MinGW), run
|
||||
this command:
|
||||
|
||||
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
|
||||
|
||||
To cross-compile for B<PS4> from a Windows host, open a "Visual Studio
|
||||
.NET Command Prompt" (64 bit host compiler), C<cd> to the directory
|
||||
where you've unpacked the sources and run the following commands:
|
||||
|
||||
cd src
|
||||
ps4build
|
||||
|
||||
To cross-compile for B<PS Vita> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (32 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
psvitabuild
|
||||
|
||||
To cross-compile for B<Xbox 360> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (32 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
xedkbuild
|
||||
|
||||
To cross-compile for B<Xbox One> from a Windows host, open a "Visual
|
||||
Studio .NET Command Prompt" (64 bit host compiler), C<cd> to the
|
||||
directory where you've unpacked the sources and run the following
|
||||
commands:
|
||||
|
||||
cd src
|
||||
xb1build
|
||||
|
||||
=head2 Embedding LuaJIT
|
||||
|
||||
LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
|
||||
into your application, you probably don't need to do anything to switch
|
||||
to LuaJIT, except link with a different library:
|
||||
|
||||
=over
|
||||
|
||||
=item * It's strongly suggested to build LuaJIT separately using the
|
||||
supplied build system. Please do I<not> attempt to integrate the
|
||||
individual source files into your build tree. You'll most likely get
|
||||
the internal build dependencies wrong or mess up the compiler flags.
|
||||
Treat LuaJIT like any other external library and link your application
|
||||
with either the dynamic or static library, depending on your needs.
|
||||
|
||||
=item * If you want to load C modules compiled for plain Lua with
|
||||
C<require()>, you need to make sure the public symbols (e.g.
|
||||
C<lua_pushnumber>) are exported, too:
|
||||
|
||||
=over
|
||||
|
||||
=item * On POSIX systems you can either link to the shared library or
|
||||
link the static library into your application. In the latter case
|
||||
you'll need to export all public symbols from your main executable
|
||||
(e.g. C<-Wl,-E> on Linux) and add the external dependencies (e.g. C<-lm
|
||||
-ldl> on Linux).
|
||||
|
||||
=item * Since Windows symbols are bound to a specific DLL name, you
|
||||
need to link to the C<lua51.dll> created by the LuaJIT build (do not
|
||||
rename the DLL). You may link LuaJIT statically on Windows only if you
|
||||
don't intend to load Lua/C modules at runtime.
|
||||
|
||||
=back
|
||||
|
||||
=item * If you're building a 64 bit application on OSX which links
|
||||
directly or indirectly against LuaJIT, you need to link your main
|
||||
executable with these flags:
|
||||
|
||||
-pagezero_size 10000 -image_base 100000000
|
||||
|
||||
Also, it's recommended to C<rebase> all (self-compiled) shared
|
||||
libraries which are loaded at runtime on OSX/x64 (e.g. C extension
|
||||
modules for Lua). See: C<man rebase>
|
||||
|
||||
=back
|
||||
|
||||
Additional hints for initializing LuaJIT using the C API functions:
|
||||
|
||||
=over
|
||||
|
||||
=item * Here's a E<rchevron> simple example for embedding Lua or LuaJIT
|
||||
into your application.
|
||||
|
||||
=item * Make sure you use C<luaL_newstate>. Avoid using
|
||||
C<lua_newstate>, since this uses the (slower) default memory allocator
|
||||
from your system (no support for this on x64).
|
||||
|
||||
=item * Make sure you use C<luaL_openlibs> and not the old Lua 5.0
|
||||
style of calling C<luaopen_base> etc. directly.
|
||||
|
||||
=item * To change or extend the list of standard libraries to load,
|
||||
copy C<src/lib_init.c> to your project and modify it accordingly. Make
|
||||
sure the C<jit> library is loaded or the JIT compiler will not be
|
||||
activated.
|
||||
|
||||
=item * The C<bit.*> module for bitwise operations is already built-in.
|
||||
There's no need to statically link E<rchevron> Lua BitOp to your
|
||||
application.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Hints for Distribution Maintainers
|
||||
|
||||
The LuaJIT build system has extra provisions for the needs of most
|
||||
POSIX-based distributions. If you're a package maintainer for a
|
||||
distribution, I<please> make use of these features and avoid patching,
|
||||
subverting, autotoolizing or messing up the build system in unspeakable
|
||||
ways.
|
||||
|
||||
There should be absolutely no need to patch C<luaconf.h> or any of the
|
||||
Makefiles. And please do not hand-pick files for your packages E<mdash>
|
||||
simply use whatever C<make install> creates. There's a reason for all
|
||||
of the files I<and> directories it creates.
|
||||
|
||||
The build system uses GNU make and auto-detects most settings based on
|
||||
the host you're building it on. This should work fine for native
|
||||
builds, even when sandboxed. You may need to pass some of the following
|
||||
flags to I<both> the C<make> and the C<make install> command lines for
|
||||
a regular distribution build:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<PREFIX> overrides the installation path and should usually be
|
||||
set to C</usr>. Setting this also changes the module paths and the
|
||||
paths needed to locate the shared library.
|
||||
|
||||
=item * C<DESTDIR> is an absolute path which allows you to install to a
|
||||
shadow tree instead of the root tree of the build system.
|
||||
|
||||
=item * C<MULTILIB> sets the architecture-specific library path
|
||||
component for multilib systems. The default is C<lib>.
|
||||
|
||||
=item * Have a look at the top-level C<Makefile> and C<src/Makefile>
|
||||
for additional variables to tweak. The following variables I<may> be
|
||||
overridden, but it's I<not> recommended, except for special needs like
|
||||
cross-builds: C<BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS,
|
||||
HOST_CFLAGS, TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS,
|
||||
TARGET_SHLDFLAGS, TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS,
|
||||
HOST_SYS, TARGET_SYS>
|
||||
|
||||
=back
|
||||
|
||||
The build system has a special target for an amalgamated build, i.e.
|
||||
C<make amalg>. This compiles the LuaJIT core as one huge C file and
|
||||
allows GCC to generate faster and shorter code. Alas, this requires
|
||||
lots of memory during the build. This may be a problem for some users,
|
||||
that's why it's not enabled by default. But it shouldn't be a problem
|
||||
for most build farms. It's recommended that binary distributions use
|
||||
this target for their LuaJIT builds.
|
||||
|
||||
The tl;dr version of the above:
|
||||
|
||||
make amalg PREFIX=/usr && \
|
||||
make install PREFIX=/usr DESTDIR=/tmp/buildroot
|
||||
|
||||
Finally, if you encounter any difficulties, please contact me first,
|
||||
instead of releasing a broken package onto unsuspecting users. Because
|
||||
they'll usually gonna complain to me (the upstream) and not you (the
|
||||
package maintainer), anyway.
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file install.html
|
||||
# 25008 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
||||
# Deleting phrasal "a" element (`a_34) because it has super-phrasal elements (`br_16) as children.
|
||||
# Deleting phrasal "a" element (`a_28) because it has super-phrasal elements (`br_11) as children.
|
||||
# Deleting phrasal "a" element (`a_25) because it has super-phrasal elements (`br_3) as children.
|
421
doc/LuaJIT-2.1/running.pod
Normal file
421
doc/LuaJIT-2.1/running.pod
Normal file
@ -0,0 +1,421 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Running LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT has only a single stand-alone executable, called C<luajit> on
|
||||
POSIX systems or C<luajit.exe> on Windows. It can be used to run simple
|
||||
Lua statements or whole Lua applications from the command line. It has
|
||||
an interactive mode, too.
|
||||
|
||||
=head2 Command Line Options
|
||||
|
||||
The C<luajit> stand-alone executable is just a slightly modified
|
||||
version of the regular C<lua> stand-alone executable. It supports the
|
||||
same basic options, too. C<luajit -h> prints a short list of the
|
||||
available options. Please have a look at the E<rchevron> Lua manual for
|
||||
details.
|
||||
|
||||
LuaJIT has some additional options:
|
||||
|
||||
=head2 C<-b[options] input output>
|
||||
|
||||
This option saves or lists bytecode. The following additional options
|
||||
are accepted:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<-l> E<mdash> Only list bytecode.
|
||||
|
||||
=item * C<-s> E<mdash> Strip debug info (this is the default).
|
||||
|
||||
=item * C<-g> E<mdash> Keep debug info.
|
||||
|
||||
=item * C<-n name> E<mdash> Set module name (default: auto-detect from
|
||||
input name)
|
||||
|
||||
=item * C<-t type> E<mdash> Set output file type (default: auto-detect
|
||||
from output name).
|
||||
|
||||
=item * C<-a arch> E<mdash> Override architecture for object files
|
||||
(default: native).
|
||||
|
||||
=item * C<-o os> E<mdash> Override OS for object files (default:
|
||||
native).
|
||||
|
||||
=item * C<-e chunk> E<mdash> Use chunk string as input.
|
||||
|
||||
=item * C<-> (a single minus sign) E<mdash> Use stdin as input and/or
|
||||
stdout as output.
|
||||
|
||||
=back
|
||||
|
||||
The output file type is auto-detected from the extension of the output
|
||||
file name:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<c> E<mdash> C source file, exported bytecode data.
|
||||
|
||||
=item * C<h> E<mdash> C header file, static bytecode data.
|
||||
|
||||
=item * C<obj> or C<o> E<mdash> Object file, exported bytecode data
|
||||
(OS- and architecture-specific).
|
||||
|
||||
=item * C<raw> or any other extension E<mdash> Raw bytecode file
|
||||
(portable).
|
||||
|
||||
=back
|
||||
|
||||
Notes:
|
||||
|
||||
=over
|
||||
|
||||
=item * See also string.dump() for information on bytecode portability
|
||||
and compatibility.
|
||||
|
||||
=item * A file in raw bytecode format is auto-detected and can be
|
||||
loaded like any Lua source file. E.g. directly from the command line or
|
||||
with C<loadfile()>, C<dofile()> etc.
|
||||
|
||||
=item * To statically embed the bytecode of a module in your
|
||||
application, generate an object file and just link it with your
|
||||
application.
|
||||
|
||||
=item * On most ELF-based systems (e.g. Linux) you need to explicitly
|
||||
export the global symbols when linking your application, e.g. with:
|
||||
C<-Wl,-E>
|
||||
|
||||
=item * C<require()> tries to load embedded bytecode data from exported
|
||||
symbols (in C<*.exe> or C<lua51.dll> on Windows) and from shared
|
||||
libraries in C<package.cpath>.
|
||||
|
||||
=back
|
||||
|
||||
Typical usage examples:
|
||||
|
||||
luajit -b test.lua test.out # Save bytecode to test.out
|
||||
luajit -bg test.lua test.out # Keep debug info
|
||||
luajit -be "print('hello world')" test.out # Save cmdline script
|
||||
|
||||
luajit -bl test.lua # List to stdout
|
||||
luajit -bl test.lua test.txt # List to test.txt
|
||||
luajit -ble "print('hello world')" # List cmdline script
|
||||
|
||||
luajit -b test.lua test.obj # Generate object file
|
||||
# Link test.obj with your application and load it with require("test")
|
||||
|
||||
=head2 C<-j cmd[=arg[,arg...]]>
|
||||
|
||||
This option performs a LuaJIT control command or activates one of the
|
||||
loadable extension modules. The command is first looked up in the
|
||||
C<jit.*> library. If no matching function is found, a module named
|
||||
C<jit.E<lt>cmdE<gt>> is loaded and the C<start()> function of the
|
||||
module is called with the specified arguments (if any). The space
|
||||
between C<-j> and C<cmd> is optional.
|
||||
|
||||
Here are the available LuaJIT control commands:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<-jon> E<mdash> Turns the JIT compiler on (default).
|
||||
|
||||
=item * C<-joff> E<mdash> Turns the JIT compiler off (only use the
|
||||
interpreter).
|
||||
|
||||
=item * C<-jflush> E<mdash> Flushes the whole cache of compiled code.
|
||||
|
||||
=item * C<-jv> E<mdash> Shows verbose information about the progress of
|
||||
the JIT compiler.
|
||||
|
||||
=item * C<-jdump> E<mdash> Dumps the code and structures used in
|
||||
various compiler stages.
|
||||
|
||||
=item * C<-jp> E<mdash> Start the integrated profiler.
|
||||
|
||||
=back
|
||||
|
||||
The C<-jv> and C<-jdump> commands are extension modules written in Lua.
|
||||
They are mainly used for debugging the JIT compiler itself. For a
|
||||
description of their options and output format, please read the comment
|
||||
block at the start of their source. They can be found in the C<lib>
|
||||
directory of the source distribution or installed under the C<jit>
|
||||
directory. By default this is C</usr/local/share/luajit-2.0.4/jit> on
|
||||
POSIX systems.
|
||||
|
||||
=head2 C<-O[level]>
|
||||
|
||||
C<-O[+]flag> C<-O-flag>
|
||||
|
||||
C<-Oparam=value>
|
||||
|
||||
This options allows fine-tuned control of the optimizations used by the
|
||||
JIT compiler. This is mainly intended for debugging LuaJIT itself.
|
||||
Please note that the JIT compiler is extremely fast (we are talking
|
||||
about the microsecond to millisecond range). Disabling optimizations
|
||||
doesn't have any visible impact on its overhead, but usually generates
|
||||
code that runs slower.
|
||||
|
||||
The first form sets an optimization level E<mdash> this enables a
|
||||
specific mix of optimization flags. C<-O0> turns off all optimizations
|
||||
and higher numbers enable more optimizations. Omitting the level (i.e.
|
||||
just C<-O>) sets the default optimization level, which is C<-O3> in the
|
||||
current version.
|
||||
|
||||
The second form adds or removes individual optimization flags. The
|
||||
third form sets a parameter for the VM or the JIT compiler to a
|
||||
specific value.
|
||||
|
||||
You can either use this option multiple times (like C<-Ocse -O-dce
|
||||
-Ohotloop=10>) or separate several settings with a comma (like
|
||||
C<-O+cse,-dce,hotloop=10>). The settings are applied from left to right
|
||||
and later settings override earlier ones. You can freely mix the three
|
||||
forms, but note that setting an optimization level overrides all
|
||||
earlier flags.
|
||||
|
||||
Here are the available flags and at what optimization levels they are
|
||||
enabled:
|
||||
|
||||
Flag
|
||||
|
||||
-O1
|
||||
|
||||
-O2
|
||||
|
||||
-O3
|
||||
|
||||
fold
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Constant Folding, Simplifications and Reassociation
|
||||
|
||||
cse
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Common-Subexpression Elimination
|
||||
|
||||
dce
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Dead-Code Elimination
|
||||
|
||||
narrow
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Narrowing of numbers to integers
|
||||
|
||||
loop
|
||||
|
||||
E<bull>
|
||||
|
||||
E<bull>
|
||||
|
||||
Loop Optimizations (code hoisting)
|
||||
|
||||
fwd
|
||||
|
||||
E<bull>
|
||||
|
||||
Load Forwarding (L2L) and Store Forwarding (S2L)
|
||||
|
||||
dse
|
||||
|
||||
E<bull>
|
||||
|
||||
Dead-Store Elimination
|
||||
|
||||
abc
|
||||
|
||||
E<bull>
|
||||
|
||||
Array Bounds Check Elimination
|
||||
|
||||
sink
|
||||
|
||||
E<bull>
|
||||
|
||||
Allocation/Store Sinking
|
||||
|
||||
fuse
|
||||
|
||||
E<bull>
|
||||
|
||||
Fusion of operands into instructions
|
||||
|
||||
Here are the parameters and their default settings:
|
||||
|
||||
Parameter
|
||||
|
||||
Default
|
||||
|
||||
maxtrace
|
||||
|
||||
1000
|
||||
|
||||
Max. number of traces in the cache
|
||||
|
||||
maxrecord
|
||||
|
||||
4000
|
||||
|
||||
Max. number of recorded IR instructions
|
||||
|
||||
maxirconst
|
||||
|
||||
500
|
||||
|
||||
Max. number of IR constants of a trace
|
||||
|
||||
maxside
|
||||
|
||||
100
|
||||
|
||||
Max. number of side traces of a root trace
|
||||
|
||||
maxsnap
|
||||
|
||||
500
|
||||
|
||||
Max. number of snapshots for a trace
|
||||
|
||||
hotloop
|
||||
|
||||
56
|
||||
|
||||
Number of iterations to detect a hot loop or hot call
|
||||
|
||||
hotexit
|
||||
|
||||
10
|
||||
|
||||
Number of taken exits to start a side trace
|
||||
|
||||
tryside
|
||||
|
||||
4
|
||||
|
||||
Number of attempts to compile a side trace
|
||||
|
||||
instunroll
|
||||
|
||||
4
|
||||
|
||||
Max. unroll factor for instable loops
|
||||
|
||||
loopunroll
|
||||
|
||||
15
|
||||
|
||||
Max. unroll factor for loop ops in side traces
|
||||
|
||||
callunroll
|
||||
|
||||
3
|
||||
|
||||
Max. unroll factor for pseudo-recursive calls
|
||||
|
||||
recunroll
|
||||
|
||||
2
|
||||
|
||||
Min. unroll factor for true recursion
|
||||
|
||||
sizemcode
|
||||
|
||||
32
|
||||
|
||||
Size of each machine code area in KBytes (Windows: 64K)
|
||||
|
||||
maxmcode
|
||||
|
||||
512
|
||||
|
||||
Max. total size of all machine code areas in KBytes
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file running.html
|
||||
# 13720 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
103
doc/LuaJIT-2.1/status.pod
Normal file
103
doc/LuaJIT-2.1/status.pod
Normal file
@ -0,0 +1,103 @@
|
||||
=pod
|
||||
|
||||
LuaJIT
|
||||
|
||||
=head1 Status
|
||||
|
||||
=over
|
||||
|
||||
=item * LuaJIT
|
||||
|
||||
=over
|
||||
|
||||
=item * Download E<rchevron>
|
||||
|
||||
=item * Installation
|
||||
|
||||
=item * Running
|
||||
|
||||
=back
|
||||
|
||||
=item * Extensions
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Library
|
||||
|
||||
=over
|
||||
|
||||
=item * FFI Tutorial
|
||||
|
||||
=item * ffi.* API
|
||||
|
||||
=item * FFI Semantics
|
||||
|
||||
=back
|
||||
|
||||
=item * jit.* Library
|
||||
|
||||
=item * Lua/C API
|
||||
|
||||
=item * Profiler
|
||||
|
||||
=back
|
||||
|
||||
=item * Status
|
||||
|
||||
=over
|
||||
|
||||
=item * Changes
|
||||
|
||||
=back
|
||||
|
||||
=item * FAQ
|
||||
|
||||
=item * Performance E<rchevron>
|
||||
|
||||
=item * Wiki E<rchevron>
|
||||
|
||||
=item * Mailing List E<rchevron>
|
||||
|
||||
=back
|
||||
|
||||
LuaJIT 2.0 is the current stable branch. This branch is in
|
||||
feature-freeze E<mdash> new features will only be added to LuaJIT 2.1.
|
||||
|
||||
=head2 Current Status
|
||||
|
||||
LuaJIT ought to run all Lua 5.1-compatible source code just fine. It's
|
||||
considered a serious bug if the VM crashes or produces unexpected
|
||||
results E<mdash> please report this.
|
||||
|
||||
Known incompatibilities and issues in LuaJIT 2.0:
|
||||
|
||||
=over
|
||||
|
||||
=item * There are some differences in B<implementation-defined>
|
||||
behavior. These either have a good reason, are arbitrary design choices
|
||||
or are due to quirks in the VM. The latter cases may get fixed if a
|
||||
demonstrable need is shown.
|
||||
|
||||
=item * The Lua B<debug API> is missing a couple of features (return
|
||||
hooks for non-Lua functions) and shows slightly different behavior in
|
||||
LuaJIT (no per-coroutine hooks, no tail call counting).
|
||||
|
||||
=item * Currently some B<out-of-memory> errors from B<on-trace code>
|
||||
are not handled correctly. The error may fall through an on-trace
|
||||
C<pcall> or it may be passed on to the function set with C<lua_atpanic>
|
||||
on x64. This issue will be fixed with the new garbage collector.
|
||||
|
||||
=back
|
||||
|
||||
----
|
||||
|
||||
Copyright E<copy> 2005-2016 Mike Pall E<middot> Contact
|
||||
|
||||
=cut
|
||||
|
||||
#Pod::HTML2Pod conversion notes:
|
||||
#From file status.html
|
||||
# 3334 bytes of input
|
||||
#Wed Jun 29 13:18:15 2016 agentzh
|
||||
# No a_name switch not specified, so will not try to render <a name='...'>
|
||||
# No a_href switch not specified, so will not try to render <a href='...'>
|
@ -124,25 +124,58 @@ MinGW gcc 4.8.1, MSYS perl, MSYS bash, MSYS make, and etc. Basically, it is curr
|
||||
the following cmmands:
|
||||
|
||||
```bash
|
||||
PCRE=pcre-8.39
|
||||
ZLIB=zlib-1.2.8
|
||||
OPENSSL=openssl-1.0.2h
|
||||
|
||||
mkdir -p objs/lib || exit 1
|
||||
cd objs/lib || exit 1
|
||||
ls ../../..
|
||||
tar -xf ../../../openssl-1.0.2d.tar.gz
|
||||
tar -xf ../../../zlib-1.2.8.tar.gz
|
||||
tar -xf ../../../pcre-8.37.tar.gz
|
||||
tar -xf ../../../$OPENSSL.tar.gz || exit 1
|
||||
tar -xf ../../../$ZLIB.tar.gz || exit 1
|
||||
tar -xf ../../../$PCRE.tar.gz || exit 1
|
||||
cd ../..
|
||||
./configure --with-cc=gcc \
|
||||
|
||||
cd objs/lib/$OPENSSL || exit 1
|
||||
patch -p1 < ../../../patches/$OPENSSL-sess_set_get_cb_yield.patch || exit 1
|
||||
cd ../../..
|
||||
|
||||
./configure \
|
||||
--with-cc=gcc \
|
||||
--with-ipv6 \
|
||||
--prefix= \
|
||||
--with-cc-opt='-DFD_SETSIZE=1024' \
|
||||
--with-select_module \
|
||||
--with-ipv6 \
|
||||
--sbin-path=nginx.exe \
|
||||
--with-pcre-jit \
|
||||
--without-http_rds_json_module \
|
||||
--without-http_rds_csv_module \
|
||||
--without-lua_rds_parser \
|
||||
--with-ipv6 \
|
||||
--with-stream \
|
||||
--with-stream_ssl_module \
|
||||
--with-http_v2_module \
|
||||
--without-mail_pop3_module \
|
||||
--without-mail_imap_module \
|
||||
--without-mail_smtp_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_realip_module \
|
||||
--with-http_addition_module \
|
||||
--with-http_auth_request_module \
|
||||
--with-http_secure_link_module \
|
||||
--with-http_random_index_module \
|
||||
--with-http_gzip_static_module \
|
||||
--with-http_sub_module \
|
||||
--with-http_dav_module \
|
||||
--with-http_flv_module \
|
||||
--with-http_mp4_module \
|
||||
--with-http_gunzip_module \
|
||||
--with-select_module \
|
||||
--with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
|
||||
--with-pcre=objs/lib/pcre-8.37 \
|
||||
--with-zlib=objs/lib/zlib-1.2.8 \
|
||||
--with-openssl=objs/lib/openssl-1.0.2d \
|
||||
-j5
|
||||
--with-pcre=objs/lib/$PCRE \
|
||||
--with-zlib=objs/lib/$ZLIB \
|
||||
--with-openssl=objs/lib/$OPENSSL \
|
||||
-j5 || exit 1
|
||||
|
||||
make
|
||||
make install
|
||||
```
|
||||
@ -150,10 +183,10 @@ make install
|
||||
where the dependency library source tarballs for OpenSSL, Zlib, and PCRE are downloaded
|
||||
from their official sites, respectively.
|
||||
|
||||
We automate these commands in a dedicated shell script named [build-win32.sh](https://github.com/openresty/ngx_openresty/blob/master/util/build-win32.sh).
|
||||
We automate these commands in a dedicated shell script named [build-win32.sh](https://github.com/openresty/openresty/blob/master/util/build-win32.sh).
|
||||
|
||||
Furthermore, we automate the packaging process of the resulting binaries and supporting files
|
||||
with this [package-win32.sh](https://github.com/openresty/ngx_openresty/blob/master/util/package-win32.sh)
|
||||
with this [package-win32.sh](https://github.com/openresty/openresty/blob/master/util/package-win32.sh)
|
||||
script.
|
||||
|
||||
Usually you can just download and use the binary distribution of OpenResty without
|
||||
@ -169,7 +202,7 @@ Copyright & License
|
||||
|
||||
This module is licensed under the BSD license.
|
||||
|
||||
Copyright (C) 2015, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
|
||||
Copyright (C) 2015-2016, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, CloudFlare Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
5878
doc/lua-5.1.5/README.pod
Normal file
5878
doc/lua-5.1.5/README.pod
Normal file
File diff suppressed because it is too large
Load Diff
21
html/50x.html
Normal file
21
html/50x.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<style>
|
||||
body {
|
||||
width: 35em;
|
||||
margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>An error occurred.</h1>
|
||||
<p>Sorry, the page you are looking for is currently unavailable.<br/>
|
||||
Please try again later.</p>
|
||||
<p>If you are the system administrator of this resource then you should check
|
||||
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
|
||||
<p><em>Faithfully yours, OpenResty.</em></p>
|
||||
</body>
|
||||
</html>
|
23
html/index.html
Normal file
23
html/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to OpenResty!</title>
|
||||
<style>
|
||||
body {
|
||||
width: 35em;
|
||||
margin: 0 auto;
|
||||
font-family: Tahoma, Verdana, Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to OpenResty!</h1>
|
||||
<p>If you see this page, the OpenResty web platform is successfully installed and
|
||||
working. Further configuration is required.</p>
|
||||
|
||||
<p>For online documentation and support please refer to
|
||||
<a href="https://openresty.org/">openresty.org</a>.<br/>
|
||||
|
||||
<p><em>Thank you for flying OpenResty.</em></p>
|
||||
</body>
|
||||
</html>
|
11
patches/nginx-1.11.2-always_enable_cc_feature_tests.patch
Normal file
11
patches/nginx-1.11.2-always_enable_cc_feature_tests.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.11.2/auto/cc/conf 2015-10-30 22:47:50.000000000 +0800
|
||||
+++ nginx-1.11.2-patched/auto/cc/conf 2015-11-02 12:23:05.385156987 +0800
|
||||
@@ -136,7 +136,7 @@ fi
|
||||
CFLAGS="$CFLAGS $NGX_CC_OPT"
|
||||
NGX_TEST_LD_OPT="$NGX_LD_OPT"
|
||||
|
||||
-if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
+if [ 1 ]; then
|
||||
|
||||
if test -n "$NGX_LD_OPT"; then
|
||||
ngx_feature=--with-ld-opt=\"$NGX_LD_OPT\"
|
19
patches/nginx-1.11.2-cache_manager_exit.patch
Normal file
19
patches/nginx-1.11.2-cache_manager_exit.patch
Normal file
@ -0,0 +1,19 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1383598130 28800
|
||||
# Node ID f64218e1ac963337d84092536f588b8e0d99bbaa
|
||||
# Parent dea321e5c0216efccbb23e84bbce7cf3e28f130c
|
||||
Cache: gracefully exit the cache manager process.
|
||||
|
||||
diff -r dea321e5c021 -r f64218e1ac96 src/os/unix/ngx_process_cycle.c
|
||||
--- a/src/os/unix/ngx_process_cycle.c Thu Oct 31 18:23:49 2013 +0400
|
||||
+++ b/src/os/unix/ngx_process_cycle.c Mon Nov 04 12:48:50 2013 -0800
|
||||
@@ -1335,7 +1335,7 @@
|
||||
|
||||
if (ngx_terminate || ngx_quit) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
- exit(0);
|
||||
+ ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_reopen) {
|
1159
patches/nginx-1.11.2-dtrace.patch
Normal file
1159
patches/nginx-1.11.2-dtrace.patch
Normal file
File diff suppressed because it is too large
Load Diff
11
patches/nginx-1.11.2-gcc-maybe-uninitialized-warning.patch
Normal file
11
patches/nginx-1.11.2-gcc-maybe-uninitialized-warning.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.11.2/src/http/ngx_http_request.c 2013-05-06 03:26:50.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/http/ngx_http_request.c 2013-06-11 12:59:48.008321688 -0700
|
||||
@@ -1951,7 +1951,7 @@
|
||||
ngx_int_t rc;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
- ngx_http_core_srv_conf_t *cscf;
|
||||
+ ngx_http_core_srv_conf_t *cscf = NULL;
|
||||
|
||||
hc = r->http_connection;
|
||||
|
20
patches/nginx-1.11.2-hash_overflow.patch
Normal file
20
patches/nginx-1.11.2-hash_overflow.patch
Normal file
@ -0,0 +1,20 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1412276417 25200
|
||||
# Thu Oct 02 12:00:17 2014 -0700
|
||||
# Node ID 4032b992f23b054c1a2cfb0be879330d2c6708e5
|
||||
# Parent 1ff0f68d9376e3d184d65814a6372856bf65cfcd
|
||||
Hash: buffer overflow might happen when exceeding the pre-configured limits.
|
||||
|
||||
diff -r 1ff0f68d9376 -r 4032b992f23b src/core/ngx_hash.c
|
||||
--- a/src/core/ngx_hash.c Tue Sep 30 15:50:28 2014 -0700
|
||||
+++ b/src/core/ngx_hash.c Thu Oct 02 12:00:17 2014 -0700
|
||||
@@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng
|
||||
continue;
|
||||
}
|
||||
|
||||
+ size--;
|
||||
+
|
||||
ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
|
||||
"could not build optimal %s, you should increase "
|
||||
"either %s_max_size: %i or %s_bucket_size: %i; "
|
13
patches/nginx-1.11.2-larger_max_error_str.patch
Normal file
13
patches/nginx-1.11.2-larger_max_error_str.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- nginx-1.11.2/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800
|
||||
@@ -64,7 +64,9 @@ struct ngx_log_s {
|
||||
};
|
||||
|
||||
|
||||
-#define NGX_MAX_ERROR_STR 2048
|
||||
+#ifndef NGX_MAX_ERROR_STR
|
||||
+#define NGX_MAX_ERROR_STR 4096
|
||||
+#endif
|
||||
|
||||
|
||||
/*********************************/
|
115
patches/nginx-1.11.2-log_escape_non_ascii.patch
Normal file
115
patches/nginx-1.11.2-log_escape_non_ascii.patch
Normal file
@ -0,0 +1,115 @@
|
||||
--- nginx-1.11.2/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.11.2-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
36
patches/nginx-1.11.2-no_Werror.patch
Normal file
36
patches/nginx-1.11.2-no_Werror.patch
Normal file
@ -0,0 +1,36 @@
|
||||
diff -urp nginx-1.11.2/auto/cc/clang nginx-1.11.2-patched/auto/cc/clang
|
||||
--- nginx-1.11.2/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.11.2-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700
|
||||
@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter"
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.11.2/auto/cc/gcc nginx-1.11.2-patched/auto/cc/gcc
|
||||
--- nginx-1.11.2/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.11.2-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -168,7 +168,7 @@ esac
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.11.2/auto/cc/icc nginx-1.11.2-patched/auto/cc/icc
|
||||
--- nginx-1.11.2/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.11.2-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
90
patches/nginx-1.11.2-no_error_pages.patch
Normal file
90
patches/nginx-1.11.2-no_error_pages.patch
Normal file
@ -0,0 +1,90 @@
|
||||
--- nginx-1.11.2/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.11.2-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
587
patches/nginx-1.11.2-no_pool.patch
Normal file
587
patches/nginx-1.11.2-no_pool.patch
Normal file
@ -0,0 +1,587 @@
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.11.2/src/core/nginx.h nginx-1.11.2-patched/src/core/nginx.h
|
||||
--- nginx-1.11.2/src/core/nginx.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/nginx.h 2016-04-21 16:25:07.452944624 -0700
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1011002
|
||||
#define NGINX_VERSION "1.11.2"
|
||||
-#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.11.2/src/core/ngx_array.c nginx-1.11.2-patched/src/core/ngx_array.c
|
||||
--- nginx-1.11.2/src/core/ngx_array.c 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/ngx_array.c 2016-04-21 16:25:07.453947190 -0700
|
||||
@@ -30,26 +30,30 @@ ngx_array_create(ngx_pool_t *p, ngx_uint
|
||||
void
|
||||
ngx_array_destroy(ngx_array_t *a)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
+ if (a->elts) {
|
||||
+ ngx_pfree(p, a->elts);
|
||||
}
|
||||
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
+ for (link = a->old_elts; link; link = link->next) {
|
||||
+ ngx_pfree(p, link->elts);
|
||||
}
|
||||
+
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_array_push(ngx_array_t *a)
|
||||
{
|
||||
- void *elt, *new;
|
||||
- size_t size;
|
||||
- ngx_pool_t *p;
|
||||
+ void *elt, *new;
|
||||
+ size_t size;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts == a->nalloc) {
|
||||
|
||||
@@ -59,29 +63,27 @@ ngx_array_push(ngx_array_t *a)
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
+ /* allocate a new array */
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
+
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -95,11 +97,10 @@ void *
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
@@ -107,31 +108,27 @@ ngx_array_push_n(ngx_array_t *a, ngx_uin
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
- }
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.11.2/src/core/ngx_array.h nginx-1.11.2-patched/src/core/ngx_array.h
|
||||
--- nginx-1.11.2/src/core/ngx_array.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/ngx_array.h 2016-04-21 16:25:07.453947190 -0700
|
||||
@@ -13,12 +13,23 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
+typedef struct ngx_array_link_s ngx_array_link_t;
|
||||
+
|
||||
+
|
||||
+struct ngx_array_link_s {
|
||||
+ void *elts;
|
||||
+ ngx_array_link_t *next;
|
||||
+};
|
||||
+
|
||||
+
|
||||
typedef struct {
|
||||
void *elts;
|
||||
ngx_uint_t nelts;
|
||||
size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *pool;
|
||||
+
|
||||
+ ngx_array_link_t *old_elts;
|
||||
} ngx_array_t;
|
||||
|
||||
|
||||
@@ -40,6 +51,7 @@ ngx_array_init(ngx_array_t *array, ngx_p
|
||||
array->size = size;
|
||||
array->nalloc = n;
|
||||
array->pool = pool;
|
||||
+ array->old_elts = NULL;
|
||||
|
||||
array->elts = ngx_palloc(pool, n * size);
|
||||
if (array->elts == NULL) {
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.11.2/src/core/ngx_palloc.c nginx-1.11.2-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.11.2/src/core/ngx_palloc.c 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/ngx_palloc.c 2016-04-21 16:25:45.912282685 -0700
|
||||
@@ -9,34 +9,26 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
|
||||
- ngx_uint_t align);
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
+static void * ngx_malloc(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ ngx_memzero(p, size);
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
|
||||
p->current = p;
|
||||
- p->chain = NULL;
|
||||
- p->large = NULL;
|
||||
- p->cleanup = NULL;
|
||||
p->log = log;
|
||||
|
||||
return p;
|
||||
@@ -46,8 +38,7 @@ ngx_create_pool(size_t size, ngx_log_t *
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
for (c = pool->cleanup; c; c = c->next) {
|
||||
@@ -58,6 +49,11 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (pool->d == NULL) {
|
||||
+ ngx_free(pool);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
#if (NGX_DEBUG)
|
||||
|
||||
/*
|
||||
@@ -65,13 +61,9 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
* so we cannot use this log while free()ing the pool
|
||||
*/
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
- }
|
||||
-
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p, unused: %d", d, 0);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
@@ -80,171 +72,82 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
|
||||
#endif
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ pool->d = NULL;
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
+ ngx_pool_data_t *saved = NULL;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
+ if (pool->d) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc == pool->log) {
|
||||
+ saved = d;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
+
|
||||
+ if (n == NULL) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.failed = 0;
|
||||
+ pool->d = saved;
|
||||
+ pool->current = pool;
|
||||
+ pool->chain = NULL;
|
||||
}
|
||||
-
|
||||
- pool->current = pool;
|
||||
- pool->chain = NULL;
|
||||
- pool->large = NULL;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
-#if !(NGX_DEBUG_PALLOC)
|
||||
- if (size <= pool->max) {
|
||||
- return ngx_palloc_small(pool, size, 1);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
-#if !(NGX_DEBUG_PALLOC)
|
||||
- if (size <= pool->max) {
|
||||
- return ngx_palloc_small(pool, size, 0);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static ngx_inline void *
|
||||
-ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
|
||||
-{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if (align) {
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- }
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
-{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- for (p = pool->current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- pool->current = p->d.next;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- p->d.next = new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
-ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- void *p;
|
||||
- ngx_uint_t n;
|
||||
- ngx_pool_large_t *large;
|
||||
+ void *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -253,38 +156,48 @@ void *
|
||||
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
|
||||
{
|
||||
void *p;
|
||||
- ngx_pool_large_t *large;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_memalign(alignment, size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
-ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
+ngx_pfree(ngx_pool_t *pool, void *data)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *d;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (p == l->alloc) {
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p", l->alloc);
|
||||
- ngx_free(l->alloc);
|
||||
- l->alloc = NULL;
|
||||
+ p = NULL;
|
||||
+ for (d = pool->d; d; p = d, d = d->next) {
|
||||
+ if (data == d->alloc) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ d->alloc = NULL;
|
||||
+
|
||||
+ if (p) {
|
||||
+ p->next = d->next;
|
||||
+
|
||||
+ } else {
|
||||
+ pool->d = d->next;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.11.2/src/core/ngx_palloc.h nginx-1.11.2-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.11.2/src/core/ngx_palloc.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/core/ngx_palloc.h 2016-04-21 16:25:07.454949755 -0700
|
||||
@@ -38,28 +38,21 @@ struct ngx_pool_cleanup_s {
|
||||
};
|
||||
|
||||
|
||||
-typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
-
|
||||
-struct ngx_pool_large_s {
|
||||
- ngx_pool_large_t *next;
|
||||
- void *alloc;
|
||||
-};
|
||||
+typedef struct ngx_pool_data_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s {
|
||||
+ ngx_pool_data_t *next;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
||||
- ngx_pool_large_t *large;
|
||||
ngx_pool_cleanup_t *cleanup;
|
||||
ngx_log_t *log;
|
||||
};
|
26
patches/nginx-1.11.2-pcre_conf_opt.patch
Normal file
26
patches/nginx-1.11.2-pcre_conf_opt.patch
Normal file
@ -0,0 +1,26 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1386694955 28800
|
||||
# Node ID 9ba6b149669f1f02eeb4cdc0ebd364a949b5c469
|
||||
# Parent 30e806b8636af5fd3f03ec17df24801f390f7511
|
||||
Configure: added new option --with-pcre-conf-opt=OPTIONS.
|
||||
|
||||
diff -r 30e806b8636a -r 9ba6b149669f auto/options
|
||||
--- a/auto/options Mon Dec 09 10:16:44 2013 +0400
|
||||
+++ b/auto/options Tue Dec 10 09:02:35 2013 -0800
|
||||
@@ -286,6 +286,7 @@
|
||||
--with-pcre) USE_PCRE=YES ;;
|
||||
--with-pcre=*) PCRE="$value" ;;
|
||||
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
||||
+ --with-pcre-conf-opt=*) PCRE_CONF_OPT="$value" ;;
|
||||
--with-pcre-jit) PCRE_JIT=YES ;;
|
||||
|
||||
--with-openssl=*) OPENSSL="$value" ;;
|
||||
@@ -441,6 +442,7 @@
|
||||
--with-pcre force PCRE library usage
|
||||
--with-pcre=DIR set path to PCRE library sources
|
||||
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
||||
+ --with-pcre-conf-opt=OPTIONS set additional configure options for PCRE
|
||||
--with-pcre-jit build PCRE with JIT compilation support
|
||||
|
||||
--with-md5=DIR set path to md5 library sources
|
15
patches/nginx-1.11.2-proxy_host_port_vars.patch
Normal file
15
patches/nginx-1.11.2-proxy_host_port_vars.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- nginx-1.11.2/src/http/modules/ngx_http_proxy_module.c 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.11.2-patched/src/http/modules/ngx_http_proxy_module.c 2013-10-27 15:29:41.619378592 -0700
|
||||
@@ -602,10 +602,10 @@ static ngx_keyval_t ngx_http_proxy_cach
|
||||
static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||
|
||||
{ ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_add_x_forwarded_for"), NULL,
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
24
patches/nginx-1.11.2-server_header.patch
Normal file
24
patches/nginx-1.11.2-server_header.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -ur nginx-1.11.2/src/core/nginx.h nginx-1.11.2-patched/src/core/nginx.h
|
||||
--- nginx-1.11.2/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ nginx-1.11.2-patched/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1011002
|
||||
#define NGINX_VERSION "1.11.2"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
diff -ur nginx-1.11.2/src/http/ngx_http_header_filter_module.c nginx-1.11.2-patched/src/http/ngx_http_header_filter_module.c
|
||||
--- nginx-1.11.2/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ nginx-1.11.2-patched/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
44
patches/nginx-1.11.2-setting_args_invalidates_uri.patch
Normal file
44
patches/nginx-1.11.2-setting_args_invalidates_uri.patch
Normal file
@ -0,0 +1,44 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1390506359 28800
|
||||
# Node ID 17186b98c235c07e94c64e5853689f790f173756
|
||||
# Parent 4b50d1f299d8a69f3e3f7975132e1490352642fe
|
||||
Variable: setting $args should invalidate unparsed uri.
|
||||
|
||||
diff -r 4b50d1f299d8 -r 17186b98c235 src/http/ngx_http_variables.c
|
||||
--- a/src/http/ngx_http_variables.c Fri Jan 10 11:22:14 2014 -0800
|
||||
+++ b/src/http/ngx_http_variables.c Thu Jan 23 11:45:59 2014 -0800
|
||||
@@ -15,6 +15,8 @@
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
+static void ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
|
||||
@@ -218,7 +220,7 @@
|
||||
NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("args"),
|
||||
- ngx_http_variable_request_set,
|
||||
+ ngx_http_variable_request_args_set,
|
||||
ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, args),
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
@@ -647,6 +649,15 @@
|
||||
|
||||
|
||||
static void
|
||||
+ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data)
|
||||
+{
|
||||
+ r->valid_unparsed_uri = 0;
|
||||
+ ngx_http_variable_request_set(r, v, data);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
138
patches/nginx-1.11.2-slab_defrag.patch
Normal file
138
patches/nginx-1.11.2-slab_defrag.patch
Normal file
@ -0,0 +1,138 @@
|
||||
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
|
||||
index c3a27f7..1bde432 100644
|
||||
--- a/src/core/ngx_slab.c
|
||||
+++ b/src/core/ngx_slab.c
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
+#include <assert.h>
|
||||
|
||||
|
||||
#define NGX_SLAB_PAGE_MASK 3
|
||||
@@ -111,6 +112,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
|
||||
|
||||
pool->pages = (ngx_slab_page_t *) p;
|
||||
+ pool->npages = pages;
|
||||
|
||||
pool->free.prev = 0;
|
||||
pool->free.next = (ngx_slab_page_t *) p;
|
||||
@@ -118,6 +120,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
pool->pages->slab = pages;
|
||||
pool->pages->next = &pool->free;
|
||||
pool->pages->prev = (uintptr_t) &pool->free;
|
||||
+ pool->pages->prev_slab = 0;
|
||||
|
||||
pool->start = (u_char *)
|
||||
ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
|
||||
@@ -625,9 +628,16 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
if (page->slab >= pages) {
|
||||
|
||||
if (page->slab > pages) {
|
||||
+ /* adjust the next adjacent block's "prev_slab" field */
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages) {
|
||||
+ p->prev_slab = page->slab - pages;
|
||||
+ }
|
||||
+
|
||||
page[pages].slab = page->slab - pages;
|
||||
page[pages].next = page->next;
|
||||
page[pages].prev = page->prev;
|
||||
+ page[pages].prev_slab = pages;
|
||||
|
||||
p = (ngx_slab_page_t *) page->prev;
|
||||
p->next = &page[pages];
|
||||
@@ -651,6 +661,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
p->slab = NGX_SLAB_PAGE_BUSY;
|
||||
p->next = NULL;
|
||||
p->prev = NGX_SLAB_PAGE;
|
||||
+ p->prev_slab = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
@@ -668,7 +679,7 @@ static void
|
||||
ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
ngx_uint_t pages)
|
||||
{
|
||||
- ngx_slab_page_t *prev;
|
||||
+ ngx_slab_page_t *prev, *p;
|
||||
|
||||
page->slab = pages--;
|
||||
|
||||
@@ -682,6 +693,53 @@ ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
page->next->prev = page->prev;
|
||||
}
|
||||
|
||||
+ /* merge the next adjacent free block if it is free */
|
||||
+
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages
|
||||
+ && !(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ page->slab += p->slab;
|
||||
+
|
||||
+ /* remove the next adjacent block from the free list */
|
||||
+
|
||||
+ prev = (ngx_slab_page_t *) p->prev;
|
||||
+ prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = page->slab;
|
||||
+ }
|
||||
+
|
||||
+ ngx_memzero(p, sizeof(ngx_slab_page_t));
|
||||
+ }
|
||||
+
|
||||
+ if (page->prev_slab) {
|
||||
+ /* merge the previous adjacent block if it is free */
|
||||
+
|
||||
+ p = page - page->prev_slab;
|
||||
+ if (!(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ assert(p->slab == page->prev_slab);
|
||||
+
|
||||
+ p->slab += page->slab;
|
||||
+ ngx_memzero(page, sizeof(ngx_slab_page_t));
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = p->slab;
|
||||
+ }
|
||||
+
|
||||
+ /* skip adding "page" to the free list */
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
page->prev = (uintptr_t) &pool->free;
|
||||
page->next = pool->free.next;
|
||||
|
||||
diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h
|
||||
index c5e420b..287ac79 100644
|
||||
--- a/src/core/ngx_slab.h
|
||||
+++ b/src/core/ngx_slab.h
|
||||
@@ -19,6 +19,8 @@ struct ngx_slab_page_s {
|
||||
uintptr_t slab;
|
||||
ngx_slab_page_t *next;
|
||||
uintptr_t prev;
|
||||
+ uintptr_t prev_slab;
|
||||
+ /* number of pages for the previous adjacent block */
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +33,8 @@ typedef struct {
|
||||
ngx_slab_page_t *pages;
|
||||
ngx_slab_page_t free;
|
||||
|
||||
+ ngx_uint_t npages;
|
||||
+
|
||||
u_char *start;
|
||||
u_char *end;
|
||||
|
42
patches/nginx-1.11.2-ssl_cert_cb_yield.patch
Normal file
42
patches/nginx-1.11.2-ssl_cert_cb_yield.patch
Normal file
@ -0,0 +1,42 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@openresty.org>
|
||||
# Date 1451762084 28800
|
||||
# Sat Jan 02 11:14:44 2016 -0800
|
||||
# Node ID 449f0461859c16e95bdb18e8be6b94401545d3dd
|
||||
# Parent 78b4e10b4367b31367aad3c83c9c3acdd42397c4
|
||||
SSL: handled SSL_CTX_set_cert_cb() callback yielding.
|
||||
|
||||
OpenSSL 1.0.2+ introduces SSL_CTX_set_cert_cb() to allow custom
|
||||
callbacks to serve the SSL certificiates and private keys dynamically
|
||||
and lazily. The callbacks may yield for nonblocking I/O or sleeping.
|
||||
Here we added support for such usage in NGINX 3rd-party modules
|
||||
(like ngx_lua) in NGINX's event handlers for downstream SSL
|
||||
connections.
|
||||
|
||||
diff -r 78b4e10b4367 -r 449f0461859c src/event/ngx_event_openssl.c
|
||||
--- a/src/event/ngx_event_openssl.c Thu Dec 17 16:39:15 2015 +0300
|
||||
+++ b/src/event/ngx_event_openssl.c Sat Jan 02 11:14:44 2016 -0800
|
||||
@@ -1210,6 +1210,23 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
+ c->read->handler = ngx_ssl_handshake_handler;
|
||||
+ c->write->handler = ngx_ssl_handshake_handler;
|
||||
+
|
||||
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return NGX_AGAIN;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
c->ssl->no_wait_shutdown = 1;
|
16
patches/nginx-1.11.2-ssl_pending_session.patch
Normal file
16
patches/nginx-1.11.2-ssl_pending_session.patch
Normal file
@ -0,0 +1,16 @@
|
||||
--- nginx-1.11.2/src/event/ngx_event_openssl.c 2016-07-17 19:20:30.411137606 -0700
|
||||
+++ nginx-1.11.2-patched/src/event/ngx_event_openssl.c 2016-07-19 16:53:35.539768477 -0700
|
||||
@@ -1307,7 +1307,12 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
- if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP
|
||||
+# ifdef SSL_ERROR_PENDING_SESSION
|
||||
+ || sslerr == SSL_ERROR_PENDING_SESSION
|
||||
+# endif
|
||||
+ )
|
||||
+ {
|
||||
c->read->handler = ngx_ssl_handshake_handler;
|
||||
c->write->handler = ngx_ssl_handshake_handler;
|
||||
|
23
patches/nginx-1.11.2-upstream_pipelining.patch
Normal file
23
patches/nginx-1.11.2-upstream_pipelining.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit f9907b72a76a21ac5413187b83177a919475c75f
|
||||
Author: Yichun Zhang (agentzh) <agentzh@gmail.com>
|
||||
Date: Wed Feb 10 16:05:08 2016 -0800
|
||||
|
||||
bugfix: upstream: keep sending request data after the first write attempt.
|
||||
|
||||
See
|
||||
http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html
|
||||
for more details on the issue.
|
||||
|
||||
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
|
||||
index dbaa956..a25aaa2 100644
|
||||
--- a/src/http/ngx_http_upstream.c
|
||||
+++ b/src/http/ngx_http_upstream.c
|
||||
@@ -2003,7 +2003,7 @@ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
||||
|
||||
#endif
|
||||
|
||||
- if (u->header_sent) {
|
||||
+ if (u->request_body_sent) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(c->write, 0);
|
120
patches/nginx-1.11.2-upstream_timeout_fields.patch
Normal file
120
patches/nginx-1.11.2-upstream_timeout_fields.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff -r 13070ecfda67 src/http/ngx_http_upstream.c
|
||||
--- a/src/http/ngx_http_upstream.c Tue Apr 19 19:02:37 2016 +0300
|
||||
+++ b/src/http/ngx_http_upstream.c Fri Jul 01 12:14:53 2016 -0700
|
||||
@@ -481,12 +481,19 @@ void
|
||||
ngx_http_upstream_init(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
+ ngx_http_upstream_t *u;
|
||||
|
||||
c = r->connection;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http init upstream, client timer: %d", c->read->timer_set);
|
||||
|
||||
+ u = r->upstream;
|
||||
+
|
||||
+ u->connect_timeout = u->conf->connect_timeout;
|
||||
+ u->send_timeout = u->conf->send_timeout;
|
||||
+ u->read_timeout = u->conf->read_timeout;
|
||||
+
|
||||
#if (NGX_HTTP_V2)
|
||||
if (r->stream) {
|
||||
ngx_http_upstream_init_request(r);
|
||||
@@ -1451,7 +1458,7 @@ ngx_http_upstream_connect(ngx_http_reque
|
||||
u->request_body_sent = 0;
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
- ngx_add_timer(c->write, u->conf->connect_timeout);
|
||||
+ ngx_add_timer(c->write, u->connect_timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1540,7 +1547,7 @@ ngx_http_upstream_ssl_init_connection(ng
|
||||
if (rc == NGX_AGAIN) {
|
||||
|
||||
if (!c->write->timer_set) {
|
||||
- ngx_add_timer(c->write, u->conf->connect_timeout);
|
||||
+ ngx_add_timer(c->write, u->connect_timeout);
|
||||
}
|
||||
|
||||
c->ssl->handler = ngx_http_upstream_ssl_handshake;
|
||||
@@ -1816,7 +1823,7 @@ ngx_http_upstream_send_request(ngx_http_
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (!c->write->ready) {
|
||||
- ngx_add_timer(c->write, u->conf->send_timeout);
|
||||
+ ngx_add_timer(c->write, u->send_timeout);
|
||||
|
||||
} else if (c->write->timer_set) {
|
||||
ngx_del_timer(c->write);
|
||||
@@ -1859,7 +1866,7 @@ ngx_http_upstream_send_request(ngx_http_
|
||||
return;
|
||||
}
|
||||
|
||||
- ngx_add_timer(c->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(c->read, u->read_timeout);
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_http_upstream_process_header(r, u);
|
||||
@@ -2658,7 +2665,7 @@ ngx_http_upstream_process_body_in_memory
|
||||
}
|
||||
|
||||
if (rev->active) {
|
||||
- ngx_add_timer(rev, u->conf->read_timeout);
|
||||
+ ngx_add_timer(rev, u->read_timeout);
|
||||
|
||||
} else if (rev->timer_set) {
|
||||
ngx_del_timer(rev);
|
||||
@@ -2982,7 +2989,7 @@ ngx_http_upstream_send_response(ngx_http
|
||||
p->cyclic_temp_file = 0;
|
||||
}
|
||||
|
||||
- p->read_timeout = u->conf->read_timeout;
|
||||
+ p->read_timeout = u->read_timeout;
|
||||
p->send_timeout = clcf->send_timeout;
|
||||
p->send_lowat = clcf->send_lowat;
|
||||
|
||||
@@ -3239,7 +3246,7 @@ ngx_http_upstream_process_upgraded(ngx_h
|
||||
}
|
||||
|
||||
if (upstream->write->active && !upstream->write->ready) {
|
||||
- ngx_add_timer(upstream->write, u->conf->send_timeout);
|
||||
+ ngx_add_timer(upstream->write, u->send_timeout);
|
||||
|
||||
} else if (upstream->write->timer_set) {
|
||||
ngx_del_timer(upstream->write);
|
||||
@@ -3251,7 +3258,7 @@ ngx_http_upstream_process_upgraded(ngx_h
|
||||
}
|
||||
|
||||
if (upstream->read->active && !upstream->read->ready) {
|
||||
- ngx_add_timer(upstream->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(upstream->read, u->read_timeout);
|
||||
|
||||
} else if (upstream->read->timer_set) {
|
||||
ngx_del_timer(upstream->read);
|
||||
@@ -3444,7 +3451,7 @@ ngx_http_upstream_process_non_buffered_r
|
||||
}
|
||||
|
||||
if (upstream->read->active && !upstream->read->ready) {
|
||||
- ngx_add_timer(upstream->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(upstream->read, u->read_timeout);
|
||||
|
||||
} else if (upstream->read->timer_set) {
|
||||
ngx_del_timer(upstream->read);
|
||||
diff -r 13070ecfda67 src/http/ngx_http_upstream.h
|
||||
--- a/src/http/ngx_http_upstream.h Tue Apr 19 19:02:37 2016 +0300
|
||||
+++ b/src/http/ngx_http_upstream.h Fri Jul 01 12:14:53 2016 -0700
|
||||
@@ -309,6 +309,12 @@ struct ngx_http_upstream_s {
|
||||
ngx_chain_writer_ctx_t writer;
|
||||
|
||||
ngx_http_upstream_conf_t *conf;
|
||||
+
|
||||
+#define HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS 1
|
||||
+ ngx_msec_t connect_timeout;
|
||||
+ ngx_msec_t send_timeout;
|
||||
+ ngx_msec_t read_timeout;
|
||||
+
|
||||
#if (NGX_HTTP_CACHE)
|
||||
ngx_array_t *caches;
|
||||
#endif
|
11
patches/nginx-1.9.11-always_enable_cc_feature_tests.patch
Normal file
11
patches/nginx-1.9.11-always_enable_cc_feature_tests.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.9.11/auto/cc/conf 2015-10-30 22:47:50.000000000 +0800
|
||||
+++ nginx-1.9.11-patched/auto/cc/conf 2015-11-02 12:23:05.385156987 +0800
|
||||
@@ -136,7 +136,7 @@ fi
|
||||
CFLAGS="$CFLAGS $NGX_CC_OPT"
|
||||
NGX_TEST_LD_OPT="$NGX_LD_OPT"
|
||||
|
||||
-if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
+if [ 1 ]; then
|
||||
|
||||
if test -n "$NGX_LD_OPT"; then
|
||||
ngx_feature=--with-ld-opt=\"$NGX_LD_OPT\"
|
19
patches/nginx-1.9.11-cache_manager_exit.patch
Normal file
19
patches/nginx-1.9.11-cache_manager_exit.patch
Normal file
@ -0,0 +1,19 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1383598130 28800
|
||||
# Node ID f64218e1ac963337d84092536f588b8e0d99bbaa
|
||||
# Parent dea321e5c0216efccbb23e84bbce7cf3e28f130c
|
||||
Cache: gracefully exit the cache manager process.
|
||||
|
||||
diff -r dea321e5c021 -r f64218e1ac96 src/os/unix/ngx_process_cycle.c
|
||||
--- a/src/os/unix/ngx_process_cycle.c Thu Oct 31 18:23:49 2013 +0400
|
||||
+++ b/src/os/unix/ngx_process_cycle.c Mon Nov 04 12:48:50 2013 -0800
|
||||
@@ -1335,7 +1335,7 @@
|
||||
|
||||
if (ngx_terminate || ngx_quit) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
- exit(0);
|
||||
+ ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_reopen) {
|
1159
patches/nginx-1.9.11-dtrace.patch
Normal file
1159
patches/nginx-1.9.11-dtrace.patch
Normal file
File diff suppressed because it is too large
Load Diff
11
patches/nginx-1.9.11-gcc-maybe-uninitialized-warning.patch
Normal file
11
patches/nginx-1.9.11-gcc-maybe-uninitialized-warning.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.9.11/src/http/ngx_http_request.c 2013-05-06 03:26:50.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/http/ngx_http_request.c 2013-06-11 12:59:48.008321688 -0700
|
||||
@@ -1951,7 +1951,7 @@
|
||||
ngx_int_t rc;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
- ngx_http_core_srv_conf_t *cscf;
|
||||
+ ngx_http_core_srv_conf_t *cscf = NULL;
|
||||
|
||||
hc = r->http_connection;
|
||||
|
20
patches/nginx-1.9.11-hash_overflow.patch
Normal file
20
patches/nginx-1.9.11-hash_overflow.patch
Normal file
@ -0,0 +1,20 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1412276417 25200
|
||||
# Thu Oct 02 12:00:17 2014 -0700
|
||||
# Node ID 4032b992f23b054c1a2cfb0be879330d2c6708e5
|
||||
# Parent 1ff0f68d9376e3d184d65814a6372856bf65cfcd
|
||||
Hash: buffer overflow might happen when exceeding the pre-configured limits.
|
||||
|
||||
diff -r 1ff0f68d9376 -r 4032b992f23b src/core/ngx_hash.c
|
||||
--- a/src/core/ngx_hash.c Tue Sep 30 15:50:28 2014 -0700
|
||||
+++ b/src/core/ngx_hash.c Thu Oct 02 12:00:17 2014 -0700
|
||||
@@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng
|
||||
continue;
|
||||
}
|
||||
|
||||
+ size--;
|
||||
+
|
||||
ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
|
||||
"could not build optimal %s, you should increase "
|
||||
"either %s_max_size: %i or %s_bucket_size: %i; "
|
13
patches/nginx-1.9.11-larger_max_error_str.patch
Normal file
13
patches/nginx-1.9.11-larger_max_error_str.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- nginx-1.9.11/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800
|
||||
@@ -64,7 +64,9 @@ struct ngx_log_s {
|
||||
};
|
||||
|
||||
|
||||
-#define NGX_MAX_ERROR_STR 2048
|
||||
+#ifndef NGX_MAX_ERROR_STR
|
||||
+#define NGX_MAX_ERROR_STR 4096
|
||||
+#endif
|
||||
|
||||
|
||||
/*********************************/
|
115
patches/nginx-1.9.11-log_escape_non_ascii.patch
Normal file
115
patches/nginx-1.9.11-log_escape_non_ascii.patch
Normal file
@ -0,0 +1,115 @@
|
||||
--- nginx-1.9.11/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.9.11-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
36
patches/nginx-1.9.11-no_Werror.patch
Normal file
36
patches/nginx-1.9.11-no_Werror.patch
Normal file
@ -0,0 +1,36 @@
|
||||
diff -urp nginx-1.9.11/auto/cc/clang nginx-1.9.11-patched/auto/cc/clang
|
||||
--- nginx-1.9.11/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.11-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700
|
||||
@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter"
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.9.11/auto/cc/gcc nginx-1.9.11-patched/auto/cc/gcc
|
||||
--- nginx-1.9.11/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.11-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -168,7 +168,7 @@ esac
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.9.11/auto/cc/icc nginx-1.9.11-patched/auto/cc/icc
|
||||
--- nginx-1.9.11/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.11-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
90
patches/nginx-1.9.11-no_error_pages.patch
Normal file
90
patches/nginx-1.9.11-no_error_pages.patch
Normal file
@ -0,0 +1,90 @@
|
||||
--- nginx-1.9.11/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.9.11-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
585
patches/nginx-1.9.11-no_pool.patch
Normal file
585
patches/nginx-1.9.11-no_pool.patch
Normal file
@ -0,0 +1,585 @@
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.11/src/core/nginx.h nginx-1.9.11-patched/src/core/nginx.h
|
||||
--- nginx-1.9.11/src/core/nginx.h 2014-07-08 06:22:39.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/nginx.h 2014-07-13 19:21:54.117099631 -0700
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1009011
|
||||
#define NGINX_VERSION "1.9.11"
|
||||
-#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.11/src/core/ngx_array.c nginx-1.9.11-patched/src/core/ngx_array.c
|
||||
--- nginx-1.9.11/src/core/ngx_array.c 2014-07-08 06:22:39.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/ngx_array.c 2014-07-13 19:21:54.117099631 -0700
|
||||
@@ -30,26 +30,30 @@ ngx_array_create(ngx_pool_t *p, ngx_uint
|
||||
void
|
||||
ngx_array_destroy(ngx_array_t *a)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
+ if (a->elts) {
|
||||
+ ngx_pfree(p, a->elts);
|
||||
}
|
||||
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
+ for (link = a->old_elts; link; link = link->next) {
|
||||
+ ngx_pfree(p, link->elts);
|
||||
}
|
||||
+
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_array_push(ngx_array_t *a)
|
||||
{
|
||||
- void *elt, *new;
|
||||
- size_t size;
|
||||
- ngx_pool_t *p;
|
||||
+ void *elt, *new;
|
||||
+ size_t size;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts == a->nalloc) {
|
||||
|
||||
@@ -59,29 +63,27 @@ ngx_array_push(ngx_array_t *a)
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
+ /* allocate a new array */
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
+
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -95,11 +97,10 @@ void *
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
@@ -107,31 +108,27 @@ ngx_array_push_n(ngx_array_t *a, ngx_uin
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
- }
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.11/src/core/ngx_array.h nginx-1.9.11-patched/src/core/ngx_array.h
|
||||
--- nginx-1.9.11/src/core/ngx_array.h 2014-07-08 06:22:39.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/ngx_array.h 2014-07-13 19:21:54.118099637 -0700
|
||||
@@ -13,12 +13,23 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
+typedef struct ngx_array_link_s ngx_array_link_t;
|
||||
+
|
||||
+
|
||||
+struct ngx_array_link_s {
|
||||
+ void *elts;
|
||||
+ ngx_array_link_t *next;
|
||||
+};
|
||||
+
|
||||
+
|
||||
typedef struct {
|
||||
void *elts;
|
||||
ngx_uint_t nelts;
|
||||
size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *pool;
|
||||
+
|
||||
+ ngx_array_link_t *old_elts;
|
||||
} ngx_array_t;
|
||||
|
||||
|
||||
@@ -40,6 +51,7 @@ ngx_array_init(ngx_array_t *array, ngx_p
|
||||
array->size = size;
|
||||
array->nalloc = n;
|
||||
array->pool = pool;
|
||||
+ array->old_elts = NULL;
|
||||
|
||||
array->elts = ngx_palloc(pool, n * size);
|
||||
if (array->elts == NULL) {
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.11/src/core/ngx_palloc.c nginx-1.9.11-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.9.11/src/core/ngx_palloc.c 2014-07-08 06:22:39.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/ngx_palloc.c 2014-07-13 20:04:41.786419098 -0700
|
||||
@@ -9,32 +9,26 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
+static void * ngx_malloc(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ ngx_memzero(p, size);
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
|
||||
p->current = p;
|
||||
- p->chain = NULL;
|
||||
- p->large = NULL;
|
||||
- p->cleanup = NULL;
|
||||
p->log = log;
|
||||
|
||||
return p;
|
||||
@@ -44,8 +38,7 @@ ngx_create_pool(size_t size, ngx_log_t *
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
for (c = pool->cleanup; c; c = c->next) {
|
||||
@@ -56,13 +49,9 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
}
|
||||
}
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
-
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
-
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
- }
|
||||
+ if (pool->d == NULL) {
|
||||
+ ngx_free(pool);
|
||||
+ return;
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
@@ -72,9 +61,9 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
* so we cannot use this log while free()ing the pool
|
||||
*/
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p, unused: %d", d, 0);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
@@ -83,170 +72,82 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
|
||||
#endif
|
||||
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ pool->d = NULL;
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
+ ngx_pool_data_t *saved = NULL;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
+ if (pool->d) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc == pool->log) {
|
||||
+ saved = d;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
+
|
||||
+ if (n == NULL) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.failed = 0;
|
||||
+ pool->d = saved;
|
||||
+ pool->current = pool;
|
||||
+ pool->chain = NULL;
|
||||
}
|
||||
-
|
||||
- pool->current = pool;
|
||||
- pool->chain = NULL;
|
||||
- pool->large = NULL;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
- }
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- if (size <= pool->max) {
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
- }
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
-{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- for (p = pool->current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- pool->current = p->d.next;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- p->d.next = new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
-ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- void *p;
|
||||
- ngx_uint_t n;
|
||||
- ngx_pool_large_t *large;
|
||||
+ void *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -255,38 +156,48 @@ void *
|
||||
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
|
||||
{
|
||||
void *p;
|
||||
- ngx_pool_large_t *large;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_memalign(alignment, size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
-ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
+ngx_pfree(ngx_pool_t *pool, void *data)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *d;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (p == l->alloc) {
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p", l->alloc);
|
||||
- ngx_free(l->alloc);
|
||||
- l->alloc = NULL;
|
||||
+ p = NULL;
|
||||
+ for (d = pool->d; d; p = d, d = d->next) {
|
||||
+ if (data == d->alloc) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ d->alloc = NULL;
|
||||
+
|
||||
+ if (p) {
|
||||
+ p->next = d->next;
|
||||
+
|
||||
+ } else {
|
||||
+ pool->d = d->next;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.11/src/core/ngx_palloc.h nginx-1.9.11-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.9.11/src/core/ngx_palloc.h 2014-07-08 06:22:39.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/core/ngx_palloc.h 2014-07-13 19:21:54.119099642 -0700
|
||||
@@ -38,28 +38,21 @@ struct ngx_pool_cleanup_s {
|
||||
};
|
||||
|
||||
|
||||
-typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
-
|
||||
-struct ngx_pool_large_s {
|
||||
- ngx_pool_large_t *next;
|
||||
- void *alloc;
|
||||
-};
|
||||
+typedef struct ngx_pool_data_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s {
|
||||
+ ngx_pool_data_t *next;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
||||
- ngx_pool_large_t *large;
|
||||
ngx_pool_cleanup_t *cleanup;
|
||||
ngx_log_t *log;
|
||||
};
|
26
patches/nginx-1.9.11-pcre_conf_opt.patch
Normal file
26
patches/nginx-1.9.11-pcre_conf_opt.patch
Normal file
@ -0,0 +1,26 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1386694955 28800
|
||||
# Node ID 9ba6b149669f1f02eeb4cdc0ebd364a949b5c469
|
||||
# Parent 30e806b8636af5fd3f03ec17df24801f390f7511
|
||||
Configure: added new option --with-pcre-conf-opt=OPTIONS.
|
||||
|
||||
diff -r 30e806b8636a -r 9ba6b149669f auto/options
|
||||
--- a/auto/options Mon Dec 09 10:16:44 2013 +0400
|
||||
+++ b/auto/options Tue Dec 10 09:02:35 2013 -0800
|
||||
@@ -286,6 +286,7 @@
|
||||
--with-pcre) USE_PCRE=YES ;;
|
||||
--with-pcre=*) PCRE="$value" ;;
|
||||
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
||||
+ --with-pcre-conf-opt=*) PCRE_CONF_OPT="$value" ;;
|
||||
--with-pcre-jit) PCRE_JIT=YES ;;
|
||||
|
||||
--with-openssl=*) OPENSSL="$value" ;;
|
||||
@@ -441,6 +442,7 @@
|
||||
--with-pcre force PCRE library usage
|
||||
--with-pcre=DIR set path to PCRE library sources
|
||||
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
||||
+ --with-pcre-conf-opt=OPTIONS set additional configure options for PCRE
|
||||
--with-pcre-jit build PCRE with JIT compilation support
|
||||
|
||||
--with-md5=DIR set path to md5 library sources
|
15
patches/nginx-1.9.11-proxy_host_port_vars.patch
Normal file
15
patches/nginx-1.9.11-proxy_host_port_vars.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- nginx-1.9.11/src/http/modules/ngx_http_proxy_module.c 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.9.11-patched/src/http/modules/ngx_http_proxy_module.c 2013-10-27 15:29:41.619378592 -0700
|
||||
@@ -602,10 +602,10 @@ static ngx_keyval_t ngx_http_proxy_cach
|
||||
static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||
|
||||
{ ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_add_x_forwarded_for"), NULL,
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
24
patches/nginx-1.9.11-server_header.patch
Normal file
24
patches/nginx-1.9.11-server_header.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -ur nginx-1.9.11/src/core/nginx.h nginx-1.9.11-patched/src/core/nginx.h
|
||||
--- nginx-1.9.11/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ nginx-1.9.11-patched/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1009011
|
||||
#define NGINX_VERSION "1.9.11"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
diff -ur nginx-1.9.11/src/http/ngx_http_header_filter_module.c nginx-1.9.11-patched/src/http/ngx_http_header_filter_module.c
|
||||
--- nginx-1.9.11/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ nginx-1.9.11-patched/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
44
patches/nginx-1.9.11-setting_args_invalidates_uri.patch
Normal file
44
patches/nginx-1.9.11-setting_args_invalidates_uri.patch
Normal file
@ -0,0 +1,44 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1390506359 28800
|
||||
# Node ID 17186b98c235c07e94c64e5853689f790f173756
|
||||
# Parent 4b50d1f299d8a69f3e3f7975132e1490352642fe
|
||||
Variable: setting $args should invalidate unparsed uri.
|
||||
|
||||
diff -r 4b50d1f299d8 -r 17186b98c235 src/http/ngx_http_variables.c
|
||||
--- a/src/http/ngx_http_variables.c Fri Jan 10 11:22:14 2014 -0800
|
||||
+++ b/src/http/ngx_http_variables.c Thu Jan 23 11:45:59 2014 -0800
|
||||
@@ -15,6 +15,8 @@
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
+static void ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
|
||||
@@ -218,7 +220,7 @@
|
||||
NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("args"),
|
||||
- ngx_http_variable_request_set,
|
||||
+ ngx_http_variable_request_args_set,
|
||||
ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, args),
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
@@ -647,6 +649,15 @@
|
||||
|
||||
|
||||
static void
|
||||
+ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data)
|
||||
+{
|
||||
+ r->valid_unparsed_uri = 0;
|
||||
+ ngx_http_variable_request_set(r, v, data);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
138
patches/nginx-1.9.11-slab_defrag.patch
Normal file
138
patches/nginx-1.9.11-slab_defrag.patch
Normal file
@ -0,0 +1,138 @@
|
||||
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
|
||||
index c3a27f7..1bde432 100644
|
||||
--- a/src/core/ngx_slab.c
|
||||
+++ b/src/core/ngx_slab.c
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
+#include <assert.h>
|
||||
|
||||
|
||||
#define NGX_SLAB_PAGE_MASK 3
|
||||
@@ -111,6 +112,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
|
||||
|
||||
pool->pages = (ngx_slab_page_t *) p;
|
||||
+ pool->npages = pages;
|
||||
|
||||
pool->free.prev = 0;
|
||||
pool->free.next = (ngx_slab_page_t *) p;
|
||||
@@ -118,6 +120,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
pool->pages->slab = pages;
|
||||
pool->pages->next = &pool->free;
|
||||
pool->pages->prev = (uintptr_t) &pool->free;
|
||||
+ pool->pages->prev_slab = 0;
|
||||
|
||||
pool->start = (u_char *)
|
||||
ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
|
||||
@@ -625,9 +628,16 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
if (page->slab >= pages) {
|
||||
|
||||
if (page->slab > pages) {
|
||||
+ /* adjust the next adjacent block's "prev_slab" field */
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages) {
|
||||
+ p->prev_slab = page->slab - pages;
|
||||
+ }
|
||||
+
|
||||
page[pages].slab = page->slab - pages;
|
||||
page[pages].next = page->next;
|
||||
page[pages].prev = page->prev;
|
||||
+ page[pages].prev_slab = pages;
|
||||
|
||||
p = (ngx_slab_page_t *) page->prev;
|
||||
p->next = &page[pages];
|
||||
@@ -651,6 +661,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
p->slab = NGX_SLAB_PAGE_BUSY;
|
||||
p->next = NULL;
|
||||
p->prev = NGX_SLAB_PAGE;
|
||||
+ p->prev_slab = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
@@ -668,7 +679,7 @@ static void
|
||||
ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
ngx_uint_t pages)
|
||||
{
|
||||
- ngx_slab_page_t *prev;
|
||||
+ ngx_slab_page_t *prev, *p;
|
||||
|
||||
page->slab = pages--;
|
||||
|
||||
@@ -682,6 +693,53 @@ ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
page->next->prev = page->prev;
|
||||
}
|
||||
|
||||
+ /* merge the next adjacent free block if it is free */
|
||||
+
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages
|
||||
+ && !(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ page->slab += p->slab;
|
||||
+
|
||||
+ /* remove the next adjacent block from the free list */
|
||||
+
|
||||
+ prev = (ngx_slab_page_t *) p->prev;
|
||||
+ prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = page->slab;
|
||||
+ }
|
||||
+
|
||||
+ ngx_memzero(p, sizeof(ngx_slab_page_t));
|
||||
+ }
|
||||
+
|
||||
+ if (page->prev_slab) {
|
||||
+ /* merge the previous adjacent block if it is free */
|
||||
+
|
||||
+ p = page - page->prev_slab;
|
||||
+ if (!(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ assert(p->slab == page->prev_slab);
|
||||
+
|
||||
+ p->slab += page->slab;
|
||||
+ ngx_memzero(page, sizeof(ngx_slab_page_t));
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = p->slab;
|
||||
+ }
|
||||
+
|
||||
+ /* skip adding "page" to the free list */
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
page->prev = (uintptr_t) &pool->free;
|
||||
page->next = pool->free.next;
|
||||
|
||||
diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h
|
||||
index c5e420b..287ac79 100644
|
||||
--- a/src/core/ngx_slab.h
|
||||
+++ b/src/core/ngx_slab.h
|
||||
@@ -19,6 +19,8 @@ struct ngx_slab_page_s {
|
||||
uintptr_t slab;
|
||||
ngx_slab_page_t *next;
|
||||
uintptr_t prev;
|
||||
+ uintptr_t prev_slab;
|
||||
+ /* number of pages for the previous adjacent block */
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +33,8 @@ typedef struct {
|
||||
ngx_slab_page_t *pages;
|
||||
ngx_slab_page_t free;
|
||||
|
||||
+ ngx_uint_t npages;
|
||||
+
|
||||
u_char *start;
|
||||
u_char *end;
|
||||
|
42
patches/nginx-1.9.11-ssl_cert_cb_yield.patch
Normal file
42
patches/nginx-1.9.11-ssl_cert_cb_yield.patch
Normal file
@ -0,0 +1,42 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@openresty.org>
|
||||
# Date 1451762084 28800
|
||||
# Sat Jan 02 11:14:44 2016 -0800
|
||||
# Node ID 449f0461859c16e95bdb18e8be6b94401545d3dd
|
||||
# Parent 78b4e10b4367b31367aad3c83c9c3acdd42397c4
|
||||
SSL: handled SSL_CTX_set_cert_cb() callback yielding.
|
||||
|
||||
OpenSSL 1.0.2+ introduces SSL_CTX_set_cert_cb() to allow custom
|
||||
callbacks to serve the SSL certificiates and private keys dynamically
|
||||
and lazily. The callbacks may yield for nonblocking I/O or sleeping.
|
||||
Here we added support for such usage in NGINX 3rd-party modules
|
||||
(like ngx_lua) in NGINX's event handlers for downstream SSL
|
||||
connections.
|
||||
|
||||
diff -r 78b4e10b4367 -r 449f0461859c src/event/ngx_event_openssl.c
|
||||
--- a/src/event/ngx_event_openssl.c Thu Dec 17 16:39:15 2015 +0300
|
||||
+++ b/src/event/ngx_event_openssl.c Sat Jan 02 11:14:44 2016 -0800
|
||||
@@ -1210,6 +1210,23 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
+ c->read->handler = ngx_ssl_handshake_handler;
|
||||
+ c->write->handler = ngx_ssl_handshake_handler;
|
||||
+
|
||||
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return NGX_AGAIN;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
c->ssl->no_wait_shutdown = 1;
|
23
patches/nginx-1.9.11-upstream_pipelining.patch
Normal file
23
patches/nginx-1.9.11-upstream_pipelining.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit f9907b72a76a21ac5413187b83177a919475c75f
|
||||
Author: Yichun Zhang (agentzh) <agentzh@gmail.com>
|
||||
Date: Wed Feb 10 16:05:08 2016 -0800
|
||||
|
||||
bugfix: upstream: keep sending request data after the first write attempt.
|
||||
|
||||
See
|
||||
http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html
|
||||
for more details on the issue.
|
||||
|
||||
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
|
||||
index dbaa956..a25aaa2 100644
|
||||
--- a/src/http/ngx_http_upstream.c
|
||||
+++ b/src/http/ngx_http_upstream.c
|
||||
@@ -2003,7 +2003,7 @@ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
||||
|
||||
#endif
|
||||
|
||||
- if (u->header_sent) {
|
||||
+ if (u->request_body_sent) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(c->write, 0);
|
11
patches/nginx-1.9.15-always_enable_cc_feature_tests.patch
Normal file
11
patches/nginx-1.9.15-always_enable_cc_feature_tests.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.9.15/auto/cc/conf 2015-10-30 22:47:50.000000000 +0800
|
||||
+++ nginx-1.9.15-patched/auto/cc/conf 2015-11-02 12:23:05.385156987 +0800
|
||||
@@ -136,7 +136,7 @@ fi
|
||||
CFLAGS="$CFLAGS $NGX_CC_OPT"
|
||||
NGX_TEST_LD_OPT="$NGX_LD_OPT"
|
||||
|
||||
-if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
+if [ 1 ]; then
|
||||
|
||||
if test -n "$NGX_LD_OPT"; then
|
||||
ngx_feature=--with-ld-opt=\"$NGX_LD_OPT\"
|
19
patches/nginx-1.9.15-cache_manager_exit.patch
Normal file
19
patches/nginx-1.9.15-cache_manager_exit.patch
Normal file
@ -0,0 +1,19 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1383598130 28800
|
||||
# Node ID f64218e1ac963337d84092536f588b8e0d99bbaa
|
||||
# Parent dea321e5c0216efccbb23e84bbce7cf3e28f130c
|
||||
Cache: gracefully exit the cache manager process.
|
||||
|
||||
diff -r dea321e5c021 -r f64218e1ac96 src/os/unix/ngx_process_cycle.c
|
||||
--- a/src/os/unix/ngx_process_cycle.c Thu Oct 31 18:23:49 2013 +0400
|
||||
+++ b/src/os/unix/ngx_process_cycle.c Mon Nov 04 12:48:50 2013 -0800
|
||||
@@ -1335,7 +1335,7 @@
|
||||
|
||||
if (ngx_terminate || ngx_quit) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
- exit(0);
|
||||
+ ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_reopen) {
|
1159
patches/nginx-1.9.15-dtrace.patch
Normal file
1159
patches/nginx-1.9.15-dtrace.patch
Normal file
File diff suppressed because it is too large
Load Diff
11
patches/nginx-1.9.15-gcc-maybe-uninitialized-warning.patch
Normal file
11
patches/nginx-1.9.15-gcc-maybe-uninitialized-warning.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- nginx-1.9.15/src/http/ngx_http_request.c 2013-05-06 03:26:50.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/http/ngx_http_request.c 2013-06-11 12:59:48.008321688 -0700
|
||||
@@ -1951,7 +1951,7 @@
|
||||
ngx_int_t rc;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
- ngx_http_core_srv_conf_t *cscf;
|
||||
+ ngx_http_core_srv_conf_t *cscf = NULL;
|
||||
|
||||
hc = r->http_connection;
|
||||
|
20
patches/nginx-1.9.15-hash_overflow.patch
Normal file
20
patches/nginx-1.9.15-hash_overflow.patch
Normal file
@ -0,0 +1,20 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1412276417 25200
|
||||
# Thu Oct 02 12:00:17 2014 -0700
|
||||
# Node ID 4032b992f23b054c1a2cfb0be879330d2c6708e5
|
||||
# Parent 1ff0f68d9376e3d184d65814a6372856bf65cfcd
|
||||
Hash: buffer overflow might happen when exceeding the pre-configured limits.
|
||||
|
||||
diff -r 1ff0f68d9376 -r 4032b992f23b src/core/ngx_hash.c
|
||||
--- a/src/core/ngx_hash.c Tue Sep 30 15:50:28 2014 -0700
|
||||
+++ b/src/core/ngx_hash.c Thu Oct 02 12:00:17 2014 -0700
|
||||
@@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ng
|
||||
continue;
|
||||
}
|
||||
|
||||
+ size--;
|
||||
+
|
||||
ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
|
||||
"could not build optimal %s, you should increase "
|
||||
"either %s_max_size: %i or %s_bucket_size: %i; "
|
13
patches/nginx-1.9.15-larger_max_error_str.patch
Normal file
13
patches/nginx-1.9.15-larger_max_error_str.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- nginx-1.9.15/src/core/ngx_log.h 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/ngx_log.h 2013-12-05 20:35:35.996236720 -0800
|
||||
@@ -64,7 +64,9 @@ struct ngx_log_s {
|
||||
};
|
||||
|
||||
|
||||
-#define NGX_MAX_ERROR_STR 2048
|
||||
+#ifndef NGX_MAX_ERROR_STR
|
||||
+#define NGX_MAX_ERROR_STR 4096
|
||||
+#endif
|
||||
|
||||
|
||||
/*********************************/
|
115
patches/nginx-1.9.15-log_escape_non_ascii.patch
Normal file
115
patches/nginx-1.9.15-log_escape_non_ascii.patch
Normal file
@ -0,0 +1,115 @@
|
||||
--- nginx-1.9.15/src/http/modules/ngx_http_log_module.c 2011-11-01 21:24:50.000000000 +0800
|
||||
+++ nginx-1.9.15-patched/src/http/modules/ngx_http_log_module.c 2011-11-10 16:17:29.599039534 +0800
|
||||
@@ -61,6 +61,8 @@
|
||||
time_t open_file_cache_valid;
|
||||
ngx_uint_t open_file_cache_min_uses;
|
||||
|
||||
+ ngx_flag_t escape_non_ascii;
|
||||
+
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
@@ -104,7 +106,8 @@
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
|
||||
+static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
|
||||
+ u_char *src, size_t size);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
@@ -146,6 +149,13 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("log_escape_non_ascii"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
+ ngx_conf_set_flag_slot,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
|
||||
+ NULL },
|
||||
+
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@@ -637,6 +647,7 @@
|
||||
ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
uintptr_t len;
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
@@ -645,7 +656,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- len = ngx_http_log_escape(NULL, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+
|
||||
+ len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
|
||||
|
||||
value->escape = len ? 1 : 0;
|
||||
|
||||
@@ -656,6 +669,7 @@
|
||||
static u_char *
|
||||
ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
{
|
||||
+ ngx_http_log_loc_conf_t *lcf;
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
@@ -669,16 +683,18 @@
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
|
||||
} else {
|
||||
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
|
||||
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
|
||||
+ return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uintptr_t
|
||||
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
|
||||
+ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
|
||||
+ size_t size)
|
||||
{
|
||||
- ngx_uint_t n;
|
||||
- static u_char hex[] = "0123456789ABCDEF";
|
||||
+ ngx_uint_t n;
|
||||
+ static u_char hex[] = "0123456789ABCDEF";
|
||||
|
||||
static uint32_t escape[] = {
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
@@ -698,6 +714,12 @@
|
||||
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||
};
|
||||
|
||||
+ if (lcf->escape_non_ascii) {
|
||||
+ ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
|
||||
+
|
||||
+ } else {
|
||||
+ ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
|
||||
+ }
|
||||
|
||||
if (dst == NULL) {
|
||||
|
||||
@@ -781,6 +803,7 @@
|
||||
}
|
||||
|
||||
conf->open_file_cache = NGX_CONF_UNSET_PTR;
|
||||
+ conf->escape_non_ascii = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
@@ -796,6 +819,8 @@
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
|
||||
+ ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
|
||||
+
|
||||
if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
|
||||
|
||||
conf->open_file_cache = prev->open_file_cache;
|
36
patches/nginx-1.9.15-no_Werror.patch
Normal file
36
patches/nginx-1.9.15-no_Werror.patch
Normal file
@ -0,0 +1,36 @@
|
||||
diff -urp nginx-1.9.15/auto/cc/clang nginx-1.9.15-patched/auto/cc/clang
|
||||
--- nginx-1.9.15/auto/cc/clang 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.15-patched/auto/cc/clang 2014-03-13 20:54:26.241413360 -0700
|
||||
@@ -89,7 +89,7 @@ CFLAGS="$CFLAGS -Wconditional-uninitiali
|
||||
CFLAGS="$CFLAGS -Wno-unused-parameter"
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.9.15/auto/cc/gcc nginx-1.9.15-patched/auto/cc/gcc
|
||||
--- nginx-1.9.15/auto/cc/gcc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.15-patched/auto/cc/gcc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -168,7 +168,7 @@ esac
|
||||
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
||||
diff -urp nginx-1.9.15/auto/cc/icc nginx-1.9.15-patched/auto/cc/icc
|
||||
--- nginx-1.9.15/auto/cc/icc 2014-03-04 03:39:24.000000000 -0800
|
||||
+++ nginx-1.9.15-patched/auto/cc/icc 2014-03-13 20:54:13.301355329 -0700
|
||||
@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
|
||||
esac
|
||||
|
||||
# stop on warning
|
||||
-CFLAGS="$CFLAGS -Werror"
|
||||
+#CFLAGS="$CFLAGS -Werror"
|
||||
|
||||
# debug
|
||||
CFLAGS="$CFLAGS -g"
|
90
patches/nginx-1.9.15-no_error_pages.patch
Normal file
90
patches/nginx-1.9.15-no_error_pages.patch
Normal file
@ -0,0 +1,90 @@
|
||||
--- nginx-1.9.15/src/http/ngx_http_core_module.c 2010-12-14 18:38:42.000000000 +0800
|
||||
+++ nginx-1.9.15-patched/src/http/ngx_http_core_module.c 2011-01-30 19:24:34.956354518 +0800
|
||||
@@ -57,6 +57,8 @@
|
||||
void *conf);
|
||||
static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
+static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
+ void *conf);
|
||||
static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -614,6 +616,14 @@
|
||||
0,
|
||||
NULL },
|
||||
|
||||
+ { ngx_string("no_error_pages"),
|
||||
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
+ |NGX_CONF_NOARGS,
|
||||
+ ngx_http_core_no_error_pages,
|
||||
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||
+ 0,
|
||||
+ NULL },
|
||||
+
|
||||
{ ngx_string("try_files"),
|
||||
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
ngx_http_core_try_files,
|
||||
@@ -3052,7 +3062,6 @@
|
||||
* clcf->types = NULL;
|
||||
* clcf->default_type = { 0, NULL };
|
||||
* clcf->error_log = NULL;
|
||||
- * clcf->error_pages = NULL;
|
||||
* clcf->try_files = NULL;
|
||||
* clcf->client_body_path = NULL;
|
||||
* clcf->regex = NULL;
|
||||
@@ -3062,6 +3071,7 @@
|
||||
* clcf->gzip_proxied = 0;
|
||||
*/
|
||||
|
||||
+ clcf->error_pages = NGX_CONF_UNSET_PTR;
|
||||
clcf->client_max_body_size = NGX_CONF_UNSET;
|
||||
clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
@@ -3250,9 +3260,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (conf->error_pages == NULL && prev->error_pages) {
|
||||
- conf->error_pages = prev->error_pages;
|
||||
- }
|
||||
+ ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
|
||||
|
||||
ngx_conf_merge_str_value(conf->default_type,
|
||||
prev->default_type, "text/plain");
|
||||
@@ -3988,6 +3996,10 @@
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
|
||||
if (clcf->error_pages == NULL) {
|
||||
+ return "conflicts with \"no_error_pages\"";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
|
||||
clcf->error_pages = ngx_array_create(cf->pool, 4,
|
||||
sizeof(ngx_http_err_page_t));
|
||||
if (clcf->error_pages == NULL) {
|
||||
@@ -4095,6 +4107,25 @@
|
||||
|
||||
|
||||
static char *
|
||||
+ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
+{
|
||||
+ ngx_http_core_loc_conf_t *clcf = conf;
|
||||
+
|
||||
+ if (clcf->error_pages == NULL) {
|
||||
+ return "is duplicate";
|
||||
+ }
|
||||
+
|
||||
+ if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
|
||||
+ return "conflicts with \"error_page\"";
|
||||
+ }
|
||||
+
|
||||
+ clcf->error_pages = NULL;
|
||||
+
|
||||
+ return NGX_CONF_OK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static char *
|
||||
ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf = conf;
|
587
patches/nginx-1.9.15-no_pool.patch
Normal file
587
patches/nginx-1.9.15-no_pool.patch
Normal file
@ -0,0 +1,587 @@
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.15/src/core/nginx.h nginx-1.9.15-patched/src/core/nginx.h
|
||||
--- nginx-1.9.15/src/core/nginx.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/nginx.h 2016-04-21 16:25:07.452944624 -0700
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
#define nginx_version 1009015
|
||||
#define NGINX_VERSION "1.9.15"
|
||||
-#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown (no pool)"
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.15/src/core/ngx_array.c nginx-1.9.15-patched/src/core/ngx_array.c
|
||||
--- nginx-1.9.15/src/core/ngx_array.c 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/ngx_array.c 2016-04-21 16:25:07.453947190 -0700
|
||||
@@ -30,26 +30,30 @@ ngx_array_create(ngx_pool_t *p, ngx_uint
|
||||
void
|
||||
ngx_array_destroy(ngx_array_t *a)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
|
||||
- p->d.last -= a->size * a->nalloc;
|
||||
+ if (a->elts) {
|
||||
+ ngx_pfree(p, a->elts);
|
||||
}
|
||||
|
||||
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
|
||||
- p->d.last = (u_char *) a;
|
||||
+ for (link = a->old_elts; link; link = link->next) {
|
||||
+ ngx_pfree(p, link->elts);
|
||||
}
|
||||
+
|
||||
+ ngx_pfree(p, a);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_array_push(ngx_array_t *a)
|
||||
{
|
||||
- void *elt, *new;
|
||||
- size_t size;
|
||||
- ngx_pool_t *p;
|
||||
+ void *elt, *new;
|
||||
+ size_t size;
|
||||
+ ngx_pool_t *p;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts == a->nalloc) {
|
||||
|
||||
@@ -59,29 +63,27 @@ ngx_array_push(ngx_array_t *a)
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + size == p->d.last
|
||||
- && p->d.last + a->size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
-
|
||||
- p->d.last += a->size;
|
||||
- a->nalloc++;
|
||||
+ /* allocate a new array */
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ new = ngx_palloc(p, 2 * size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, 2 * size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ ngx_memcpy(new, a->elts, size);
|
||||
|
||||
- ngx_memcpy(new, a->elts, size);
|
||||
- a->elts = new;
|
||||
- a->nalloc *= 2;
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
}
|
||||
+
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
+
|
||||
+ a->elts = new;
|
||||
+ a->nalloc *= 2;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
@@ -95,11 +97,10 @@ void *
|
||||
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
|
||||
{
|
||||
void *elt, *new;
|
||||
- size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *p;
|
||||
|
||||
- size = n * a->size;
|
||||
+ ngx_array_link_t *link;
|
||||
|
||||
if (a->nelts + n > a->nalloc) {
|
||||
|
||||
@@ -107,31 +108,27 @@ ngx_array_push_n(ngx_array_t *a, ngx_uin
|
||||
|
||||
p = a->pool;
|
||||
|
||||
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
|
||||
- && p->d.last + size <= p->d.end)
|
||||
- {
|
||||
- /*
|
||||
- * the array allocation is the last in the pool
|
||||
- * and there is space for new allocation
|
||||
- */
|
||||
+ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
|
||||
- p->d.last += size;
|
||||
- a->nalloc += n;
|
||||
+ new = ngx_palloc(p, nalloc * a->size);
|
||||
+ if (new == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- } else {
|
||||
- /* allocate a new array */
|
||||
+ ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
|
||||
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
|
||||
+ link = ngx_palloc(p, sizeof(ngx_array_link_t));
|
||||
+ if (link == NULL) {
|
||||
+ ngx_pfree(p, new);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- new = ngx_palloc(p, nalloc * a->size);
|
||||
- if (new == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
+ link->next = a->old_elts;
|
||||
+ link->elts = a->elts;
|
||||
+ a->old_elts = link;
|
||||
|
||||
- ngx_memcpy(new, a->elts, a->nelts * a->size);
|
||||
- a->elts = new;
|
||||
- a->nalloc = nalloc;
|
||||
- }
|
||||
+ a->elts = new;
|
||||
+ a->nalloc = nalloc;
|
||||
}
|
||||
|
||||
elt = (u_char *) a->elts + a->size * a->nelts;
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.15/src/core/ngx_array.h nginx-1.9.15-patched/src/core/ngx_array.h
|
||||
--- nginx-1.9.15/src/core/ngx_array.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/ngx_array.h 2016-04-21 16:25:07.453947190 -0700
|
||||
@@ -13,12 +13,23 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
+typedef struct ngx_array_link_s ngx_array_link_t;
|
||||
+
|
||||
+
|
||||
+struct ngx_array_link_s {
|
||||
+ void *elts;
|
||||
+ ngx_array_link_t *next;
|
||||
+};
|
||||
+
|
||||
+
|
||||
typedef struct {
|
||||
void *elts;
|
||||
ngx_uint_t nelts;
|
||||
size_t size;
|
||||
ngx_uint_t nalloc;
|
||||
ngx_pool_t *pool;
|
||||
+
|
||||
+ ngx_array_link_t *old_elts;
|
||||
} ngx_array_t;
|
||||
|
||||
|
||||
@@ -40,6 +51,7 @@ ngx_array_init(ngx_array_t *array, ngx_p
|
||||
array->size = size;
|
||||
array->nalloc = n;
|
||||
array->pool = pool;
|
||||
+ array->old_elts = NULL;
|
||||
|
||||
array->elts = ngx_palloc(pool, n * size);
|
||||
if (array->elts == NULL) {
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.15/src/core/ngx_palloc.c nginx-1.9.15-patched/src/core/ngx_palloc.c
|
||||
--- nginx-1.9.15/src/core/ngx_palloc.c 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/ngx_palloc.c 2016-04-21 16:25:45.912282685 -0700
|
||||
@@ -9,34 +9,26 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
-static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
|
||||
- ngx_uint_t align);
|
||||
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
|
||||
-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
|
||||
+static void * ngx_malloc(ngx_pool_t *pool, size_t size);
|
||||
|
||||
|
||||
ngx_pool_t *
|
||||
ngx_create_pool(size_t size, ngx_log_t *log)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
+ ngx_pool_t *p;
|
||||
|
||||
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
|
||||
+ size = sizeof(ngx_pool_t);
|
||||
+ p = ngx_alloc(size, log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.end = (u_char *) p + size;
|
||||
- p->d.next = NULL;
|
||||
- p->d.failed = 0;
|
||||
+ ngx_memzero(p, size);
|
||||
|
||||
size = size - sizeof(ngx_pool_t);
|
||||
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
|
||||
|
||||
p->current = p;
|
||||
- p->chain = NULL;
|
||||
- p->large = NULL;
|
||||
- p->cleanup = NULL;
|
||||
p->log = log;
|
||||
|
||||
return p;
|
||||
@@ -46,8 +38,7 @@ ngx_create_pool(size_t size, ngx_log_t *
|
||||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p, *n;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
for (c = pool->cleanup; c; c = c->next) {
|
||||
@@ -58,6 +49,11 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (pool->d == NULL) {
|
||||
+ ngx_free(pool);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
#if (NGX_DEBUG)
|
||||
|
||||
/*
|
||||
@@ -65,13 +61,9 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
* so we cannot use this log while free()ing the pool
|
||||
*/
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
|
||||
- }
|
||||
-
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
|
||||
+ "free: %p, unused: %d", d, 0);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
@@ -80,171 +72,82 @@ ngx_destroy_pool(ngx_pool_t *pool)
|
||||
|
||||
#endif
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
|
||||
- ngx_free(p);
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
|
||||
if (n == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ pool->d = NULL;
|
||||
+ ngx_free(pool);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_reset_pool(ngx_pool_t *pool)
|
||||
{
|
||||
- ngx_pool_t *p;
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *d, *n;
|
||||
+ ngx_pool_data_t *saved = NULL;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (l->alloc) {
|
||||
- ngx_free(l->alloc);
|
||||
+ if (pool->d) {
|
||||
+ for (d = pool->d, n = d->next; ; d = n, n = n->next) {
|
||||
+ if (d->alloc == pool->log) {
|
||||
+ saved = d;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ ngx_free(d);
|
||||
+
|
||||
+ if (n == NULL) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- for (p = pool; p; p = p->d.next) {
|
||||
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
|
||||
- p->d.failed = 0;
|
||||
+ pool->d = saved;
|
||||
+ pool->current = pool;
|
||||
+ pool->chain = NULL;
|
||||
}
|
||||
-
|
||||
- pool->current = pool;
|
||||
- pool->chain = NULL;
|
||||
- pool->large = NULL;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_palloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
-#if !(NGX_DEBUG_PALLOC)
|
||||
- if (size <= pool->max) {
|
||||
- return ngx_palloc_small(pool, size, 1);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_pnalloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
-#if !(NGX_DEBUG_PALLOC)
|
||||
- if (size <= pool->max) {
|
||||
- return ngx_palloc_small(pool, size, 0);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- return ngx_palloc_large(pool, size);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static ngx_inline void *
|
||||
-ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
|
||||
-{
|
||||
- u_char *m;
|
||||
- ngx_pool_t *p;
|
||||
-
|
||||
- p = pool->current;
|
||||
-
|
||||
- do {
|
||||
- m = p->d.last;
|
||||
-
|
||||
- if (align) {
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- }
|
||||
-
|
||||
- if ((size_t) (p->d.end - m) >= size) {
|
||||
- p->d.last = m + size;
|
||||
-
|
||||
- return m;
|
||||
- }
|
||||
-
|
||||
- p = p->d.next;
|
||||
-
|
||||
- } while (p);
|
||||
-
|
||||
- return ngx_palloc_block(pool, size);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static void *
|
||||
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
|
||||
-{
|
||||
- u_char *m;
|
||||
- size_t psize;
|
||||
- ngx_pool_t *p, *new;
|
||||
-
|
||||
- psize = (size_t) (pool->d.end - (u_char *) pool);
|
||||
-
|
||||
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
|
||||
- if (m == NULL) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- new = (ngx_pool_t *) m;
|
||||
-
|
||||
- new->d.end = m + psize;
|
||||
- new->d.next = NULL;
|
||||
- new->d.failed = 0;
|
||||
-
|
||||
- m += sizeof(ngx_pool_data_t);
|
||||
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
|
||||
- new->d.last = m + size;
|
||||
-
|
||||
- for (p = pool->current; p->d.next; p = p->d.next) {
|
||||
- if (p->d.failed++ > 4) {
|
||||
- pool->current = p->d.next;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- p->d.next = new;
|
||||
-
|
||||
- return m;
|
||||
+ return ngx_malloc(pool, size);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
-ngx_palloc_large(ngx_pool_t *pool, size_t size)
|
||||
+ngx_malloc(ngx_pool_t *pool, size_t size)
|
||||
{
|
||||
- void *p;
|
||||
- ngx_uint_t n;
|
||||
- ngx_pool_large_t *large;
|
||||
+ void *p;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_alloc(size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- n = 0;
|
||||
-
|
||||
- for (large = pool->large; large; large = large->next) {
|
||||
- if (large->alloc == NULL) {
|
||||
- large->alloc = p;
|
||||
- return p;
|
||||
- }
|
||||
-
|
||||
- if (n++ > 3) {
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -253,38 +156,48 @@ void *
|
||||
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
|
||||
{
|
||||
void *p;
|
||||
- ngx_pool_large_t *large;
|
||||
+ ngx_pool_data_t *d;
|
||||
|
||||
p = ngx_memalign(alignment, size, pool->log);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
|
||||
- if (large == NULL) {
|
||||
+ d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
|
||||
+ if (d == NULL){
|
||||
ngx_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- large->alloc = p;
|
||||
- large->next = pool->large;
|
||||
- pool->large = large;
|
||||
-
|
||||
+ d->alloc = p;
|
||||
+ d->next = pool->d;
|
||||
+ pool->d = d;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
-ngx_pfree(ngx_pool_t *pool, void *p)
|
||||
+ngx_pfree(ngx_pool_t *pool, void *data)
|
||||
{
|
||||
- ngx_pool_large_t *l;
|
||||
+ ngx_pool_data_t *p, *d;
|
||||
|
||||
- for (l = pool->large; l; l = l->next) {
|
||||
- if (p == l->alloc) {
|
||||
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
|
||||
- "free: %p", l->alloc);
|
||||
- ngx_free(l->alloc);
|
||||
- l->alloc = NULL;
|
||||
+ p = NULL;
|
||||
+ for (d = pool->d; d; p = d, d = d->next) {
|
||||
+ if (data == d->alloc) {
|
||||
+
|
||||
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
|
||||
+
|
||||
+ ngx_free(d->alloc);
|
||||
+ d->alloc = NULL;
|
||||
+
|
||||
+ if (p) {
|
||||
+ p->next = d->next;
|
||||
+
|
||||
+ } else {
|
||||
+ pool->d = d->next;
|
||||
+ }
|
||||
+
|
||||
+ ngx_free(d);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
diff --minimal '--exclude=*.swp' '--exclude=*~' -up nginx-1.9.15/src/core/ngx_palloc.h nginx-1.9.15-patched/src/core/ngx_palloc.h
|
||||
--- nginx-1.9.15/src/core/ngx_palloc.h 2016-04-19 09:02:38.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/core/ngx_palloc.h 2016-04-21 16:25:07.454949755 -0700
|
||||
@@ -38,28 +38,21 @@ struct ngx_pool_cleanup_s {
|
||||
};
|
||||
|
||||
|
||||
-typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
-
|
||||
-struct ngx_pool_large_s {
|
||||
- ngx_pool_large_t *next;
|
||||
- void *alloc;
|
||||
-};
|
||||
+typedef struct ngx_pool_data_s ngx_pool_large_t;
|
||||
+typedef struct ngx_pool_data_s ngx_pool_data_t;
|
||||
|
||||
|
||||
-typedef struct {
|
||||
- u_char *last;
|
||||
- u_char *end;
|
||||
- ngx_pool_t *next;
|
||||
- ngx_uint_t failed;
|
||||
-} ngx_pool_data_t;
|
||||
+struct ngx_pool_data_s {
|
||||
+ ngx_pool_data_t *next;
|
||||
+ void *alloc;
|
||||
+};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
- ngx_pool_data_t d;
|
||||
+ ngx_pool_data_t *d;
|
||||
size_t max;
|
||||
ngx_pool_t *current;
|
||||
ngx_chain_t *chain;
|
||||
- ngx_pool_large_t *large;
|
||||
ngx_pool_cleanup_t *cleanup;
|
||||
ngx_log_t *log;
|
||||
};
|
26
patches/nginx-1.9.15-pcre_conf_opt.patch
Normal file
26
patches/nginx-1.9.15-pcre_conf_opt.patch
Normal file
@ -0,0 +1,26 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1386694955 28800
|
||||
# Node ID 9ba6b149669f1f02eeb4cdc0ebd364a949b5c469
|
||||
# Parent 30e806b8636af5fd3f03ec17df24801f390f7511
|
||||
Configure: added new option --with-pcre-conf-opt=OPTIONS.
|
||||
|
||||
diff -r 30e806b8636a -r 9ba6b149669f auto/options
|
||||
--- a/auto/options Mon Dec 09 10:16:44 2013 +0400
|
||||
+++ b/auto/options Tue Dec 10 09:02:35 2013 -0800
|
||||
@@ -286,6 +286,7 @@
|
||||
--with-pcre) USE_PCRE=YES ;;
|
||||
--with-pcre=*) PCRE="$value" ;;
|
||||
--with-pcre-opt=*) PCRE_OPT="$value" ;;
|
||||
+ --with-pcre-conf-opt=*) PCRE_CONF_OPT="$value" ;;
|
||||
--with-pcre-jit) PCRE_JIT=YES ;;
|
||||
|
||||
--with-openssl=*) OPENSSL="$value" ;;
|
||||
@@ -441,6 +442,7 @@
|
||||
--with-pcre force PCRE library usage
|
||||
--with-pcre=DIR set path to PCRE library sources
|
||||
--with-pcre-opt=OPTIONS set additional build options for PCRE
|
||||
+ --with-pcre-conf-opt=OPTIONS set additional configure options for PCRE
|
||||
--with-pcre-jit build PCRE with JIT compilation support
|
||||
|
||||
--with-md5=DIR set path to md5 library sources
|
15
patches/nginx-1.9.15-proxy_host_port_vars.patch
Normal file
15
patches/nginx-1.9.15-proxy_host_port_vars.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- nginx-1.9.15/src/http/modules/ngx_http_proxy_module.c 2013-10-08 05:07:14.000000000 -0700
|
||||
+++ nginx-1.9.15-patched/src/http/modules/ngx_http_proxy_module.c 2013-10-27 15:29:41.619378592 -0700
|
||||
@@ -602,10 +602,10 @@ static ngx_keyval_t ngx_http_proxy_cach
|
||||
static ngx_http_variable_t ngx_http_proxy_vars[] = {
|
||||
|
||||
{ ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
|
||||
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
|
||||
+ NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("proxy_add_x_forwarded_for"), NULL,
|
||||
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
|
24
patches/nginx-1.9.15-server_header.patch
Normal file
24
patches/nginx-1.9.15-server_header.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -ur nginx-1.9.15/src/core/nginx.h nginx-1.9.15-patched/src/core/nginx.h
|
||||
--- nginx-1.9.15/src/core/nginx.h 2010-02-12 17:31:01.000000000 +0800
|
||||
+++ nginx-1.9.15-patched/src/core/nginx.h 2010-03-30 10:52:13.240702627 +0800
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#define nginx_version 1009015
|
||||
#define NGINX_VERSION "1.9.15"
|
||||
-#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
+#define NGINX_VER "openresty/" NGINX_VERSION ".unknown"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
diff -ur nginx-1.9.15/src/http/ngx_http_header_filter_module.c nginx-1.9.15-patched/src/http/ngx_http_header_filter_module.c
|
||||
--- nginx-1.9.15/src/http/ngx_http_header_filter_module.c 2010-03-03 23:14:04.000000000 +0800
|
||||
+++ nginx-1.9.15-patched/src/http/ngx_http_header_filter_module.c 2010-03-30 10:52:53.670909405 +0800
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
|
||||
-static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
+static char ngx_http_server_string[] = "Server: openresty" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
44
patches/nginx-1.9.15-setting_args_invalidates_uri.patch
Normal file
44
patches/nginx-1.9.15-setting_args_invalidates_uri.patch
Normal file
@ -0,0 +1,44 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@gmail.com>
|
||||
# Date 1390506359 28800
|
||||
# Node ID 17186b98c235c07e94c64e5853689f790f173756
|
||||
# Parent 4b50d1f299d8a69f3e3f7975132e1490352642fe
|
||||
Variable: setting $args should invalidate unparsed uri.
|
||||
|
||||
diff -r 4b50d1f299d8 -r 17186b98c235 src/http/ngx_http_variables.c
|
||||
--- a/src/http/ngx_http_variables.c Fri Jan 10 11:22:14 2014 -0800
|
||||
+++ b/src/http/ngx_http_variables.c Thu Jan 23 11:45:59 2014 -0800
|
||||
@@ -15,6 +15,8 @@
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
+static void ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
|
||||
@@ -218,7 +220,7 @@
|
||||
NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
|
||||
{ ngx_string("args"),
|
||||
- ngx_http_variable_request_set,
|
||||
+ ngx_http_variable_request_args_set,
|
||||
ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, args),
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
@@ -647,6 +649,15 @@
|
||||
|
||||
|
||||
static void
|
||||
+ngx_http_variable_request_args_set(ngx_http_request_t *r,
|
||||
+ ngx_http_variable_value_t *v, uintptr_t data)
|
||||
+{
|
||||
+ r->valid_unparsed_uri = 0;
|
||||
+ ngx_http_variable_request_set(r, v, data);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
ngx_http_variable_request_set(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
138
patches/nginx-1.9.15-slab_defrag.patch
Normal file
138
patches/nginx-1.9.15-slab_defrag.patch
Normal file
@ -0,0 +1,138 @@
|
||||
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
|
||||
index c3a27f7..1bde432 100644
|
||||
--- a/src/core/ngx_slab.c
|
||||
+++ b/src/core/ngx_slab.c
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
+#include <assert.h>
|
||||
|
||||
|
||||
#define NGX_SLAB_PAGE_MASK 3
|
||||
@@ -111,6 +112,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
|
||||
|
||||
pool->pages = (ngx_slab_page_t *) p;
|
||||
+ pool->npages = pages;
|
||||
|
||||
pool->free.prev = 0;
|
||||
pool->free.next = (ngx_slab_page_t *) p;
|
||||
@@ -118,6 +120,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
|
||||
pool->pages->slab = pages;
|
||||
pool->pages->next = &pool->free;
|
||||
pool->pages->prev = (uintptr_t) &pool->free;
|
||||
+ pool->pages->prev_slab = 0;
|
||||
|
||||
pool->start = (u_char *)
|
||||
ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
|
||||
@@ -625,9 +628,16 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
if (page->slab >= pages) {
|
||||
|
||||
if (page->slab > pages) {
|
||||
+ /* adjust the next adjacent block's "prev_slab" field */
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages) {
|
||||
+ p->prev_slab = page->slab - pages;
|
||||
+ }
|
||||
+
|
||||
page[pages].slab = page->slab - pages;
|
||||
page[pages].next = page->next;
|
||||
page[pages].prev = page->prev;
|
||||
+ page[pages].prev_slab = pages;
|
||||
|
||||
p = (ngx_slab_page_t *) page->prev;
|
||||
p->next = &page[pages];
|
||||
@@ -651,6 +661,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
|
||||
p->slab = NGX_SLAB_PAGE_BUSY;
|
||||
p->next = NULL;
|
||||
p->prev = NGX_SLAB_PAGE;
|
||||
+ p->prev_slab = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
@@ -668,7 +679,7 @@ static void
|
||||
ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
ngx_uint_t pages)
|
||||
{
|
||||
- ngx_slab_page_t *prev;
|
||||
+ ngx_slab_page_t *prev, *p;
|
||||
|
||||
page->slab = pages--;
|
||||
|
||||
@@ -682,6 +693,53 @@ ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
|
||||
page->next->prev = page->prev;
|
||||
}
|
||||
|
||||
+ /* merge the next adjacent free block if it is free */
|
||||
+
|
||||
+ p = &page[page->slab];
|
||||
+ if (p < pool->pages + pool->npages
|
||||
+ && !(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ page->slab += p->slab;
|
||||
+
|
||||
+ /* remove the next adjacent block from the free list */
|
||||
+
|
||||
+ prev = (ngx_slab_page_t *) p->prev;
|
||||
+ prev->next = p->next;
|
||||
+ p->next->prev = p->prev;
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = page->slab;
|
||||
+ }
|
||||
+
|
||||
+ ngx_memzero(p, sizeof(ngx_slab_page_t));
|
||||
+ }
|
||||
+
|
||||
+ if (page->prev_slab) {
|
||||
+ /* merge the previous adjacent block if it is free */
|
||||
+
|
||||
+ p = page - page->prev_slab;
|
||||
+ if (!(p->slab & NGX_SLAB_PAGE_START)
|
||||
+ && p->next != NULL
|
||||
+ && (p->prev & NGX_SLAB_PAGE_MASK) == NGX_SLAB_PAGE)
|
||||
+ {
|
||||
+ assert(p->slab == page->prev_slab);
|
||||
+
|
||||
+ p->slab += page->slab;
|
||||
+ ngx_memzero(page, sizeof(ngx_slab_page_t));
|
||||
+
|
||||
+ /* adjust the "prev_slab" field in the next adjacent block */
|
||||
+ if (p + p->slab < pool->pages + pool->npages) {
|
||||
+ p[p->slab].prev_slab = p->slab;
|
||||
+ }
|
||||
+
|
||||
+ /* skip adding "page" to the free list */
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
page->prev = (uintptr_t) &pool->free;
|
||||
page->next = pool->free.next;
|
||||
|
||||
diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h
|
||||
index c5e420b..287ac79 100644
|
||||
--- a/src/core/ngx_slab.h
|
||||
+++ b/src/core/ngx_slab.h
|
||||
@@ -19,6 +19,8 @@ struct ngx_slab_page_s {
|
||||
uintptr_t slab;
|
||||
ngx_slab_page_t *next;
|
||||
uintptr_t prev;
|
||||
+ uintptr_t prev_slab;
|
||||
+ /* number of pages for the previous adjacent block */
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +33,8 @@ typedef struct {
|
||||
ngx_slab_page_t *pages;
|
||||
ngx_slab_page_t free;
|
||||
|
||||
+ ngx_uint_t npages;
|
||||
+
|
||||
u_char *start;
|
||||
u_char *end;
|
||||
|
42
patches/nginx-1.9.15-ssl_cert_cb_yield.patch
Normal file
42
patches/nginx-1.9.15-ssl_cert_cb_yield.patch
Normal file
@ -0,0 +1,42 @@
|
||||
# HG changeset patch
|
||||
# User Yichun Zhang <agentzh@openresty.org>
|
||||
# Date 1451762084 28800
|
||||
# Sat Jan 02 11:14:44 2016 -0800
|
||||
# Node ID 449f0461859c16e95bdb18e8be6b94401545d3dd
|
||||
# Parent 78b4e10b4367b31367aad3c83c9c3acdd42397c4
|
||||
SSL: handled SSL_CTX_set_cert_cb() callback yielding.
|
||||
|
||||
OpenSSL 1.0.2+ introduces SSL_CTX_set_cert_cb() to allow custom
|
||||
callbacks to serve the SSL certificiates and private keys dynamically
|
||||
and lazily. The callbacks may yield for nonblocking I/O or sleeping.
|
||||
Here we added support for such usage in NGINX 3rd-party modules
|
||||
(like ngx_lua) in NGINX's event handlers for downstream SSL
|
||||
connections.
|
||||
|
||||
diff -r 78b4e10b4367 -r 449f0461859c src/event/ngx_event_openssl.c
|
||||
--- a/src/event/ngx_event_openssl.c Thu Dec 17 16:39:15 2015 +0300
|
||||
+++ b/src/event/ngx_event_openssl.c Sat Jan 02 11:14:44 2016 -0800
|
||||
@@ -1210,6 +1210,23 @@
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
+ c->read->handler = ngx_ssl_handshake_handler;
|
||||
+ c->write->handler = ngx_ssl_handshake_handler;
|
||||
+
|
||||
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ return NGX_AGAIN;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
c->ssl->no_wait_shutdown = 1;
|
16
patches/nginx-1.9.15-ssl_pending_session.patch
Normal file
16
patches/nginx-1.9.15-ssl_pending_session.patch
Normal file
@ -0,0 +1,16 @@
|
||||
--- nginx-1.9.15/src/event/ngx_event_openssl.c 2016-07-17 19:20:30.411137606 -0700
|
||||
+++ nginx-1.9.15-patched/src/event/ngx_event_openssl.c 2016-07-19 16:53:35.539768477 -0700
|
||||
@@ -1307,7 +1307,12 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
- if (sslerr == SSL_ERROR_WANT_X509_LOOKUP) {
|
||||
+ if (sslerr == SSL_ERROR_WANT_X509_LOOKUP
|
||||
+# ifdef SSL_ERROR_PENDING_SESSION
|
||||
+ || sslerr == SSL_ERROR_PENDING_SESSION
|
||||
+# endif
|
||||
+ )
|
||||
+ {
|
||||
c->read->handler = ngx_ssl_handshake_handler;
|
||||
c->write->handler = ngx_ssl_handshake_handler;
|
||||
|
23
patches/nginx-1.9.15-upstream_pipelining.patch
Normal file
23
patches/nginx-1.9.15-upstream_pipelining.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit f9907b72a76a21ac5413187b83177a919475c75f
|
||||
Author: Yichun Zhang (agentzh) <agentzh@gmail.com>
|
||||
Date: Wed Feb 10 16:05:08 2016 -0800
|
||||
|
||||
bugfix: upstream: keep sending request data after the first write attempt.
|
||||
|
||||
See
|
||||
http://mailman.nginx.org/pipermail/nginx-devel/2012-March/002040.html
|
||||
for more details on the issue.
|
||||
|
||||
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
|
||||
index dbaa956..a25aaa2 100644
|
||||
--- a/src/http/ngx_http_upstream.c
|
||||
+++ b/src/http/ngx_http_upstream.c
|
||||
@@ -2003,7 +2003,7 @@ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
||||
|
||||
#endif
|
||||
|
||||
- if (u->header_sent) {
|
||||
+ if (u->request_body_sent) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(c->write, 0);
|
120
patches/nginx-1.9.15-upstream_timeout_fields.patch
Normal file
120
patches/nginx-1.9.15-upstream_timeout_fields.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff -r 13070ecfda67 src/http/ngx_http_upstream.c
|
||||
--- a/src/http/ngx_http_upstream.c Tue Apr 19 19:02:37 2016 +0300
|
||||
+++ b/src/http/ngx_http_upstream.c Fri Jul 01 12:14:53 2016 -0700
|
||||
@@ -481,12 +481,19 @@ void
|
||||
ngx_http_upstream_init(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
+ ngx_http_upstream_t *u;
|
||||
|
||||
c = r->connection;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http init upstream, client timer: %d", c->read->timer_set);
|
||||
|
||||
+ u = r->upstream;
|
||||
+
|
||||
+ u->connect_timeout = u->conf->connect_timeout;
|
||||
+ u->send_timeout = u->conf->send_timeout;
|
||||
+ u->read_timeout = u->conf->read_timeout;
|
||||
+
|
||||
#if (NGX_HTTP_V2)
|
||||
if (r->stream) {
|
||||
ngx_http_upstream_init_request(r);
|
||||
@@ -1451,7 +1458,7 @@ ngx_http_upstream_connect(ngx_http_reque
|
||||
u->request_body_sent = 0;
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
- ngx_add_timer(c->write, u->conf->connect_timeout);
|
||||
+ ngx_add_timer(c->write, u->connect_timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1540,7 +1547,7 @@ ngx_http_upstream_ssl_init_connection(ng
|
||||
if (rc == NGX_AGAIN) {
|
||||
|
||||
if (!c->write->timer_set) {
|
||||
- ngx_add_timer(c->write, u->conf->connect_timeout);
|
||||
+ ngx_add_timer(c->write, u->connect_timeout);
|
||||
}
|
||||
|
||||
c->ssl->handler = ngx_http_upstream_ssl_handshake;
|
||||
@@ -1816,7 +1823,7 @@ ngx_http_upstream_send_request(ngx_http_
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (!c->write->ready) {
|
||||
- ngx_add_timer(c->write, u->conf->send_timeout);
|
||||
+ ngx_add_timer(c->write, u->send_timeout);
|
||||
|
||||
} else if (c->write->timer_set) {
|
||||
ngx_del_timer(c->write);
|
||||
@@ -1859,7 +1866,7 @@ ngx_http_upstream_send_request(ngx_http_
|
||||
return;
|
||||
}
|
||||
|
||||
- ngx_add_timer(c->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(c->read, u->read_timeout);
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_http_upstream_process_header(r, u);
|
||||
@@ -2658,7 +2665,7 @@ ngx_http_upstream_process_body_in_memory
|
||||
}
|
||||
|
||||
if (rev->active) {
|
||||
- ngx_add_timer(rev, u->conf->read_timeout);
|
||||
+ ngx_add_timer(rev, u->read_timeout);
|
||||
|
||||
} else if (rev->timer_set) {
|
||||
ngx_del_timer(rev);
|
||||
@@ -2982,7 +2989,7 @@ ngx_http_upstream_send_response(ngx_http
|
||||
p->cyclic_temp_file = 0;
|
||||
}
|
||||
|
||||
- p->read_timeout = u->conf->read_timeout;
|
||||
+ p->read_timeout = u->read_timeout;
|
||||
p->send_timeout = clcf->send_timeout;
|
||||
p->send_lowat = clcf->send_lowat;
|
||||
|
||||
@@ -3239,7 +3246,7 @@ ngx_http_upstream_process_upgraded(ngx_h
|
||||
}
|
||||
|
||||
if (upstream->write->active && !upstream->write->ready) {
|
||||
- ngx_add_timer(upstream->write, u->conf->send_timeout);
|
||||
+ ngx_add_timer(upstream->write, u->send_timeout);
|
||||
|
||||
} else if (upstream->write->timer_set) {
|
||||
ngx_del_timer(upstream->write);
|
||||
@@ -3251,7 +3258,7 @@ ngx_http_upstream_process_upgraded(ngx_h
|
||||
}
|
||||
|
||||
if (upstream->read->active && !upstream->read->ready) {
|
||||
- ngx_add_timer(upstream->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(upstream->read, u->read_timeout);
|
||||
|
||||
} else if (upstream->read->timer_set) {
|
||||
ngx_del_timer(upstream->read);
|
||||
@@ -3444,7 +3451,7 @@ ngx_http_upstream_process_non_buffered_r
|
||||
}
|
||||
|
||||
if (upstream->read->active && !upstream->read->ready) {
|
||||
- ngx_add_timer(upstream->read, u->conf->read_timeout);
|
||||
+ ngx_add_timer(upstream->read, u->read_timeout);
|
||||
|
||||
} else if (upstream->read->timer_set) {
|
||||
ngx_del_timer(upstream->read);
|
||||
diff -r 13070ecfda67 src/http/ngx_http_upstream.h
|
||||
--- a/src/http/ngx_http_upstream.h Tue Apr 19 19:02:37 2016 +0300
|
||||
+++ b/src/http/ngx_http_upstream.h Fri Jul 01 12:14:53 2016 -0700
|
||||
@@ -309,6 +309,12 @@ struct ngx_http_upstream_s {
|
||||
ngx_chain_writer_ctx_t writer;
|
||||
|
||||
ngx_http_upstream_conf_t *conf;
|
||||
+
|
||||
+#define HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS 1
|
||||
+ ngx_msec_t connect_timeout;
|
||||
+ ngx_msec_t send_timeout;
|
||||
+ ngx_msec_t read_timeout;
|
||||
+
|
||||
#if (NGX_HTTP_CACHE)
|
||||
ngx_array_t *caches;
|
||||
#endif
|
565
patches/nginx-1.9.7-resolver_security_fixes.patch
Normal file
565
patches/nginx-1.9.7-resolver_security_fixes.patch
Normal file
@ -0,0 +1,565 @@
|
||||
diff -upr nginx-1.9.7-old/src/core/ngx_resolver.c nginx-1.9.7/src/core/ngx_resolver.c
|
||||
--- nginx-1.9.7-old/src/core/ngx_resolver.c 2016-01-26 11:54:55.915406799 -0800
|
||||
+++ nginx-1.9.7/src/core/ngx_resolver.c 2016-01-26 11:55:27.067782268 -0800
|
||||
@@ -59,15 +59,15 @@ ngx_int_t ngx_udp_connect(ngx_udp_connec
|
||||
static void ngx_resolver_cleanup(void *data);
|
||||
static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
|
||||
static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
|
||||
- ngx_resolver_ctx_t *ctx);
|
||||
+ ngx_resolver_ctx_t *ctx, ngx_str_t *name);
|
||||
static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
||||
ngx_queue_t *queue);
|
||||
static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
|
||||
ngx_resolver_node_t *rn);
|
||||
-static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn,
|
||||
- ngx_resolver_ctx_t *ctx);
|
||||
-static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
|
||||
- ngx_resolver_ctx_t *ctx);
|
||||
+static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r,
|
||||
+ ngx_resolver_node_t *rn, ngx_str_t *name);
|
||||
+static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r,
|
||||
+ ngx_resolver_node_t *rn, ngx_addr_t *addr);
|
||||
static void ngx_resolver_resend_handler(ngx_event_t *ev);
|
||||
static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
||||
ngx_queue_t *queue);
|
||||
@@ -376,7 +376,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx
|
||||
|
||||
/* lock name mutex */
|
||||
|
||||
- rc = ngx_resolve_name_locked(r, ctx);
|
||||
+ rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_OK;
|
||||
@@ -403,7 +403,6 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx
|
||||
void
|
||||
ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
||||
{
|
||||
- uint32_t hash;
|
||||
ngx_resolver_t *r;
|
||||
ngx_resolver_ctx_t *w, **p;
|
||||
ngx_resolver_node_t *rn;
|
||||
@@ -423,11 +422,9 @@ ngx_resolve_name_done(ngx_resolver_ctx_t
|
||||
|
||||
/* lock name mutex */
|
||||
|
||||
- if (ctx->state == NGX_AGAIN) {
|
||||
-
|
||||
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
|
||||
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
|
||||
|
||||
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
|
||||
+ rn = ctx->node;
|
||||
|
||||
if (rn) {
|
||||
p = &rn->waiting;
|
||||
@@ -472,23 +469,28 @@ done:
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
-ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
||||
+ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
||||
+ ngx_str_t *name)
|
||||
{
|
||||
uint32_t hash;
|
||||
ngx_int_t rc;
|
||||
+ ngx_str_t cname;
|
||||
ngx_uint_t naddrs;
|
||||
ngx_addr_t *addrs;
|
||||
- ngx_resolver_ctx_t *next;
|
||||
+ ngx_resolver_ctx_t *next, *last;
|
||||
ngx_resolver_node_t *rn;
|
||||
|
||||
- ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len);
|
||||
+ ngx_strlow(name->data, name->data, name->len);
|
||||
|
||||
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
|
||||
+ hash = ngx_crc32_short(name->data, name->len);
|
||||
|
||||
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
|
||||
+ rn = ngx_resolver_lookup_name(r, name, hash);
|
||||
|
||||
if (rn) {
|
||||
|
||||
+ /* ctx can be a list after NGX_RESOLVE_CNAME */
|
||||
+ for (last = ctx; last->next; last = last->next);
|
||||
+
|
||||
if (rn->valid >= ngx_time()) {
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
|
||||
@@ -516,7 +518,7 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
}
|
||||
}
|
||||
|
||||
- ctx->next = rn->waiting;
|
||||
+ last->next = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
/* unlock name mutex */
|
||||
@@ -556,13 +558,13 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
|
||||
if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
|
||||
|
||||
- ctx->name.len = rn->cnlen;
|
||||
- ctx->name.data = rn->u.cname;
|
||||
+ cname.len = rn->cnlen;
|
||||
+ cname.data = rn->u.cname;
|
||||
|
||||
- return ngx_resolve_name_locked(r, ctx);
|
||||
+ return ngx_resolve_name_locked(r, ctx, &cname);
|
||||
}
|
||||
|
||||
- ctx->next = rn->waiting;
|
||||
+ last->next = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
/* unlock name mutex */
|
||||
@@ -581,10 +583,29 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
|
||||
if (rn->waiting) {
|
||||
|
||||
- ctx->next = rn->waiting;
|
||||
+ if (ctx->event == NULL) {
|
||||
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
||||
+ if (ctx->event == NULL) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
+ ctx->event->data = ctx;
|
||||
+ ctx->event->log = r->log;
|
||||
+ ctx->ident = -1;
|
||||
+
|
||||
+ ngx_add_timer(ctx->event, ctx->timeout);
|
||||
+ }
|
||||
+
|
||||
+ last->next = rn->waiting;
|
||||
rn->waiting = ctx;
|
||||
ctx->state = NGX_AGAIN;
|
||||
|
||||
+ do {
|
||||
+ ctx->node = rn;
|
||||
+ ctx = ctx->next;
|
||||
+ } while (ctx);
|
||||
+
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
@@ -623,14 +644,14 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
- rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len);
|
||||
+ rn->name = ngx_resolver_dup(r, name->data, name->len);
|
||||
if (rn->name == NULL) {
|
||||
ngx_resolver_free(r, rn);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rn->node.key = hash;
|
||||
- rn->nlen = (u_short) ctx->name.len;
|
||||
+ rn->nlen = (u_short) name->len;
|
||||
rn->query = NULL;
|
||||
#if (NGX_HAVE_INET6)
|
||||
rn->query6 = NULL;
|
||||
@@ -639,7 +660,7 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
ngx_rbtree_insert(&r->name_rbtree, &rn->node);
|
||||
}
|
||||
|
||||
- rc = ngx_resolver_create_name_query(rn, ctx);
|
||||
+ rc = ngx_resolver_create_name_query(r, rn, name);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
goto failed;
|
||||
@@ -652,8 +673,14 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
ngx_resolver_free(r, rn->name);
|
||||
ngx_resolver_free(r, rn);
|
||||
|
||||
- ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
- ctx->handler(ctx);
|
||||
+ do {
|
||||
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
+ next = ctx->next;
|
||||
+
|
||||
+ ctx->handler(ctx);
|
||||
+
|
||||
+ ctx = next;
|
||||
+ } while (ctx);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -674,9 +701,9 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
- ctx->event->data = rn;
|
||||
+ ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
- rn->ident = -1;
|
||||
+ ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
}
|
||||
@@ -697,6 +724,11 @@ ngx_resolve_name_locked(ngx_resolver_t *
|
||||
|
||||
ctx->state = NGX_AGAIN;
|
||||
|
||||
+ do {
|
||||
+ ctx->node = rn;
|
||||
+ ctx = ctx->next;
|
||||
+ } while (ctx);
|
||||
+
|
||||
return NGX_AGAIN;
|
||||
|
||||
failed:
|
||||
@@ -804,9 +836,22 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
|
||||
|
||||
if (rn->waiting) {
|
||||
|
||||
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
||||
+ if (ctx->event == NULL) {
|
||||
+ return NGX_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
+ ctx->event->data = ctx;
|
||||
+ ctx->event->log = r->log;
|
||||
+ ctx->ident = -1;
|
||||
+
|
||||
+ ngx_add_timer(ctx->event, ctx->timeout);
|
||||
+
|
||||
ctx->next = rn->waiting;
|
||||
rn->waiting = ctx;
|
||||
ctx->state = NGX_AGAIN;
|
||||
+ ctx->node = rn;
|
||||
|
||||
/* unlock addr mutex */
|
||||
|
||||
@@ -848,7 +893,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
|
||||
ngx_rbtree_insert(tree, &rn->node);
|
||||
}
|
||||
|
||||
- if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
|
||||
+ if (ngx_resolver_create_addr_query(r, rn, &ctx->addr) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -867,9 +912,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
|
||||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
- ctx->event->data = rn;
|
||||
+ ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
- rn->ident = -1;
|
||||
+ ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
|
||||
@@ -892,6 +937,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
|
||||
/* unlock addr mutex */
|
||||
|
||||
ctx->state = NGX_AGAIN;
|
||||
+ ctx->node = rn;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
@@ -922,17 +968,11 @@ failed:
|
||||
void
|
||||
ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
|
||||
{
|
||||
- in_addr_t addr;
|
||||
ngx_queue_t *expire_queue;
|
||||
ngx_rbtree_t *tree;
|
||||
ngx_resolver_t *r;
|
||||
ngx_resolver_ctx_t *w, **p;
|
||||
- struct sockaddr_in *sin;
|
||||
ngx_resolver_node_t *rn;
|
||||
-#if (NGX_HAVE_INET6)
|
||||
- uint32_t hash;
|
||||
- struct sockaddr_in6 *sin6;
|
||||
-#endif
|
||||
|
||||
r = ctx->resolver;
|
||||
|
||||
@@ -959,23 +999,9 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t
|
||||
|
||||
/* lock addr mutex */
|
||||
|
||||
- if (ctx->state == NGX_AGAIN) {
|
||||
-
|
||||
- switch (ctx->addr.sockaddr->sa_family) {
|
||||
-
|
||||
-#if (NGX_HAVE_INET6)
|
||||
- case AF_INET6:
|
||||
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
|
||||
- hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16);
|
||||
- rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash);
|
||||
- break;
|
||||
-#endif
|
||||
+ if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
|
||||
|
||||
- default: /* AF_INET */
|
||||
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
|
||||
- addr = ntohl(sin->sin_addr.s_addr);
|
||||
- rn = ngx_resolver_lookup_addr(r, addr);
|
||||
- }
|
||||
+ rn = ctx->node;
|
||||
|
||||
if (rn) {
|
||||
p = &rn->waiting;
|
||||
@@ -1312,7 +1338,7 @@ ngx_resolver_process_response(ngx_resolv
|
||||
times = 0;
|
||||
|
||||
for (q = ngx_queue_head(&r->name_resend_queue);
|
||||
- q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100;
|
||||
+ q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
|
||||
q = ngx_queue_next(q))
|
||||
{
|
||||
rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
|
||||
@@ -1975,20 +2001,39 @@ ngx_resolver_process_a(ngx_resolver_t *r
|
||||
|
||||
ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
|
||||
|
||||
+ ngx_resolver_free(r, rn->query);
|
||||
+ rn->query = NULL;
|
||||
+#if (NGX_HAVE_INET6)
|
||||
+ rn->query6 = NULL;
|
||||
+#endif
|
||||
+
|
||||
ctx = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
if (ctx) {
|
||||
- ctx->name = name;
|
||||
|
||||
- (void) ngx_resolve_name_locked(r, ctx);
|
||||
- }
|
||||
+ if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) {
|
||||
|
||||
- ngx_resolver_free(r, rn->query);
|
||||
- rn->query = NULL;
|
||||
-#if (NGX_HAVE_INET6)
|
||||
- rn->query6 = NULL;
|
||||
-#endif
|
||||
+ /* unlock name mutex */
|
||||
+
|
||||
+ do {
|
||||
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
+ next = ctx->next;
|
||||
+
|
||||
+ ctx->handler(ctx);
|
||||
+
|
||||
+ ctx = next;
|
||||
+ } while (ctx);
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (next = ctx; next; next = next->next) {
|
||||
+ next->node = NULL;
|
||||
+ }
|
||||
+
|
||||
+ (void) ngx_resolve_name_locked(r, ctx, &name);
|
||||
+ }
|
||||
|
||||
/* unlock name mutex */
|
||||
|
||||
@@ -2496,27 +2541,23 @@ ngx_resolver_rbtree_insert_addr6_value(n
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
-ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
||||
+ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
||||
+ ngx_str_t *name)
|
||||
{
|
||||
u_char *p, *s;
|
||||
size_t len, nlen;
|
||||
ngx_uint_t ident;
|
||||
-#if (NGX_HAVE_INET6)
|
||||
- ngx_resolver_t *r;
|
||||
-#endif
|
||||
ngx_resolver_qs_t *qs;
|
||||
ngx_resolver_hdr_t *query;
|
||||
|
||||
- nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
|
||||
+ nlen = name->len ? (1 + name->len + 1) : 1;
|
||||
|
||||
len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
- r = ctx->resolver;
|
||||
-
|
||||
- p = ngx_resolver_alloc(ctx->resolver, r->ipv6 ? len * 2 : len);
|
||||
+ p = ngx_resolver_alloc(r, r->ipv6 ? len * 2 : len);
|
||||
#else
|
||||
- p = ngx_resolver_alloc(ctx->resolver, len);
|
||||
+ p = ngx_resolver_alloc(r, len);
|
||||
#endif
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
@@ -2535,8 +2576,8 @@ ngx_resolver_create_name_query(ngx_resol
|
||||
|
||||
ident = ngx_random();
|
||||
|
||||
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
|
||||
- "resolve: \"%V\" A %i", &ctx->name, ident & 0xffff);
|
||||
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
|
||||
+ "resolve: \"%V\" A %i", name, ident & 0xffff);
|
||||
|
||||
query->ident_hi = (u_char) ((ident >> 8) & 0xff);
|
||||
query->ident_lo = (u_char) (ident & 0xff);
|
||||
@@ -2566,11 +2607,11 @@ ngx_resolver_create_name_query(ngx_resol
|
||||
p--;
|
||||
*p-- = '\0';
|
||||
|
||||
- if (ctx->name.len == 0) {
|
||||
+ if (name->len == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
- for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
|
||||
+ for (s = name->data + name->len - 1; s >= name->data; s--) {
|
||||
if (*s != '.') {
|
||||
*p = *s;
|
||||
len++;
|
||||
@@ -2606,8 +2647,8 @@ ngx_resolver_create_name_query(ngx_resol
|
||||
|
||||
ident = ngx_random();
|
||||
|
||||
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
|
||||
- "resolve: \"%V\" AAAA %i", &ctx->name, ident & 0xffff);
|
||||
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
|
||||
+ "resolve: \"%V\" AAAA %i", name, ident & 0xffff);
|
||||
|
||||
query->ident_hi = (u_char) ((ident >> 8) & 0xff);
|
||||
query->ident_lo = (u_char) (ident & 0xff);
|
||||
@@ -2624,11 +2665,12 @@ ngx_resolver_create_name_query(ngx_resol
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
-ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
||||
+ngx_resolver_create_addr_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
||||
+ ngx_addr_t *addr)
|
||||
{
|
||||
u_char *p, *d;
|
||||
size_t len;
|
||||
- in_addr_t addr;
|
||||
+ in_addr_t inaddr;
|
||||
ngx_int_t n;
|
||||
ngx_uint_t ident;
|
||||
ngx_resolver_hdr_t *query;
|
||||
@@ -2637,7 +2679,7 @@ ngx_resolver_create_addr_query(ngx_resol
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
- switch (ctx->addr.sockaddr->sa_family) {
|
||||
+ switch (addr->sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
@@ -2654,7 +2696,7 @@ ngx_resolver_create_addr_query(ngx_resol
|
||||
+ sizeof(ngx_resolver_qs_t);
|
||||
}
|
||||
|
||||
- p = ngx_resolver_alloc(ctx->resolver, len);
|
||||
+ p = ngx_resolver_alloc(r, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@@ -2678,11 +2720,11 @@ ngx_resolver_create_addr_query(ngx_resol
|
||||
|
||||
p += sizeof(ngx_resolver_hdr_t);
|
||||
|
||||
- switch (ctx->addr.sockaddr->sa_family) {
|
||||
+ switch (addr->sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
|
||||
+ sin6 = (struct sockaddr_in6 *) addr->sockaddr;
|
||||
|
||||
for (n = 15; n >= 0; n--) {
|
||||
p = ngx_sprintf(p, "\1%xd\1%xd",
|
||||
@@ -2697,11 +2739,11 @@ ngx_resolver_create_addr_query(ngx_resol
|
||||
|
||||
default: /* AF_INET */
|
||||
|
||||
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
|
||||
- addr = ntohl(sin->sin_addr.s_addr);
|
||||
+ sin = (struct sockaddr_in *) addr->sockaddr;
|
||||
+ inaddr = ntohl(sin->sin_addr.s_addr);
|
||||
|
||||
for (n = 0; n < 32; n += 8) {
|
||||
- d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
|
||||
+ d = ngx_sprintf(&p[1], "%ud", (inaddr >> n) & 0xff);
|
||||
*p = (u_char) (d - &p[1]);
|
||||
p = d;
|
||||
}
|
||||
@@ -2815,21 +2857,13 @@ done:
|
||||
static void
|
||||
ngx_resolver_timeout_handler(ngx_event_t *ev)
|
||||
{
|
||||
- ngx_resolver_ctx_t *ctx, *next;
|
||||
- ngx_resolver_node_t *rn;
|
||||
+ ngx_resolver_ctx_t *ctx;
|
||||
|
||||
- rn = ev->data;
|
||||
- ctx = rn->waiting;
|
||||
- rn->waiting = NULL;
|
||||
+ ctx = ev->data;
|
||||
|
||||
- do {
|
||||
- ctx->state = NGX_RESOLVE_TIMEDOUT;
|
||||
- next = ctx->next;
|
||||
-
|
||||
- ctx->handler(ctx);
|
||||
+ ctx->state = NGX_RESOLVE_TIMEDOUT;
|
||||
|
||||
- ctx = next;
|
||||
- } while (ctx);
|
||||
+ ctx->handler(ctx);
|
||||
}
|
||||
|
||||
|
||||
diff -upr nginx-1.9.7-old/src/core/ngx_resolver.h nginx-1.9.7/src/core/ngx_resolver.h
|
||||
--- nginx-1.9.7-old/src/core/ngx_resolver.h 2016-01-26 11:54:55.914404751 -0800
|
||||
+++ nginx-1.9.7/src/core/ngx_resolver.h 2016-01-26 11:55:27.068784001 -0800
|
||||
@@ -51,15 +51,11 @@ typedef void (*ngx_resolver_handler_pt)(
|
||||
|
||||
|
||||
typedef struct {
|
||||
- /* PTR: resolved name, A: name to resolve */
|
||||
- u_char *name;
|
||||
-
|
||||
+ ngx_rbtree_node_t node;
|
||||
ngx_queue_t queue;
|
||||
|
||||
- /* event ident must be after 3 pointers as in ngx_connection_t */
|
||||
- ngx_int_t ident;
|
||||
-
|
||||
- ngx_rbtree_node_t node;
|
||||
+ /* PTR: resolved name, A: name to resolve */
|
||||
+ u_char *name;
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
/* PTR: IPv6 address to resolve (IPv4 address is in rbtree node key) */
|
||||
@@ -147,6 +143,9 @@ struct ngx_resolver_ctx_s {
|
||||
ngx_resolver_t *resolver;
|
||||
ngx_udp_connection_t *udp_connection;
|
||||
|
||||
+ /* event ident must be after 3 pointers as in ngx_connection_t */
|
||||
+ ngx_int_t ident;
|
||||
+
|
||||
ngx_int_t state;
|
||||
ngx_str_t name;
|
||||
|
||||
@@ -162,6 +161,8 @@ struct ngx_resolver_ctx_s {
|
||||
ngx_uint_t quick; /* unsigned quick:1; */
|
||||
ngx_uint_t recursion;
|
||||
ngx_event_t *event;
|
||||
+
|
||||
+ ngx_resolver_node_t *node;
|
||||
};
|
||||
|
||||
|
233
patches/openssl-1.0.2h-sess_set_get_cb_yield.patch
Normal file
233
patches/openssl-1.0.2h-sess_set_get_cb_yield.patch
Normal file
@ -0,0 +1,233 @@
|
||||
diff -urp openssl-1.0.2h/ssl/s3_srvr.c openssl-1.0.2h-patched/ssl/s3_srvr.c
|
||||
--- openssl-1.0.2h/ssl/s3_srvr.c 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/s3_srvr.c 2016-07-19 19:18:03.779159083 -0700
|
||||
@@ -358,14 +358,20 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_D:
|
||||
|
||||
s->shutdown = 0;
|
||||
ret = ssl3_get_client_hello(s);
|
||||
+ if (ret == PENDING_SESSION) {
|
||||
+ s->state = SSL3_ST_SR_CLNT_HELLO_D;
|
||||
+ s->rwstate = SSL_PENDING_SESSION;
|
||||
+ goto end;
|
||||
+ }
|
||||
if (ret <= 0)
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
- s->state = SSL3_ST_SR_CLNT_HELLO_D;
|
||||
- case SSL3_ST_SR_CLNT_HELLO_D:
|
||||
+ s->state = SSL3_ST_SR_CLNT_HELLO_E;
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_E:
|
||||
{
|
||||
int al;
|
||||
if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
|
||||
@@ -925,16 +931,25 @@ int ssl3_get_client_hello(SSL *s)
|
||||
if (s->state == SSL3_ST_SR_CLNT_HELLO_A) {
|
||||
s->state = SSL3_ST_SR_CLNT_HELLO_B;
|
||||
}
|
||||
- s->first_packet = 1;
|
||||
- n = s->method->ssl_get_message(s,
|
||||
- SSL3_ST_SR_CLNT_HELLO_B,
|
||||
- SSL3_ST_SR_CLNT_HELLO_C,
|
||||
- SSL3_MT_CLIENT_HELLO,
|
||||
- SSL3_RT_MAX_PLAIN_LENGTH, &ok);
|
||||
-
|
||||
- if (!ok)
|
||||
- return ((int)n);
|
||||
- s->first_packet = 0;
|
||||
+
|
||||
+ if (s->state != SSL3_ST_SR_CLNT_HELLO_D) {
|
||||
+ s->first_packet = 1;
|
||||
+ n = s->method->ssl_get_message(s,
|
||||
+ SSL3_ST_SR_CLNT_HELLO_B,
|
||||
+ SSL3_ST_SR_CLNT_HELLO_C,
|
||||
+ SSL3_MT_CLIENT_HELLO,
|
||||
+ SSL3_RT_MAX_PLAIN_LENGTH, &ok);
|
||||
+
|
||||
+ if (!ok)
|
||||
+ return ((int)n);
|
||||
+ s->first_packet = 0;
|
||||
+ } else {
|
||||
+ /* We have previously parsed the ClientHello message, and can't
|
||||
+ * call ssl_get_message again without hashing the message into
|
||||
+ * the Finished digest again. */
|
||||
+ n = s->init_num;
|
||||
+ }
|
||||
+
|
||||
d = p = (unsigned char *)s->init_msg;
|
||||
|
||||
/*
|
||||
@@ -1041,15 +1056,26 @@ int ssl3_get_client_hello(SSL *s)
|
||||
if (i == 1 && s->version == s->session->ssl_version) { /* previous
|
||||
* session */
|
||||
s->hit = 1;
|
||||
- } else if (i == -1)
|
||||
+ } else if (i == -1) {
|
||||
+ goto err;
|
||||
+ } else if (i == PENDING_SESSION) {
|
||||
+ ret = PENDING_SESSION;
|
||||
goto err;
|
||||
- else { /* i == 0 */
|
||||
+ } else { /* i == 0 */
|
||||
|
||||
if (!ssl_get_new_session(s, 1))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Switch to server state ClientHello C once the session lookup
|
||||
+ * is finished so it can proceed with original state loop.
|
||||
+ */
|
||||
+ if (s->state == SSL3_ST_SR_CLNT_HELLO_D) {
|
||||
+ s->state = SSL3_ST_SR_CLNT_HELLO_C;
|
||||
+ }
|
||||
+
|
||||
p += j;
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
diff -urp openssl-1.0.2h/ssl/ssl3.h openssl-1.0.2h-patched/ssl/ssl3.h
|
||||
--- openssl-1.0.2h/ssl/ssl3.h 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl3.h 2016-07-19 19:15:54.117778328 -0700
|
||||
@@ -698,6 +698,7 @@ typedef struct ssl3_state_st {
|
||||
# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
|
||||
# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
|
||||
# define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT)
|
||||
+# define SSL3_ST_SR_CLNT_HELLO_E (0x116|SSL_ST_ACCEPT)
|
||||
/* write to client */
|
||||
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
|
||||
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
|
||||
diff -urp openssl-1.0.2h/ssl/ssl.h openssl-1.0.2h-patched/ssl/ssl.h
|
||||
--- openssl-1.0.2h/ssl/ssl.h 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl.h 2016-07-19 19:19:44.699562938 -0700
|
||||
@@ -1243,6 +1243,13 @@ void SSL_CTX_sess_set_get_cb(SSL_CTX *ct
|
||||
SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
|
||||
unsigned char *Data,
|
||||
int len, int *copy);
|
||||
+
|
||||
+/* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
|
||||
+ * that the session isn't currently unavailable. SSL_get_error will then return
|
||||
+ * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
|
||||
+ * lookup has completed. */
|
||||
+SSL_SESSION *SSL_magic_pending_session_ptr(void);
|
||||
+
|
||||
void SSL_CTX_set_info_callback(SSL_CTX *ctx,
|
||||
void (*cb) (const SSL *ssl, int type,
|
||||
int val));
|
||||
@@ -1408,11 +1415,14 @@ int SSL_extension_supported(unsigned int
|
||||
# define SSL_READING 3
|
||||
# define SSL_X509_LOOKUP 4
|
||||
|
||||
+# define SSL_PENDING_SESSION 7
|
||||
+
|
||||
/* These will only be used when doing non-blocking IO */
|
||||
# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
|
||||
# define SSL_want_read(s) (SSL_want(s) == SSL_READING)
|
||||
# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
|
||||
# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
|
||||
+# define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
|
||||
|
||||
# define SSL_MAC_FLAG_READ_MAC_STREAM 1
|
||||
# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
|
||||
@@ -1865,6 +1875,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
# define SSL_ERROR_ZERO_RETURN 6
|
||||
# define SSL_ERROR_WANT_CONNECT 7
|
||||
# define SSL_ERROR_WANT_ACCEPT 8
|
||||
+# define SSL_ERROR_PENDING_SESSION 11
|
||||
# define SSL_CTRL_NEED_TMP_RSA 1
|
||||
# define SSL_CTRL_SET_TMP_RSA 2
|
||||
# define SSL_CTRL_SET_TMP_DH 3
|
||||
diff -urp openssl-1.0.2h/ssl/ssl_lib.c openssl-1.0.2h-patched/ssl/ssl_lib.c
|
||||
--- openssl-1.0.2h/ssl/ssl_lib.c 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl_lib.c 2016-07-19 19:21:04.032021549 -0700
|
||||
@@ -2709,6 +2709,9 @@ int SSL_get_error(const SSL *s, int i)
|
||||
return (SSL_ERROR_SSL);
|
||||
}
|
||||
|
||||
+ if ((i < 0) && SSL_want_session(s))
|
||||
+ return (SSL_ERROR_PENDING_SESSION);
|
||||
+
|
||||
if ((i < 0) && SSL_want_read(s)) {
|
||||
bio = SSL_get_rbio(s);
|
||||
if (BIO_should_read(bio))
|
||||
diff -urp openssl-1.0.2h/ssl/ssl_locl.h openssl-1.0.2h-patched/ssl/ssl_locl.h
|
||||
--- openssl-1.0.2h/ssl/ssl_locl.h 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl_locl.h 2016-07-19 19:15:54.117778328 -0700
|
||||
@@ -518,6 +518,8 @@
|
||||
#define CERT_PRIVATE_KEY 2
|
||||
*/
|
||||
|
||||
+# define PENDING_SESSION -10000
|
||||
+
|
||||
# ifndef OPENSSL_NO_EC
|
||||
/*
|
||||
* From ECC-TLS draft, used in encoding the curve type in ECParameters
|
||||
diff -urp openssl-1.0.2h/ssl/ssl_sess.c openssl-1.0.2h-patched/ssl/ssl_sess.c
|
||||
--- openssl-1.0.2h/ssl/ssl_sess.c 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl_sess.c 2016-07-19 19:15:54.118778298 -0700
|
||||
@@ -143,10 +143,20 @@
|
||||
#endif
|
||||
#include "ssl_locl.h"
|
||||
|
||||
+/* The address of this is a magic value, a pointer to which is returned by
|
||||
+ * SSL_magic_pending_session_ptr(). It allows a session callback to indicate
|
||||
+ * that it needs to asynchronously fetch session information. */
|
||||
+static char g_pending_session_magic;
|
||||
+
|
||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
|
||||
static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
|
||||
|
||||
+SSL_SESSION *SSL_magic_pending_session_ptr()
|
||||
+{
|
||||
+ return (SSL_SESSION*) &g_pending_session_magic;
|
||||
+}
|
||||
+
|
||||
SSL_SESSION *SSL_get_session(const SSL *ssl)
|
||||
/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
|
||||
{
|
||||
@@ -626,6 +636,12 @@ int ssl_get_prev_session(SSL *s, unsigne
|
||||
int copy = 1;
|
||||
|
||||
if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) {
|
||||
+ if (ret == SSL_magic_pending_session_ptr()) {
|
||||
+ /* This is a magic value which indicates that
|
||||
+ * the callback needs to unwind the stack and
|
||||
+ * figure out the session asynchronously. */
|
||||
+ return PENDING_SESSION;
|
||||
+ }
|
||||
s->session_ctx->stats.sess_cb_hit++;
|
||||
|
||||
/*
|
||||
diff -urp openssl-1.0.2h/ssl/ssl_stat.c openssl-1.0.2h-patched/ssl/ssl_stat.c
|
||||
--- openssl-1.0.2h/ssl/ssl_stat.c 2016-05-03 06:44:42.000000000 -0700
|
||||
+++ openssl-1.0.2h-patched/ssl/ssl_stat.c 2016-07-19 19:15:54.118778298 -0700
|
||||
@@ -353,6 +353,12 @@ const char *SSL_state_string_long(const
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
str = "SSLv3 read client hello C";
|
||||
break;
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_D:
|
||||
+ str = "SSLv3 read client hello D";
|
||||
+ break;
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_E:
|
||||
+ str = "SSLv3 read client hello E";
|
||||
+ break;
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
str = "SSLv3 write hello request A";
|
||||
break;
|
||||
@@ -737,6 +743,12 @@ const char *SSL_state_string(const SSL *
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
str = "3RCH_C";
|
||||
break;
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_D:
|
||||
+ str = "3RCH_D";
|
||||
+ break;
|
||||
+ case SSL3_ST_SR_CLNT_HELLO_E:
|
||||
+ str = "3RCH_E";
|
||||
+ break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
str = "3WSH_A";
|
||||
break;
|
14
patches/patch.2016.write.txt
Normal file
14
patches/patch.2016.write.txt
Normal file
@ -0,0 +1,14 @@
|
||||
--- src/os/unix/ngx_files.c
|
||||
+++ src/os/unix/ngx_files.c
|
||||
@@ -356,6 +356,11 @@
|
||||
n = 0;
|
||||
|
||||
for ( /* void */ ; cl; cl = cl->next) {
|
||||
+
|
||||
+ if (ngx_buf_special(cl->buf)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
size = cl->buf->last - cl->buf->pos;
|
||||
|
||||
if (prev == cl->buf->pos) {
|
15
patches/patch.2016.write2.txt
Normal file
15
patches/patch.2016.write2.txt
Normal file
@ -0,0 +1,15 @@
|
||||
--- src/os/unix/ngx_files.c
|
||||
+++ src/os/unix/ngx_files.c
|
||||
@@ -183,6 +183,12 @@ ngx_write_chain_to_file(ngx_file_t *file
|
||||
/* create the iovec and coalesce the neighbouring bufs */
|
||||
|
||||
while (cl && vec.nelts < IOV_MAX) {
|
||||
+
|
||||
+ if (ngx_buf_special(cl->buf)) {
|
||||
+ cl = cl->next;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (prev == cl->buf->pos) {
|
||||
iov->iov_len += cl->buf->last - cl->buf->pos;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
%define dir_name openresty
|
||||
|
||||
Name: ngx_openresty
|
||||
Name: openresty
|
||||
|
||||
Version: 1.0.5.1
|
||||
Release: 5
|
||||
@ -14,7 +14,7 @@ Group: Productivity/Networking/Web/Servers
|
||||
License: BSD
|
||||
URL: http://www.openresty.org/
|
||||
|
||||
Source0: ngx_openresty-%{version}rc%{release}.tar.gz
|
||||
Source0: openresty-%{version}rc%{release}.tar.gz
|
||||
|
||||
BuildRoot: %{build_root}
|
||||
|
||||
@ -23,11 +23,11 @@ BuildRequires: gcc >= 3.0, openssl-devel, pcre-devel, readline-devel
|
||||
Requires: openssl, pcre, readline
|
||||
|
||||
%description
|
||||
OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard Nginx core, lots of 3rd-party Nginx modules, as well as most of their external dependencie
|
||||
OpenResty is a full-fledged web application server by bundling the standard Nginx core, lots of 3rd-party Nginx modules, as well as most of their external dependencie
|
||||
|
||||
%prep
|
||||
#%setup -q -n ngx_openresty-%{version}
|
||||
%setup -q -n ngx_openresty-%{version}rc%{release}
|
||||
#%setup -q -n openresty-%{version}
|
||||
%setup -q -n openresty-%{version}rc%{release}
|
||||
|
||||
%build
|
||||
#--with-pg_config=opt/pg90/bin/pg_config \
|
@ -23,7 +23,7 @@ sub run_tests {
|
||||
my $ver = `bash util/ver`;
|
||||
chomp $ver;
|
||||
|
||||
cd "ngx_openresty-$ver";
|
||||
cd "openresty-$ver";
|
||||
|
||||
$DistRoot = cwd();
|
||||
$BuildRoot = File::Spec->rel2abs("./build");
|
||||
|
3540
t/sanity.t
3540
t/sanity.t
File diff suppressed because it is too large
Load Diff
@ -1,36 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
PCRE=pcre-8.38
|
||||
PCRE=pcre-8.39
|
||||
ZLIB=zlib-1.2.8
|
||||
OPENSSL=openssl-1.0.2e
|
||||
OPENSSL=openssl-1.0.2j
|
||||
|
||||
rm -rf objs || exit 1
|
||||
mkdir -p objs/lib || exit 1
|
||||
cd objs/lib || exit 1
|
||||
ls ../../..
|
||||
tar -xf ../../../$OPENSSL.tar.gz
|
||||
tar -xf ../../../$ZLIB.tar.gz
|
||||
tar -xf ../../../$PCRE.tar.gz
|
||||
tar -xf ../../../$OPENSSL.tar.gz || exit 1
|
||||
tar -xf ../../../$ZLIB.tar.gz || exit 1
|
||||
tar -xf ../../../$PCRE.tar.gz || exit 1
|
||||
cd ../..
|
||||
|
||||
cd objs/lib/$OPENSSL || exit 1
|
||||
patch -p1 < ../../../patches/openssl-1.0.2h-sess_set_get_cb_yield.patch || exit 1
|
||||
cd ../../..
|
||||
|
||||
#--with-openssl-opt="no-asm" \
|
||||
|
||||
./configure --with-cc=gcc --with-ipv6 --prefix= \
|
||||
./configure \
|
||||
--with-cc=gcc \
|
||||
--with-ipv6 \
|
||||
--prefix= \
|
||||
--with-cc-opt='-DFD_SETSIZE=1024' \
|
||||
--sbin-path=nginx.exe \
|
||||
--with-ipv6 \
|
||||
--with-pcre-jit \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_realip_module \
|
||||
--without-http_rds_json_module \
|
||||
--without-http_rds_csv_module \
|
||||
--without-lua_rds_parser \
|
||||
--with-ipv6 \
|
||||
--with-stream \
|
||||
--with-stream_ssl_module \
|
||||
--with-http_v2_module \
|
||||
--without-mail_pop3_module \
|
||||
--without-mail_imap_module \
|
||||
--without-mail_smtp_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_realip_module \
|
||||
--with-http_addition_module \
|
||||
--with-http_auth_request_module \
|
||||
--with-http_secure_link_module \
|
||||
--with-http_random_index_module \
|
||||
--with-http_gzip_static_module \
|
||||
--with-http_sub_module \
|
||||
--with-http_dav_module \
|
||||
--with-http_flv_module \
|
||||
--with-http_mp4_module \
|
||||
--with-http_gunzip_module \
|
||||
--with-select_module \
|
||||
--with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
|
||||
--with-pcre=objs/lib/$PCRE \
|
||||
--with-zlib=objs/lib/$ZLIB \
|
||||
--with-openssl=objs/lib/$OPENSSL \
|
||||
--with-select_module -j5 || exit 1
|
||||
-j5 || exit 1
|
||||
#gmake -j5
|
||||
make || exit 1
|
||||
make install
|
||||
|
171
util/configure
vendored
171
util/configure
vendored
@ -127,6 +127,7 @@ my @ngx_rpaths;
|
||||
my $cc;
|
||||
my $cores;
|
||||
my $luajit_xcflags = '';
|
||||
my $no_luajit_lua52;
|
||||
|
||||
my (@ngx_opts, @ngx_cc_opts, @ngx_ld_opts);
|
||||
|
||||
@ -144,7 +145,7 @@ for my $opt (@ARGV) {
|
||||
|
||||
if ($opt =~ /^--with-cc=(.+)/) {
|
||||
$cc = $1;
|
||||
push @ngx_opts, "'$opt'";
|
||||
push @ngx_opts, "$opt";
|
||||
next;
|
||||
}
|
||||
|
||||
@ -203,6 +204,9 @@ for my $opt (@ARGV) {
|
||||
} elsif ($opt eq '--without-lua_resty_string') {
|
||||
$resty_opts{no_lua_resty_string} = 1;
|
||||
|
||||
} elsif ($opt eq '--without-lua_resty_limit_traffic') {
|
||||
$resty_opts{no_lua_resty_limit_traffic} = 1;
|
||||
|
||||
} elsif ($opt eq '--without-lua_resty_websocket') {
|
||||
$resty_opts{no_lua_resty_websocket} = 1;
|
||||
|
||||
@ -252,6 +256,9 @@ for my $opt (@ARGV) {
|
||||
} elsif ($opt =~ /^--with-luajit-xcflags=(.*)/) {
|
||||
$luajit_xcflags .= " $1";
|
||||
|
||||
} elsif ($opt =~ /^--without-luajit-lua52/) {
|
||||
$no_luajit_lua52 = 1;
|
||||
|
||||
} elsif ($opt =~ /^--with-libdrizzle=(.*)/) {
|
||||
$resty_opts{libdrizzle} = $1;
|
||||
|
||||
@ -278,6 +285,7 @@ for my $opt (@ARGV) {
|
||||
|
||||
} elsif ($opt eq '--without-http_ssl_module') {
|
||||
$resty_opts{no_http_ssl} = 1;
|
||||
$resty_opts{no_http_encrypted_session} = 1;
|
||||
|
||||
} elsif ($opt =~ /^--add-module=(.*)/) {
|
||||
|
||||
@ -329,7 +337,7 @@ if (@ngx_ld_opts) {
|
||||
my $cmd = "sh ./configure --prefix=$ngx_prefix"
|
||||
. $resty_opts
|
||||
. $ld_opts
|
||||
. (@ngx_opts ? " \\\n @ngx_opts" : "");
|
||||
. (@ngx_opts ? " \\\n " . quote_cli_args(\@ngx_opts) : "");
|
||||
;
|
||||
|
||||
shell $cmd, $dry_run;
|
||||
@ -340,6 +348,15 @@ push @make_cmds, "cd $root_dir/build/$ngx_dir && "
|
||||
push @make_install_cmds, "cd $root_dir/build/$ngx_dir && "
|
||||
. "\$(MAKE) install DESTDIR=\$(DESTDIR)";
|
||||
|
||||
push @make_install_cmds,
|
||||
"mkdir -p \$(DESTDIR)$prefix/site/lualib"
|
||||
. " \$(DESTDIR)$prefix/site/pod"
|
||||
. " \$(DESTDIR)$prefix/site/manifest";
|
||||
|
||||
if ($platform ne 'msys') {
|
||||
push @make_install_cmds, "ln -sf $ngx_prefix/sbin/nginx \$(DESTDIR)$prefix/bin/openresty";
|
||||
}
|
||||
|
||||
cd '../..'; # to the root
|
||||
#die "pwd: " .. `pwd`;
|
||||
|
||||
@ -594,6 +611,12 @@ _END_
|
||||
}
|
||||
}
|
||||
|
||||
if (!$no_luajit_lua52
|
||||
&& (!$luajit_xcflags || $luajit_xcflags !~ /-DLUAJIT_ENABLE_LUA52COMPAT\b/))
|
||||
{
|
||||
$luajit_xcflags .= " -DLUAJIT_ENABLE_LUA52COMPAT";
|
||||
}
|
||||
|
||||
if ($opts->{debug}) {
|
||||
$luajit_xcflags .= " -DLUA_USE_APICHECK -DLUA_USE_ASSERT";
|
||||
$luajit_xcflags =~ s/^ +//;
|
||||
@ -748,6 +771,7 @@ _END_
|
||||
# build lua modules
|
||||
|
||||
my $lualib_prefix = File::Spec->catfile($prefix, "lualib");
|
||||
my $site_lualib_prefix = File::Spec->catfile($prefix, "site/lualib");
|
||||
|
||||
my $ngx_lua_dir = auto_complete 'ngx_lua';
|
||||
|
||||
@ -755,20 +779,11 @@ _END_
|
||||
die "Cannot open $ngx_lua_dir/config for appending: $!\n";
|
||||
|
||||
{
|
||||
my $path_prefix = $lualib_prefix;
|
||||
|
||||
#if (File::Spec->rel2abs($lualib_prefix) ne File::Spec->canonpath($lualib_prefix)
|
||||
#&& $platform eq 'msys')
|
||||
#{
|
||||
# being a relative path and on MSYS
|
||||
#$path_prefix = "!/$lualib_prefix";
|
||||
#}
|
||||
|
||||
print $in <<"_EOC_";
|
||||
|
||||
ngx_lua_dquote='"'
|
||||
CFLAGS="\$CFLAGS -DLUA_DEFAULT_PATH='\$ngx_lua_dquote$path_prefix/?.lua;$path_prefix/?/init.lua\$ngx_lua_dquote'"
|
||||
CFLAGS="\$CFLAGS -DLUA_DEFAULT_CPATH='\$ngx_lua_dquote$path_prefix/?.so\$ngx_lua_dquote'"
|
||||
CFLAGS="\$CFLAGS -DLUA_DEFAULT_PATH='\${ngx_lua_dquote}$site_lualib_prefix/?.lua;$site_lualib_prefix/?/init.lua;$lualib_prefix/?.lua;$lualib_prefix/?/init.lua\$ngx_lua_dquote'"
|
||||
CFLAGS="\$CFLAGS -DLUA_DEFAULT_CPATH='\${ngx_lua_dquote}$site_lualib_prefix/?.so;$lualib_prefix/?.so\$ngx_lua_dquote'"
|
||||
_EOC_
|
||||
}
|
||||
|
||||
@ -934,7 +949,7 @@ _EOC_
|
||||
}
|
||||
|
||||
for my $key (qw(dns memcached redis mysql string upload websocket
|
||||
lock lrucache core upstream_healthcheck))
|
||||
lock lrucache core upstream_healthcheck limit_traffic))
|
||||
{
|
||||
unless ($opts->{"no_lua_resty_$key"}) {
|
||||
(my $key2 = $key) =~ s/_/-/g;
|
||||
@ -953,6 +968,19 @@ _EOC_
|
||||
}
|
||||
}
|
||||
|
||||
# configure opm:
|
||||
{
|
||||
my $opm_dir = auto_complete 'opm';
|
||||
my $target_dir;
|
||||
if ($platform eq 'msys') {
|
||||
$target_dir = "\$(DESTDIR)$prefix/";
|
||||
} else {
|
||||
$target_dir = "\$(DESTDIR)$prefix/bin/";
|
||||
}
|
||||
push @make_install_cmds, "cd $root_dir/build/$opm_dir && "
|
||||
. "$root_dir/build/install bin/* $target_dir";
|
||||
}
|
||||
|
||||
# configure resty-cli:
|
||||
|
||||
{
|
||||
@ -964,9 +992,14 @@ _EOC_
|
||||
$target_dir = "\$(DESTDIR)$prefix/bin/";
|
||||
}
|
||||
push @make_install_cmds, "cd $root_dir/build/$resty_cli_dir && "
|
||||
. "$root_dir/build/install resty $target_dir";
|
||||
. "$root_dir/build/install bin/* $target_dir";
|
||||
}
|
||||
|
||||
# configure restydoc indexes
|
||||
|
||||
push @make_install_cmds, "cp $root_dir/build/resty.index \$(DESTDIR)$prefix/",
|
||||
"cp -r $root_dir/build/pod \$(DESTDIR)$prefix/";
|
||||
|
||||
# prepare nginx configure line
|
||||
|
||||
$ngx_dir = auto_complete "nginx";
|
||||
@ -1077,6 +1110,7 @@ _EOC_
|
||||
disable the lua-resty-upstream-healthcheck library
|
||||
--without-lua_resty_string disable the lua-resty-string library
|
||||
--without-lua_resty_websocket disable the lua-resty-websocket library
|
||||
--without-lua_resty_limit_traffic disable the lua-resty-limit-traffic library
|
||||
--without-lua_resty_lock disable the lua-resty-lock library
|
||||
--without-lua_resty_lrucache disable the lua-resty-lrucache library
|
||||
--without-lua_resty_core disable the lua-resty-core library
|
||||
@ -1084,9 +1118,13 @@ _EOC_
|
||||
--with-lua51 enable and build the bundled standard Lua 5.1 interpreter
|
||||
--without-lua51 disable the bundled standard Lua 5.1 interpreter
|
||||
--with-lua51=DIR specify the external installation of Lua 5.1 by DIR
|
||||
|
||||
--with-luajit enable and build the bundled LuaJIT 2.1 (the default)
|
||||
--with-luajit=DIR use the external LuaJIT 2.1 installation specified by DIR
|
||||
--with-luajit-xcflags=FLAGS Specify extra C compiler flags for LuaJIT 2.1
|
||||
--without-luajit-lua52 Turns off the LuaJIT extensions from Lua 5.2 that may break
|
||||
backward compatibility.
|
||||
|
||||
--with-libdrizzle=DIR specify the libdrizzle 1.0 (or drizzle) installation prefix
|
||||
--with-libpq=DIR specify the libpq (or postgresql) installation prefix
|
||||
--with-pg_config=PATH specify the path of the pg_config utility
|
||||
@ -1094,6 +1132,7 @@ _EOC_
|
||||
Options directly inherited from nginx
|
||||
|
||||
--sbin-path=PATH set nginx binary pathname
|
||||
--modules-path=PATH set modules path
|
||||
--conf-path=PATH set nginx.conf pathname
|
||||
--error-log-path=PATH set error log pathname
|
||||
--pid-path=PATH set nginx.pid pathname
|
||||
@ -1106,6 +1145,7 @@ Options directly inherited from nginx
|
||||
--group=GROUP set non-privileged group for
|
||||
worker processes
|
||||
|
||||
--build=NAME set build name
|
||||
--builddir=DIR set the build directory
|
||||
|
||||
--with-select_module enable select module
|
||||
@ -1115,22 +1155,30 @@ Options directly inherited from nginx
|
||||
|
||||
--with-threads enable thread pool support
|
||||
|
||||
--with-file-aio enable file aio support
|
||||
--with-ipv6 enable ipv6 support
|
||||
--with-file-aio enable file AIO support
|
||||
--with-ipv6 enable IPv6 support
|
||||
|
||||
--with-http_v2_module enable ngx_http_v2_module
|
||||
--with-http_realip_module enable ngx_http_realip_module
|
||||
--with-http_addition_module enable ngx_http_addition_module
|
||||
--with-http_xslt_module enable ngx_http_xslt_module
|
||||
--with-http_xslt_module=dynamic enable dynamic ngx_http_xslt_module
|
||||
--with-http_image_filter_module enable ngx_http_image_filter_module
|
||||
--with-http_image_filter_module=dynamic
|
||||
enable dynamic ngx_http_image_filter_module
|
||||
--with-http_geoip_module enable ngx_http_geoip_module
|
||||
--with-http_geoip_module=dynamic enable dynamic ngx_http_geoip_module
|
||||
--with-http_sub_module enable ngx_http_sub_module
|
||||
--with-http_dav_module enable ngx_http_dav_module
|
||||
--with-http_flv_module enable ngx_http_flv_module
|
||||
--with-http_mp4_module enable ngx_http_mp4_module
|
||||
--with-http_gunzip_module enable ngx_http_gunzip_module
|
||||
--with-http_gzip_static_module enable ngx_http_gzip_static_module
|
||||
--with-http_auth_request_module enable ngx_http_auth_request_module
|
||||
--with-http_random_index_module enable ngx_http_random_index_module
|
||||
--with-http_secure_link_module enable ngx_http_secure_link_module
|
||||
--with-http_degradation_module enable ngx_http_degradation_module
|
||||
--with-http_slice_module enable ngx_http_slice_module
|
||||
--with-http_stub_status_module enable ngx_http_stub_status_module
|
||||
|
||||
--without-http_charset_module disable ngx_http_charset_module
|
||||
@ -1154,6 +1202,8 @@ Options directly inherited from nginx
|
||||
--without-http_limit_req_module disable ngx_http_limit_req_module
|
||||
--without-http_empty_gif_module disable ngx_http_empty_gif_module
|
||||
--without-http_browser_module disable ngx_http_browser_module
|
||||
--without-http_upstream_hash_module
|
||||
disable ngx_http_upstream_hash_module
|
||||
--without-http_upstream_ip_hash_module
|
||||
disable ngx_http_upstream_ip_hash_module
|
||||
--without-http_upstream_least_conn_module
|
||||
@ -1161,43 +1211,63 @@ Options directly inherited from nginx
|
||||
--without-http_upstream_keepalive_module
|
||||
disable ngx_http_upstream_keepalive_module
|
||||
|
||||
--without-http_upstream_zone_module
|
||||
disable ngx_http_upstream_zone_module
|
||||
--with-http_perl_module enable ngx_http_perl_module
|
||||
--with-perl_modules_path=PATH set path to the perl modules
|
||||
--with-perl=PATH set path to the perl binary
|
||||
--with-http_perl_module=dynamic enable dynamic ngx_http_perl_module
|
||||
--with-perl_modules_path=PATH set Perl modules path
|
||||
--with-perl=PATH set perl binary pathname
|
||||
|
||||
--http-log-path=PATH set path to the http access log
|
||||
--http-client-body-temp-path=PATH set path to the http client request body
|
||||
temporary files
|
||||
--http-proxy-temp-path=PATH set path to the http proxy temporary files
|
||||
--http-fastcgi-temp-path=PATH set path to the http fastcgi temporary
|
||||
files
|
||||
--http-uwsgi-temp-path=PATH set path to the http uwsgi temporary files
|
||||
--http-scgi-temp-path=PATH set path to the http scgi temporary files
|
||||
--http-log-path=PATH set http access log pathname
|
||||
--http-client-body-temp-path=PATH set path to store
|
||||
http client request body temporary files
|
||||
--http-proxy-temp-path=PATH set path to store
|
||||
http proxy temporary files
|
||||
--http-fastcgi-temp-path=PATH set path to store
|
||||
http fastcgi temporary files
|
||||
--http-uwsgi-temp-path=PATH set path to store
|
||||
http uwsgi temporary files
|
||||
--http-scgi-temp-path=PATH set path to store
|
||||
http scgi temporary files
|
||||
|
||||
--without-http disable HTTP server
|
||||
--without-http-cache disable HTTP cache
|
||||
|
||||
--with-mail enable POP3/IMAP4/SMTP proxy module
|
||||
--with-mail=dynamic enable dynamic POP3/IMAP4/SMTP proxy module
|
||||
--with-mail_ssl_module enable ngx_mail_ssl_module
|
||||
--without-mail_pop3_module disable ngx_mail_pop3_module
|
||||
--without-mail_imap_module disable ngx_mail_imap_module
|
||||
--without-mail_smtp_module disable ngx_mail_smtp_module
|
||||
|
||||
--with-stream enable TCP/UDP proxy module
|
||||
--with-stream=dynamic enable dynamic TCP/UDP proxy module
|
||||
--with-stream_ssl_module enable ngx_stream_ssl_module
|
||||
--without-stream_limit_conn_module disable ngx_stream_limit_conn_module
|
||||
--without-stream_access_module disable ngx_stream_access_module
|
||||
--without-stream_map_module disable ngx_stream_map_module
|
||||
--without-stream_return_module disable ngx_stream_return_module
|
||||
--without-stream_upstream_hash_module
|
||||
disable ngx_stream_upstream_hash_module
|
||||
--without-stream_upstream_least_conn_module
|
||||
disable ngx_stream_upstream_least_conn_module
|
||||
--without-stream_upstream_zone_module
|
||||
disable ngx_stream_upstream_zone_module
|
||||
|
||||
--with-google_perftools_module enable ngx_google_perftools_module
|
||||
--with-cpp_test_module enable ngx_cpp_test_module
|
||||
|
||||
--add-module=PATH enable an external module
|
||||
--add-module=PATH enable external module
|
||||
--add-dynamic-module=PATH enable dynamic external module
|
||||
|
||||
--with-cc=PATH set path to C compiler
|
||||
--with-cpp=PATH set path to C preprocessor
|
||||
--with-cc-opt=OPTIONS set additional options for C compiler
|
||||
--with-ld-opt=OPTIONS set additional options for linker
|
||||
--with-cpu-opt=CPU build for specified CPU, the valid values:
|
||||
--with-cc=PATH set C compiler pathname
|
||||
--with-cpp=PATH set C preprocessor pathname
|
||||
--with-cc-opt=OPTIONS set additional C compiler options
|
||||
--with-ld-opt=OPTIONS set additional linker options
|
||||
--with-cpu-opt=CPU build for the specified CPU, valid values:
|
||||
pentium, pentiumpro, pentium3, pentium4,
|
||||
athlon, opteron, sparc32, sparc64, ppc64
|
||||
|
||||
--with-make=PATH specify the default make utility to be used
|
||||
|
||||
--without-pcre disable PCRE library usage
|
||||
--with-pcre force PCRE library usage
|
||||
--with-pcre=DIR set path to PCRE library sources
|
||||
@ -1205,25 +1275,17 @@ Options directly inherited from nginx
|
||||
--with-pcre-conf-opt=OPTIONS set additional configure options for PCRE
|
||||
--with-pcre-jit build PCRE with JIT compilation support
|
||||
|
||||
--with-md5=DIR set path to md5 library sources
|
||||
--with-md5-opt=OPTIONS set additional options for md5 building
|
||||
--with-md5-asm use md5 assembler sources
|
||||
|
||||
--with-sha1=DIR set path to sha1 library sources
|
||||
--with-sha1-opt=OPTIONS set additional options for sha1 building
|
||||
--with-sha1-asm use sha1 assembler sources
|
||||
|
||||
--with-zlib=DIR set path to zlib library sources
|
||||
--with-zlib-opt=OPTIONS set additional options for zlib building
|
||||
--with-zlib-opt=OPTIONS set additional build options for zlib
|
||||
--with-zlib-asm=CPU use zlib assembler sources optimized
|
||||
for specified CPU, the valid values:
|
||||
for the specified CPU, valid values:
|
||||
pentium, pentiumpro
|
||||
|
||||
--with-libatomic force libatomic_ops library usage
|
||||
--with-libatomic=DIR set path to libatomic_ops library sources
|
||||
|
||||
--with-openssl=DIR set path to OpenSSL library sources
|
||||
--with-openssl-opt=OPTIONS set additional options for OpenSSL building
|
||||
--with-openssl-opt=OPTIONS set additional build options for OpenSSL
|
||||
|
||||
--dry-run dry running the configure, for testing only
|
||||
--platform=PLATFORM forcibly specify a platform name, for testing only
|
||||
@ -1284,3 +1346,20 @@ sub can_run {
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub quote_cli_args {
|
||||
my $args = shift;
|
||||
my @quoted;
|
||||
for my $arg (@$args) {
|
||||
if ($arg =~ /[\\\s'"\$]/) {
|
||||
if ($arg =~ /'/) {
|
||||
$arg =~ s/([\\'])/\\$1/g;
|
||||
push @quoted, "\$'$arg'";
|
||||
} else {
|
||||
push @quoted, "'$arg'";
|
||||
}
|
||||
} else {
|
||||
push @quoted, $arg;
|
||||
}
|
||||
}
|
||||
join " ", @quoted;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use Getopt::Std qw(getopts);
|
||||
use Cwd qw/cwd/;
|
||||
|
||||
sub sh ($);
|
||||
sub cleanup ();
|
||||
sub write_config_file ($);
|
||||
|
||||
my %opts;
|
||||
@ -15,7 +16,7 @@ getopts("lf:", \%opts) or die "Usage: $0 [-f] [-l] <cores>\n";
|
||||
my $jobs = shift || 4;
|
||||
|
||||
my $cwd = cwd();
|
||||
if ($cwd !~ /ngx_openresty-(\d+(?:\.\d+)+(?:rc\d+(?:\.\d+)?)?)$/) {
|
||||
if ($cwd !~ /openresty-(\d+(?:\.\d+)+(?:rc\d+(?:\.\d+)?)?)$/) {
|
||||
die "Bad current working directory: $cwd\n";
|
||||
}
|
||||
|
||||
@ -67,9 +68,27 @@ sub write_config_file ($) {
|
||||
|
||||
write_config_file "/tmp/nginx.conf";
|
||||
|
||||
warn "=== Without FFI ===\n";
|
||||
$prefix = "/usr/local/openresty-noffi";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --with-cc-opt='-DNGX_LUA_NO_FFI_API' --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
sh "$make -j$jobs > /dev/null";
|
||||
sh "sudo $make install > /dev/null";
|
||||
sh "sudo cp /tmp/nginx.conf $prefix/nginx/conf/nginx.conf";
|
||||
sh "$prefix/nginx/sbin/nginx -V 2>&1 |grep $ver";
|
||||
system "sudo killall nginx > /dev/null 2>&1";
|
||||
sh "sudo $prefix/nginx/sbin/nginx";
|
||||
sh "curl -si localhost/lua|grep $lua";
|
||||
sh "curl -si localhost/lua|grep $ver";
|
||||
sh "curl -si localhost/cjson|grep 'json.safe: '";
|
||||
sh qq{$prefix/bin/resty -e 'ngx.say("Hello World!")'|grep 'Hello World'};
|
||||
sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "=== --with-stream ===\n";
|
||||
$prefix = "/usr/local/openresty-nogzip";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
$prefix = "/usr/local/openresty-stream";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --with-stream --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -87,8 +106,8 @@ sh qq{$prefix/bin/resty -e 'ngx.say("Hello World!")'|grep 'Hello World'};
|
||||
sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "=== --with-stream + dtrace static probes ===\n";
|
||||
$prefix = "/usr/local/openresty-nogzip";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
$prefix = "/usr/local/openresty-stream-usdt";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --with-dtrace-probes --with-stream --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -108,7 +127,7 @@ sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "=== Without Gzip/SSL/PCRE ===\n";
|
||||
$prefix = "/usr/local/openresty-nogzip";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --without-http_rewrite_module --without-http_ssl_module --without-pcre --without-http_gzip_module --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -131,7 +150,7 @@ $cfg_opts .= " --with-http_iconv_module";
|
||||
|
||||
warn "\n=== --with-threads ===\n";
|
||||
$prefix = "/usr/local/openresty-threads";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --with-threads --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -150,7 +169,7 @@ sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "\n=== No Pool Build ===\n";
|
||||
$prefix = "/usr/local/openresty-nopool";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure --with-no-pool-patch $cfg_opts --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -170,7 +189,7 @@ sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "\n=== Normal Build ===\n";
|
||||
$prefix = "/usr/local/openresty";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts -j$jobs > /dev/null";
|
||||
}
|
||||
@ -184,11 +203,13 @@ sh "curl -si localhost/lua|grep $lua";
|
||||
sh "curl -si localhost/lua|grep $ver";
|
||||
sh "curl -si localhost/cjson|grep 'json.safe: '";
|
||||
sh qq{$prefix/bin/resty -e 'ngx.say("Hello World!")'|grep 'Hello World'};
|
||||
sh qq{$prefix/bin/restydoc -s listen | grep 'configures the port to accept HTTP/2'};
|
||||
sh qq{$prefix/bin/restydoc opm | grep -E '^Status\$'};
|
||||
sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "\n=== Debug Build ===\n";
|
||||
$prefix = "/usr/local/openresty-debug";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
my $more_cfg_opts = '';
|
||||
if ($lua eq 'LuaJIT') {
|
||||
@ -211,7 +232,7 @@ sh "sudo $prefix/nginx/sbin/nginx -sstop";
|
||||
|
||||
warn "\n=== DTrace Build ===\n";
|
||||
$prefix = "/usr/local/openresty-dtrace";
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html";
|
||||
cleanup();
|
||||
unless ($opts{f}) {
|
||||
sh "./configure $cfg_opts --with-dtrace-probes --prefix=$prefix -j$jobs > /dev/null";
|
||||
}
|
||||
@ -240,6 +261,11 @@ sub sh ($) {
|
||||
system($cmd) == 0 or die "Command \"$cmd\" failed";
|
||||
}
|
||||
|
||||
sub cleanup () {
|
||||
sh "sudo rm -rf $prefix/lualib $prefix/luajit $prefix/bin $prefix/lua $prefix/nginx/sbin $prefix/nginx/html"
|
||||
. " $prefix/site $prefix/pod $prefix/resty.index";
|
||||
}
|
||||
|
||||
__DATA__
|
||||
|
||||
user nobody;
|
||||
|
@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $indented;
|
||||
while (<>) {
|
||||
if (/^ \S/) {
|
||||
$indented = 1;
|
||||
print;
|
||||
next;
|
||||
}
|
||||
if ($indented) {
|
||||
if (/^[^-\#=\s]/) {
|
||||
print "\n";
|
||||
}
|
||||
undef $indented;
|
||||
}
|
||||
print;
|
||||
}
|
@ -8,7 +8,7 @@ sub cd ($);
|
||||
my $ver = `bash util/ver`;
|
||||
chomp $ver;
|
||||
|
||||
cd "ngx_openresty-$ver/bundle";
|
||||
cd "openresty-$ver/bundle";
|
||||
|
||||
opendir(my $dh, '.') or
|
||||
die "cannot opendir .: $!";
|
||||
@ -45,7 +45,7 @@ for my $t_file (@t_files) {
|
||||
warn "\n- $orig";
|
||||
warn "+ $_";
|
||||
|
||||
} elsif (s{ngx_openresty-\d+\.\d+\.\d+\.\d+(?:rc\d+)?}{ngx_openresty-$ver} && $orig ne $_) {
|
||||
} elsif (s{openresty-\d+\.\d+\.\d+\.\d+(?:rc\d+)?}{openresty-$ver} && $orig ne $_) {
|
||||
$changed++;
|
||||
|
||||
warn "\n- $orig";
|
||||
|
@ -14,7 +14,7 @@ cachefile=$work/$outfile
|
||||
if [ -s $cachefile ]; then
|
||||
cp $work/$outfile $outfile || exit 1
|
||||
else
|
||||
wget --no-check-certificate $1 -O $3 || exit 1
|
||||
wget $1 -O $3 || exit 1
|
||||
if [ $? == 0 ]; then
|
||||
cp $3 $work/ || exit 1
|
||||
fi
|
||||
|
@ -5,11 +5,11 @@ root=`perl -MCwd -e'print Cwd::abs_path(shift)' $(dirname -- "$0")/..`
|
||||
|
||||
info_txt=`perl -e 'print "\033[33m[INFO]\033[0m"'`
|
||||
|
||||
echo -n "ngx_openresty "
|
||||
echo -n "openresty "
|
||||
. ./util/ver
|
||||
echo
|
||||
|
||||
name=ngx_openresty-$version
|
||||
name=openresty-$version
|
||||
work=$root/work
|
||||
|
||||
if [ -z $debug ]; then
|
||||
@ -17,6 +17,8 @@ if [ -z $debug ]; then
|
||||
mkdir -p $name/bundle || exit 1
|
||||
fi
|
||||
|
||||
bundle_dir=$root/$name/bundle
|
||||
|
||||
cd $name/bundle || exit 1
|
||||
|
||||
if [ ! -d $work ]; then
|
||||
@ -26,7 +28,7 @@ fi
|
||||
#################################
|
||||
|
||||
ver="$main_ver"
|
||||
$root/util/get-tarball "http://openresty.org/download/nginx-$ver.tar.gz" -O nginx-$ver.tar.gz || exit 1
|
||||
$root/util/get-tarball "https://openresty.org/download/nginx-$ver.tar.gz" -O nginx-$ver.tar.gz || exit 1
|
||||
tar -xzf nginx-$ver.tar.gz || exit 1
|
||||
cd nginx-$ver || exit 1
|
||||
|
||||
@ -39,6 +41,20 @@ if [ "$answer" = "N" ]; then
|
||||
echo
|
||||
fi
|
||||
|
||||
answer=`$root/util/ver-ge "$main_ver" 1.9.12`
|
||||
if [ "$answer" = "N" ]; then
|
||||
echo "$info_txt applying the patch for nginx security advisory (CVE-2016-4450)"
|
||||
patch -p0 < $root/patches/patch.2016.write2.txt || exit 1
|
||||
echo
|
||||
else
|
||||
answer=`$root/util/ver-ge "$main_ver" 1.10.1`
|
||||
if [ "$answer" = "N" ]; then
|
||||
echo "$info_txt applying the patch for nginx security advisory (CVE-2016-4450)"
|
||||
patch -p0 < $root/patches/patch.2016.write.txt || exit 1
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$info_txt applying the upstream-pipelining patch for nginx"
|
||||
patch -p1 < $root/patches/nginx-$main_ver-upstream_pipelining.patch || exit 1
|
||||
echo
|
||||
@ -293,6 +309,12 @@ if [ "$answer" = "N" ]; then
|
||||
echo
|
||||
fi
|
||||
|
||||
if [ "$main_ver" = "1.9.7" ]; then
|
||||
echo "$info_txt applying the resolver_security_fixes patch for nginx"
|
||||
patch -p1 < $root/patches/nginx-$main_ver-resolver_security_fixes.patch || exit 1
|
||||
echo
|
||||
fi
|
||||
|
||||
rm -f *.patch || exit 1
|
||||
|
||||
echo "$info_txt applying the always_enable_cc_feature_tests patch to nginx"
|
||||
@ -303,6 +325,17 @@ echo "$info_txt applying the ssl_cert_cb_yield.patch patch to nginx"
|
||||
patch -p1 < $root/patches/nginx-$main_ver-ssl_cert_cb_yield.patch
|
||||
echo
|
||||
|
||||
echo "$info_txt applying the ssl_pending_session.patch patch to nginx"
|
||||
patch -p1 < $root/patches/nginx-$main_ver-ssl_pending_session.patch
|
||||
echo
|
||||
|
||||
echo "$info_txt applying the upstream_timeout_fields patch for nginx"
|
||||
patch -p1 < $root/patches/nginx-$main_ver-upstream_timeout_fields.patch || exit 1
|
||||
echo
|
||||
|
||||
cp $root/html/index.html docs/html/ || exit 1
|
||||
cp $root/html/50x.html docs/html/ || exit 1
|
||||
|
||||
cd .. || exit 1
|
||||
|
||||
cp $root/patches/nginx-$main_ver-no_pool.patch ./nginx-no_pool.patch || exit 1
|
||||
@ -314,7 +347,7 @@ rm -rf no-pool-nginx-$ver
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.58
|
||||
ver=0.60
|
||||
$root/util/get-tarball "https://github.com/openresty/echo-nginx-module/tarball/v$ver" -O echo-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf echo-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-echo-nginx-module-* echo-nginx-module-$ver || exit 1
|
||||
@ -328,14 +361,14 @@ mv openresty-xss-nginx-module-* xss-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.2.19
|
||||
ver=0.3.0
|
||||
$root/util/get-tarball "https://github.com/simpl/ngx_devel_kit/tarball/v$ver" -O ngx_devel_kit-$ver.tar.gz
|
||||
tar -xzf ngx_devel_kit-$ver.tar.gz || exit 1
|
||||
mv simpl-ngx_devel_kit-* ngx_devel_kit-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.29
|
||||
ver=0.31
|
||||
$root/util/get-tarball "https://github.com/openresty/set-misc-nginx-module/tarball/v$ver" -O set-misc-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf set-misc-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-set-misc-nginx-module-* set-misc-nginx-module-$ver || exit 1
|
||||
@ -356,7 +389,7 @@ mv openresty-rds-csv-nginx-module-* rds-csv-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.29
|
||||
ver=0.32
|
||||
$root/util/get-tarball "https://github.com/openresty/headers-more-nginx-module/tarball/v$ver" -O headers-more-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf headers-more-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-headers-more-nginx-module-* headers-more-nginx-module-$ver || exit 1
|
||||
@ -370,56 +403,56 @@ mv openresty-drizzle-nginx-module-* drizzle-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.10.0
|
||||
ver=0.10.7
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-nginx-module/tarball/v$ver" -O lua-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf lua-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-nginx-module-* ngx_lua-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.04
|
||||
ver=0.06
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-upstream-nginx-module/tarball/v$ver" -O lua-upstream-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf lua-upstream-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-upstream-nginx-module-* ngx_lua_upstream-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.04
|
||||
ver=0.05
|
||||
$root/util/get-tarball "https://github.com/openresty/array-var-nginx-module/tarball/v$ver" -O array-var-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf array-var-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-array-var-nginx-module-* array-var-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.16
|
||||
ver=0.17
|
||||
$root/util/get-tarball "https://github.com/openresty/memc-nginx-module/tarball/v$ver" -O memc-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf memc-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-memc-nginx-module-* memc-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.30
|
||||
ver=0.31
|
||||
$root/util/get-tarball "https://github.com/openresty/srcache-nginx-module/tarball/v$ver" -O srcache-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf srcache-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-srcache-nginx-module-* srcache-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.11
|
||||
ver=0.12
|
||||
$root/util/get-tarball "https://github.com/calio/form-input-nginx-module/tarball/v$ver" -O form-input-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf form-input-nginx-module-$ver.tar.gz || exit 1
|
||||
mv calio-form-input-nginx-module-* form-input-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.13
|
||||
ver=0.14
|
||||
$root/util/get-tarball "https://github.com/calio/iconv-nginx-module/tarball/v$ver" -O iconv-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf iconv-nginx-module-$ver.tar.gz || exit 1
|
||||
mv calio-iconv-nginx-module-* iconv-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.04
|
||||
ver=0.06
|
||||
$root/util/get-tarball "https://github.com/openresty/encrypted-session-nginx-module/tarball/v$ver" -O encrypted-session-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf encrypted-session-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-encrypted-session-nginx-module-* encrypted-session-nginx-module-$ver || exit 1
|
||||
@ -435,7 +468,7 @@ mv openresty-encrypted-session-nginx-module-* encrypted-session-nginx-module-$ve
|
||||
#################################
|
||||
|
||||
ver=0.3.7
|
||||
$root/util/get-tarball "http://people.freebsd.org/~osa/ngx_http_redis-$ver.tar.gz" -O redis-nginx-module-$ver.tar.gz || exit 1
|
||||
$root/util/get-tarball "https://people.freebsd.org/~osa/ngx_http_redis-$ver.tar.gz" -O redis-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf redis-nginx-module-$ver.tar.gz || exit 1
|
||||
mv ngx_http_redis-* redis-nginx-module-$ver || exit 1
|
||||
|
||||
@ -465,17 +498,25 @@ mv FRiCKLE-ngx_coolkit-* ngx_coolkit-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.12
|
||||
ver=0.13
|
||||
$root/util/get-tarball "https://github.com/openresty/redis2-nginx-module/tarball/v$ver" -O redis2-nginx-module-$ver.tar.gz || exit 1
|
||||
tar -xzf redis2-nginx-module-$ver.tar.gz || exit 1
|
||||
mv openresty-redis2-nginx-module-* redis2-nginx-module-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.05
|
||||
ver=0.16
|
||||
$root/util/get-tarball "https://github.com/openresty/resty-cli/tarball/v$ver" -O resty-cli-$ver.tar.gz || exit 1
|
||||
tar -xzf resty-cli-$ver.tar.gz || exit 1
|
||||
mv openresty-resty-cli-* resty-cli-$ver || exit 1
|
||||
resty_cli=resty-cli-$ver
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.0.2
|
||||
$root/util/get-tarball "https://github.com/openresty/opm/tarball/v$ver" -O opm-$ver.tar.gz || exit 1
|
||||
tar -xzf opm-$ver.tar.gz || exit 1
|
||||
mv openresty-opm-* opm-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
@ -505,7 +546,7 @@ echo
|
||||
|
||||
#################################
|
||||
|
||||
ver=2.1-20160108
|
||||
ver=2.1-20161104
|
||||
$root/util/get-tarball "https://github.com/openresty/luajit2/archive/v$ver.tar.gz" -O "LuaJIT-$ver.tar.gz" || exit 1
|
||||
tar -xzf LuaJIT-$ver.tar.gz || exit 1
|
||||
mv luajit2-* LuaJIT-$ver || exit 1
|
||||
@ -526,7 +567,7 @@ cd .. || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=2.1.0.3
|
||||
ver=2.1.0.4
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-cjson/archive/$ver.tar.gz" -O "lua-cjson-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-cjson-$ver.tar.gz || exit 1
|
||||
#cd lua-cjson-$ver || exit 1
|
||||
@ -561,7 +602,7 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.14
|
||||
ver=0.18
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-dns/tarball/v$ver" -O "lua-resty-dns-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-dns-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-dns-* lua-resty-dns-$ver || exit 1
|
||||
@ -573,7 +614,7 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.13
|
||||
ver=0.14
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-memcached/tarball/v$ver" -O "lua-resty-memcached-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-memcached-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-memcached-* lua-resty-memcached-$ver || exit 1
|
||||
@ -585,7 +626,7 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.22
|
||||
ver=0.26
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-redis/tarball/v$ver" -O "lua-resty-redis-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-redis-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-redis-* lua-resty-redis-$ver || exit 1
|
||||
@ -597,7 +638,7 @@ mv openresty-lua-resty-redis-* lua-resty-redis-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.15
|
||||
ver=0.17
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-mysql/tarball/v$ver" -O "lua-resty-mysql-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-mysql-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-mysql-* lua-resty-mysql-$ver || exit 1
|
||||
@ -609,7 +650,19 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.09
|
||||
ver=0.01
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-limit-traffic/tarball/v$ver" -O "lua-resty-limit-traffic-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-limit-traffic-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-limit-traffic-* lua-resty-limit-traffic-$ver || exit 1
|
||||
cd lua-resty-limit-traffic-$ver || exit 1
|
||||
#patch -p1 < $root/patches/lua_cjson-$ver-array_detection_fix.patch || exit 1
|
||||
sed 's/\$(DESTDIR)\//$(DESTDIR)/g' Makefile > mk || exit 1
|
||||
mv mk Makefile || exit 1
|
||||
cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.10
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-upload/tarball/v$ver" -O "lua-resty-upload-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-upload-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-upload-* lua-resty-upload-$ver || exit 1
|
||||
@ -633,7 +686,7 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.05
|
||||
ver=0.06
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-websocket/tarball/v$ver" -O "lua-resty-websocket-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-websocket-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-websocket-* lua-resty-websocket-$ver || exit 1
|
||||
@ -669,7 +722,7 @@ cd ..
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.1.4
|
||||
ver=0.1.9
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-core/tarball/v$ver" -O "lua-resty-core-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-core-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-core-* lua-resty-core-$ver || exit 1
|
||||
@ -681,7 +734,7 @@ mv openresty-lua-resty-core-* lua-resty-core-$ver || exit 1
|
||||
|
||||
#################################
|
||||
|
||||
ver=0.03
|
||||
ver=0.04
|
||||
$root/util/get-tarball "https://github.com/openresty/lua-resty-upstream-healthcheck/tarball/v$ver" -O "lua-resty-upstream-healthcheck-$ver.tar.gz" || exit 1
|
||||
tar -xzf lua-resty-upstream-healthcheck-$ver.tar.gz || exit 1
|
||||
mv openresty-lua-resty-upstream-healthcheck-* lua-resty-upstream-healthcheck-$ver || exit 1
|
||||
@ -697,19 +750,68 @@ rm *.tar.gz
|
||||
|
||||
cd ..
|
||||
cp $root/util/configure ./ || exit 1
|
||||
#markdown2pod -e utf8 -d GitHub $root/README.markdown|$root/util/fix-pod2markdown|pod2text > README || exit 1
|
||||
cp $root/README.markdown ./ || exit 1
|
||||
cp $root/util/install bundle/ || exit 1
|
||||
mkdir util || exit 1
|
||||
cp $root/util/package-win32.sh util/ || exit 1
|
||||
cp $root/util/build-win32.sh util/ || exit 1
|
||||
cp $root/COPYRIGHT ./ || exit 1
|
||||
markdown2pod -e utf8 -d GitHub $root/doc/README-win32.md|$root/util/fix-pod2markdown|pod2text > README-win32.txt || exit 1
|
||||
perl bundle/$resty_cli/bin/md2pod.pl $root/doc/README-win32.md | pod2text > README-win32.txt || exit 1
|
||||
unix2dos README-win32.txt || exit 1
|
||||
mkdir patches/ || exit 1
|
||||
cp $root/patches/openssl-1.0.2h-sess_set_get_cb_yield.patch patches/ || exit 1
|
||||
|
||||
restydoc_index=$bundle_dir/$resty_cli/bin/restydoc-index
|
||||
#restydoc_index=$HOME/git/resty-cli/bin/restydoc-index
|
||||
|
||||
nginx_xml2pod=$bundle_dir/$resty_cli/bin/nginx-xml2pod
|
||||
#nginx_xml2pod=$HOME/git/resty-cli/bin/nginx-xml2pod
|
||||
|
||||
# generate restydoc index from nginx docs
|
||||
|
||||
curdir=$PWD
|
||||
cd $root/work/ || exit 1
|
||||
if [ -d nginx.org ]; then
|
||||
cd nginx.org/ || exit 1
|
||||
hg pull || exit 1
|
||||
hg update || exit 1
|
||||
cd ..
|
||||
else
|
||||
hg clone http://hg.nginx.org/nginx.org || exit 1
|
||||
fi
|
||||
cd nginx.org/ || exit 1
|
||||
$nginx_xml2pod xml/en/docs || exit 1
|
||||
cd $curdir || exit 1
|
||||
|
||||
echo "restydoc-index $root/work/nginx.org"
|
||||
$restydoc_index --outdir bundle $root/work/nginx.org || exit 1
|
||||
|
||||
echo "restydoc-index $root/doc/lua-5.1.5"
|
||||
$restydoc_index --outdir bundle $root/doc/lua-5.1.5 || exit 1
|
||||
|
||||
echo "restydoc-index $root/doc/LuaJIT-2.1"
|
||||
$restydoc_index --outdir bundle $root/doc/LuaJIT-2.1 || exit 1
|
||||
|
||||
# generate restydoc index from openresty docs
|
||||
|
||||
for indir in bundle/*/; do
|
||||
if [ "$indir" == "bundle/pod/" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$indir" == "bundle/nginx-$main_ver/" ]; then
|
||||
continue
|
||||
fi
|
||||
echo "restydoc-index --outdir bundle $indir"
|
||||
$restydoc_index --outdir $curdir/bundle $indir || exit 1
|
||||
done
|
||||
|
||||
cd $curdir || exit 1
|
||||
find bundle -name '*.md' -delete
|
||||
find bundle -name '*.markdown' -delete
|
||||
find bundle -name '*.wiki' -delete
|
||||
find bundle -name '*~' -delete
|
||||
|
||||
cd $root
|
||||
|
||||
tar cf $name.tar $name
|
||||
gzip -f --best $name.tar
|
||||
cd $root || exit 1
|
||||
|
||||
tar cf $name.tar $name || exit 1
|
||||
gzip -f --best $name.tar || exit 1
|
||||
|
@ -31,4 +31,4 @@ cd ..
|
||||
tar czvf nginx-$ver.tar.gz nginx-$ver || exit 1
|
||||
ls -lh ./nginx-$ver.tar.gz
|
||||
#ls -lh ~/work/nginx-$ver.tar.gz
|
||||
scp nginx-$ver.tar.gz agentzh.org:~/www/agentzh/misc/nginx/
|
||||
scp nginx-$ver.tar.gz openresty.org:/home/agentz/www/agentzh/misc/nginx/
|
||||
|
@ -7,11 +7,13 @@ if [ -d $name ]; then
|
||||
rm -rf $name
|
||||
fi
|
||||
mkdir $name || exit 1
|
||||
cp -r resty nginx.exe luajit.exe lua51.dll lua include lualib html conf logs $name/ || exit 1
|
||||
cp -r resty restydoc restydoc-index nginx.exe luajit.exe lua51.dll lua include lualib html conf logs pod $name/ || exit 1
|
||||
cp COPYRIGHT $name/ || exit 1
|
||||
cp /c/MinGW/bin/libgcc_s_dw2-1.dll $name/ || exit 1
|
||||
cd $name || exit 1
|
||||
PATH=/c/Strawberry/perl/bin:$PATH cmd /c 'pl2bat.bat resty' || exit 1
|
||||
PATH=/c/Strawberry/perl/bin:$PATH cmd /c 'pl2bat.bat restydoc' || exit 1
|
||||
PATH=/c/Strawberry/perl/bin:$PATH cmd /c 'pl2bat.bat restydoc-index' || exit 1
|
||||
cp ../README-win32.txt README.txt
|
||||
unix2dos conf/* html/*.html resty || exit 1
|
||||
cd .. || exit 1
|
||||
|
Reference in New Issue
Block a user