passenger 4.0.36 → 4.0.37
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/NEWS +51 -0
- data/README.md +3 -1
- data/build/integration_tests.rb +5 -1
- data/build/test_basics.rb +2 -2
- data/dev/run_travis.sh +3 -0
- data/doc/Users guide Nginx.txt +3 -3
- data/ext/common/ApplicationPool2/Group.h +2 -1
- data/ext/common/ApplicationPool2/Implementation.cpp +30 -1
- data/ext/common/ApplicationPool2/Pool.h +26 -3
- data/ext/common/ApplicationPool2/Process.h +39 -10
- data/ext/common/Constants.h +1 -1
- data/ext/common/MultiLibeio.cpp +4 -0
- data/ext/common/ServerInstanceDir.h +1 -1
- data/ext/common/Utils.cpp +29 -0
- data/ext/common/Utils.h +7 -1
- data/ext/common/Utils/BufferedIO.h +13 -0
- data/ext/common/agents/HelperAgent/Main.cpp +6 -2
- data/ext/common/agents/HelperAgent/RequestHandler.h +32 -1
- data/helper-scripts/meteor-loader.rb +126 -10
- data/helper-scripts/node-loader.js +5 -3
- data/helper-scripts/wsgi-loader.py +23 -11
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/config/detach_process_command.rb +96 -0
- data/lib/phusion_passenger/config/main.rb +1 -0
- data/lib/phusion_passenger/request_handler.rb +11 -4
- data/node_lib/phusion_passenger/httplib_emulation.js +20 -14
- data/test/cxx/RequestHandlerTest.cpp +80 -0
- data/test/integration_tests/apache2_tests.rb +57 -0
- data/test/integration_tests/nginx_tests.rb +62 -0
- data/test/node/httplib_emulation_spec.js +137 -5
- data/test/node/spec_helper.js +13 -0
- data/test/stub/node/app.js +125 -0
- data/test/stub/node/public/.gitignore +0 -0
- data/test/stub/node/tmp/.gitignore +0 -0
- data/test/stub/rack/config.ru +19 -0
- data/test/stub/wsgi/passenger_wsgi.py +37 -1
- metadata +6 -2
- metadata.gz.asc +7 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzY2YjMwZGFkMjkzNDNlMjgwYWIwZjM0OTk4OTEzZDczYmNhZTUxNw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjMwYmQ4ZWM4ZWZkOTc1OWY2NTk0OGFjYTdjYjllZGE0ZWFkMTlhMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZWY2OGFiZTMxNTMxMmNkZGFhYTQ4Nzk3OWM4MTNlNjJjZGQ1MDkwZTA0ZTNl
|
10
|
+
MDY2N2FhOWFkNjdkYWYzYTgzNzMxMmE5ZGMzNjU2MmUwYjA4MDRlMDZmZDg2
|
11
|
+
YTk1MTlmMjJmYmI5OWQ0ZjU4YzU5MDI0M2ZkMzU2NGRkNWU5Mzk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODFhMDg0OWU1YmY2MjRiNWZjYjFkY2ZjN2MwMTZhYjA5YmNjM2E3ZDMwNTMx
|
14
|
+
M2ExZDYxZGQyNWQ2ZjFjNzA4MDhjZjIzMzA5YTQyN2E1MjVmOTQyMzU4YzBi
|
15
|
+
OGM2NDliMWNkMjQwYTBhYmFhNzhmZTZkNTUyMTVjMWE2Nzc3NTM=
|
checksums.yaml.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJS6CPIAAoJECrHRaUKISqMBzMIAJc+WtmkHIzclF/yuMagWa40
|
6
|
+
0p9dz6CINEmYQ4gCabMeRhBa/VeQauXhvR3d2cm7TyCyLqfoN6YLHnesVwGGI2vu
|
7
|
+
Kt5HbgOYGTT6cyf8QmGjubNC+VslKTZIyoapRigRRtX10tLsvAYyC9WnaOMGikWS
|
8
|
+
OKpNucWMA7UnXfsfyNa/u4L0c+pNI15DM5asjMPG46QHiYDfAKIhRzGTRovjBAOW
|
9
|
+
WaLu+qtfMJ9ui261i9KBJuPjIbbIeHZQeGDA70tvnm6na5W8A11XilYav4T8Qcv+
|
10
|
+
fGoDcJ88M6q3cYspeOJPsEEICFHvhjQ0wMm5qT/YHhLd1dqxapCidmj+nqFwxuQ=
|
11
|
+
=6pys
|
12
12
|
-----END PGP SIGNATURE-----
|
data.tar.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJS6CPIAAoJECrHRaUKISqMvrEIAKw15y9cgHaX26Mh6AYj+Bj1
|
6
|
+
jQ2aTpVBoNwhxX6dGEvLhpxxknTmvaryffRxYJX7eE8JJKP526RzJogkbgBMktqY
|
7
|
+
vxSRNSzpZpvoEztvpiy+UGVtgaUjTEaIFl9daOQbWxQkiLmvglRPMBFu7j30fU9B
|
8
|
+
56vdqzGxqZ9eSHMqd3B+kVSnpoiVOgRCigVocU/hoblLBDankxuzNkj6tAtlX+G3
|
9
|
+
zmX0QZ+QBfWDqEvw2mVbXIQFwz9+tMCnybEctz5VJIPHaO8cco129jXYo+hcdu1Q
|
10
|
+
EUlt3bcb0/w7a2giU2WuzYdRJqQFdTF24XOOwLozx0Kf8HizpQCU7dJaz3hE79E=
|
11
|
+
=0LER
|
12
12
|
-----END PGP SIGNATURE-----
|
data/NEWS
CHANGED
@@ -1,3 +1,54 @@
|
|
1
|
+
Release 4.0.37
|
2
|
+
--------------
|
3
|
+
|
4
|
+
* Improved Node.js compatibility. Calling on() on the request object
|
5
|
+
now returns the request object itself. This fixes some issues with
|
6
|
+
Express, Connect and Formidable. Furthermore, some WebSocket-related
|
7
|
+
issues have been fixed.
|
8
|
+
* Improved Meteor support. Meteor application processes are now shut down
|
9
|
+
quicker. Previously, they linger around for 5 seconds while waiting for
|
10
|
+
all connections to terminate, but that didn't work well because WebSocket
|
11
|
+
connections were kept open indefinitely. Also, some WebSocket-related
|
12
|
+
issues have been fixed.
|
13
|
+
* Introduced a new tool `passenger-config detach-process` for gracefully
|
14
|
+
detaching an application process from the process pool. Has a similar
|
15
|
+
effect to killing the application process directly with `kill <PID>`,
|
16
|
+
but killing directly may cause the HTTP client to see an error, while
|
17
|
+
using this command guarantees that clients see no errors.
|
18
|
+
* Fixed a crash occurs when an application fails to spawn, but the HTTP
|
19
|
+
client disconnects before the error page is generated. Fixes issue #1028.
|
20
|
+
* Fixed a symlink-related security vulnerability.
|
21
|
+
|
22
|
+
Urgency: low
|
23
|
+
Scope: local exploit
|
24
|
+
Summary: writing files to arbitrary directory by hijacking temp directories
|
25
|
+
Affected versions: 4.0.5 and later
|
26
|
+
Fixed versions: 4.0.37
|
27
|
+
|
28
|
+
Description:
|
29
|
+
Phusion Passenger creates a "server instance directory" in /tmp during startup,
|
30
|
+
which is a temporary directory that Phusion Passenger uses to store working files.
|
31
|
+
This directory is deleted after Phusion Passenger exits. For various technical
|
32
|
+
reasons, this directory must have a semi-predictable filename. If a local attacker
|
33
|
+
can predict this filename, and precreates a symlink with the same filename that
|
34
|
+
points to an arbitrary directory with mode 755, owner root and group root, then
|
35
|
+
the attacker will succeed in making Phusion Passenger write files and create
|
36
|
+
subdirectories inside that target directory. The following files/subdirectories
|
37
|
+
are created:
|
38
|
+
|
39
|
+
* control_process.pid
|
40
|
+
* generation-X, where X is a number.
|
41
|
+
|
42
|
+
If you happen to have a file inside the target directory called `control_process.pid`,
|
43
|
+
then that file's contents are overwritten.
|
44
|
+
|
45
|
+
These files and directories are deleted during Phusion Passenger exit. The target
|
46
|
+
directory itself is not deleted, nor are any other contents inside the target
|
47
|
+
directory, although the symlink is.
|
48
|
+
|
49
|
+
Thanks go to Jakub Wilk for discovering this issue.
|
50
|
+
|
51
|
+
|
1
52
|
Release 4.0.36
|
2
53
|
--------------
|
3
54
|
|
data/README.md
CHANGED
@@ -4,9 +4,11 @@
|
|
4
4
|
|
5
5
|
What makes it so fast and reliable is its **C++** core, its **zero-copy** architecture, its **watchdog** system and its **hybrid** evented, multi-threaded and multi-process design.
|
6
6
|
|
7
|
+
<a href="http://vimeo.com/phusionnl/review/80475623/c16e940d1f"><img src="http://blog.phusion.nl/wp-content/uploads/2014/01/gameofthrones.jpg" height="300"></a><br><em>Phusion Passenger used in Game of Thrones Ascention</em>
|
8
|
+
|
7
9
|
**Learn more:** [Website](https://www.phusionpassenger.com/) | [Documentation](https://www.phusionpassenger.com/documentation_and_support) | [Support resources](https://www.phusionpassenger.com/documentation_and_support) | [Github](https://github.com/phusion/passenger) | [Twitter](https://twitter.com/phusion_nl) | [Blog](http://blog.phusion.nl/)
|
8
10
|
|
9
|
-
<center><img src="http://blog.phusion.nl/wp-content/uploads/2012/07/Passenger_chair_256x256.jpg" width="160" height="160" alt="Phusion Passenger"></center>
|
11
|
+
<a href="https://www.phusionpassenger.com"><center><img src="http://blog.phusion.nl/wp-content/uploads/2012/07/Passenger_chair_256x256.jpg" width="160" height="160" alt="Phusion Passenger"></center></a>
|
10
12
|
|
11
13
|
## Installation
|
12
14
|
|
data/build/integration_tests.rb
CHANGED
@@ -59,7 +59,11 @@ task 'test:integration:nginx' => dependencies do
|
|
59
59
|
require 'shellwords'
|
60
60
|
command << " -e #{Shellwords.escape(grep)}"
|
61
61
|
end
|
62
|
-
|
62
|
+
repeat = true
|
63
|
+
while repeat
|
64
|
+
sh "cd test && exec #{command}"
|
65
|
+
repeat = boolean_option('REPEAT')
|
66
|
+
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
data/build/test_basics.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010-
|
2
|
+
# Copyright (c) 2010-2014 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -77,6 +77,6 @@ task 'test:install_deps' do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
if boolean_option('NODE_MODULES', default)
|
80
|
-
sh "npm install mocha should sinon"
|
80
|
+
sh "npm install mocha should sinon express"
|
81
81
|
end
|
82
82
|
end
|
data/dev/run_travis.sh
CHANGED
@@ -111,6 +111,7 @@ fi
|
|
111
111
|
|
112
112
|
if [[ "$TEST_NGINX" = 1 ]]; then
|
113
113
|
install_base_test_deps
|
114
|
+
install_node_and_modules
|
114
115
|
run ./bin/passenger-install-nginx-module --auto --prefix=/tmp/nginx --auto-download
|
115
116
|
run rake test:integration:nginx
|
116
117
|
fi
|
@@ -120,6 +121,7 @@ if [[ "$TEST_APACHE2" = 1 ]]; then
|
|
120
121
|
run sudo apt-get install -y --no-install-recommends \
|
121
122
|
apache2-mpm-worker apache2-threaded-dev
|
122
123
|
install_base_test_deps
|
124
|
+
install_node_and_modules
|
123
125
|
run ./bin/passenger-install-apache2-module --auto #--no-update-config
|
124
126
|
run rvmsudo ./bin/passenger-install-apache2-module --auto --no-compile
|
125
127
|
run rake test:integration:apache2
|
@@ -137,6 +139,7 @@ if [[ "$TEST_DEBIAN_PACKAGING" = 1 ]]; then
|
|
137
139
|
ruby1.8 ruby1.8-dev ruby1.9.1 ruby1.9.1-dev rubygems libev-dev gdebi-core \
|
138
140
|
source-highlight
|
139
141
|
install_test_deps_with_doctools
|
142
|
+
install_node_and_modules
|
140
143
|
run rake debian:dev debian:dev:reinstall
|
141
144
|
run rake test:integration:native_packaging SUDO=1
|
142
145
|
run env PASSENGER_LOCATION_CONFIGURATION_FILE=/usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini \
|
data/doc/Users guide Nginx.txt
CHANGED
@@ -561,9 +561,9 @@ server {
|
|
561
561
|
==== passenger_ruby <filename>
|
562
562
|
The `passenger_ruby` option allows one to specify the Ruby interpreter to use. Similarly, the `passenger_python` and `passenger_nodejs` options are for specifying the Python interpreter and Node.js commands, respectively.
|
563
563
|
|
564
|
-
In versions prior to 4.0.0, only a single Ruby version was supported for the entire Nginx instance, so `passenger_ruby` may only occur in the global server configuration. Also, the `passenger_python`
|
564
|
+
In versions prior to 4.0.0, only a single Ruby version was supported for the entire Nginx instance, so `passenger_ruby` may only occur in the global server configuration. Also, the `passenger_python`/`passenger_nodejs` options were not supported.
|
565
565
|
|
566
|
-
Since version 4.0.0,
|
566
|
+
Since version 4.0.0, Phusion Passenger supports multiple Ruby interpreters in the same Nginx instance. And so, since version 4.0.0, this option may occur in the following places:
|
567
567
|
|
568
568
|
* In the 'http' configuration block.
|
569
569
|
* In a 'server' configuration block.
|
@@ -574,7 +574,7 @@ The `passenger_ruby` in the `http` block - that is, the one that `passenger-inst
|
|
574
574
|
|
575
575
|
The `passenger_ruby` directive in the `http` block is also used as the default Ruby interpreter for Ruby web apps. You don't *have* to specify a `passenger_ruby` in the `http` block though, because the default is to use the first `ruby` command found in `$PATH`.
|
576
576
|
|
577
|
-
The `passenger_python` and `passenger_nodejs` options
|
577
|
+
The `passenger_python` and `passenger_nodejs` options work in a similar manner, but apply to Python and Node.js instead.
|
578
578
|
|
579
579
|
You can also override `passenger_ruby` and other directives in specific contexts if you want to use a different interpreter for that web app. For example:
|
580
580
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -510,6 +510,7 @@ public:
|
|
510
510
|
} else if (&destination == &detachedProcesses) {
|
511
511
|
assert(process->isAlive());
|
512
512
|
process->enabled = Process::DETACHED;
|
513
|
+
process->abortLongRunningConnections();
|
513
514
|
} else {
|
514
515
|
P_BUG("Unknown destination list");
|
515
516
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -35,6 +35,7 @@
|
|
35
35
|
#include <Exceptions.h>
|
36
36
|
#include <MessageReadersWriters.h>
|
37
37
|
#include <Utils/ScopeGuard.h>
|
38
|
+
#include <Utils/MessageIO.h>
|
38
39
|
|
39
40
|
namespace Passenger {
|
40
41
|
namespace ApplicationPool2 {
|
@@ -1225,12 +1226,40 @@ Group::generateSecret(const SuperGroupPtr &superGroup) {
|
|
1225
1226
|
}
|
1226
1227
|
|
1227
1228
|
|
1229
|
+
PoolPtr
|
1230
|
+
Process::getPool() const {
|
1231
|
+
assert(getLifeStatus() != DEAD);
|
1232
|
+
return getGroup()->getPool();
|
1233
|
+
}
|
1234
|
+
|
1228
1235
|
SuperGroupPtr
|
1229
1236
|
Process::getSuperGroup() const {
|
1230
1237
|
assert(getLifeStatus() != DEAD);
|
1231
1238
|
return getGroup()->getSuperGroup();
|
1232
1239
|
}
|
1233
1240
|
|
1241
|
+
void
|
1242
|
+
Process::sendAbortLongRunningConnectionsMessage(const string &address) {
|
1243
|
+
boost::function<void ()> func = boost::bind(
|
1244
|
+
realSendAbortLongRunningConnectionsMessage, address);
|
1245
|
+
return getPool()->nonInterruptableThreads.create_thread(
|
1246
|
+
boost::bind(runAndPrintExceptions, func, false),
|
1247
|
+
"Sending detached message to process " + toString(pid),
|
1248
|
+
256 * 1024);
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
void
|
1252
|
+
Process::realSendAbortLongRunningConnectionsMessage(string address) {
|
1253
|
+
TRACE_POINT();
|
1254
|
+
FileDescriptor fd(connectToServer(address));
|
1255
|
+
unsigned long long timeout = 3000000;
|
1256
|
+
vector<string> args;
|
1257
|
+
|
1258
|
+
UPDATE_TRACE_POINT();
|
1259
|
+
args.push_back("abort_long_running_connections");
|
1260
|
+
writeArrayMessage(fd, args, &timeout);
|
1261
|
+
}
|
1262
|
+
|
1234
1263
|
string
|
1235
1264
|
Process::inspect() const {
|
1236
1265
|
assert(getLifeStatus() != DEAD);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -149,6 +149,7 @@ public:
|
|
149
149
|
|
150
150
|
enum LifeStatus {
|
151
151
|
ALIVE,
|
152
|
+
PREPARED_FOR_SHUTDOWN,
|
152
153
|
SHUTTING_DOWN,
|
153
154
|
SHUT_DOWN
|
154
155
|
} lifeStatus;
|
@@ -953,6 +954,7 @@ public:
|
|
953
954
|
}
|
954
955
|
}
|
955
956
|
|
957
|
+
/** Must be called right after construction. */
|
956
958
|
void initialize() {
|
957
959
|
LockGuard l(syncher);
|
958
960
|
interruptableThreads.create_thread(
|
@@ -972,10 +974,31 @@ public:
|
|
972
974
|
debugSupport = boost::make_shared<DebugSupport>();
|
973
975
|
}
|
974
976
|
|
975
|
-
|
977
|
+
/** Should be called right after the HelperAgent has received
|
978
|
+
* the message to exit gracefully. This will tell processes to
|
979
|
+
* abort any long-running connections, e.g. WebSocket connections,
|
980
|
+
* because the RequestHandler has to wait until all connections are
|
981
|
+
* finished before proceeding with shutdown.
|
982
|
+
*/
|
983
|
+
void prepareForShutdown() {
|
976
984
|
TRACE_POINT();
|
977
985
|
ScopedLock lock(syncher);
|
978
986
|
assert(lifeStatus == ALIVE);
|
987
|
+
lifeStatus = PREPARED_FOR_SHUTDOWN;
|
988
|
+
vector<ProcessPtr> processes = getProcesses(false);
|
989
|
+
foreach (ProcessPtr process, processes) {
|
990
|
+
if (process->abortLongRunningConnections()) {
|
991
|
+
// Ensure that the process is not immediately respawned.
|
992
|
+
process->getGroup()->options.minProcesses = 0;
|
993
|
+
}
|
994
|
+
}
|
995
|
+
}
|
996
|
+
|
997
|
+
/** Must be called right before destruction. */
|
998
|
+
void destroy() {
|
999
|
+
TRACE_POINT();
|
1000
|
+
ScopedLock lock(syncher);
|
1001
|
+
assert(lifeStatus == ALIVE || lifeStatus == PREPARED_FOR_SHUTDOWN);
|
979
1002
|
|
980
1003
|
lifeStatus = SHUTTING_DOWN;
|
981
1004
|
|
@@ -1004,7 +1027,7 @@ public:
|
|
1004
1027
|
void asyncGet(const Options &options, const GetCallback &callback, bool lockNow = true) {
|
1005
1028
|
DynamicScopedLock lock(syncher, lockNow);
|
1006
1029
|
|
1007
|
-
assert(lifeStatus == ALIVE);
|
1030
|
+
assert(lifeStatus == ALIVE || lifeStatus == PREPARED_FOR_SHUTDOWN);
|
1008
1031
|
verifyInvariants();
|
1009
1032
|
P_TRACE(2, "asyncGet(appGroupName=" << options.getAppGroupName() << ")");
|
1010
1033
|
vector<Callback> actions;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2014 Phusion
|
4
4
|
*
|
5
5
|
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
*
|
@@ -113,20 +113,21 @@ public:
|
|
113
113
|
* ## Life time
|
114
114
|
*
|
115
115
|
* A Process object lives until the containing Group calls `detach(process)`,
|
116
|
-
* which indicates that it wants this Process to
|
117
|
-
*
|
118
|
-
*
|
119
|
-
*
|
120
|
-
*
|
121
|
-
*
|
122
|
-
*
|
123
|
-
*
|
116
|
+
* which indicates that it wants this Process to shut down. This causes
|
117
|
+
* `signalDetached()` to be called, which may or may not send a message
|
118
|
+
* to the process. After this, the Process object is stored in the
|
119
|
+
* `detachedProcesses` collection in the Group and are no longer eligible for
|
120
|
+
* receiving requests. Once all requests on this Process have finished,
|
121
|
+
* `triggerShutdown()` will be called, which will send a message to the
|
122
|
+
* process telling it to shut down. Once the process is gone, `cleanup()` is
|
123
|
+
* called, and the Process object is removed from the collection.
|
124
124
|
*
|
125
125
|
* This means that a Group outlives all its Processes, a Process outlives all
|
126
126
|
* its Sessions, and a Process also outlives the OS process.
|
127
127
|
*/
|
128
128
|
class Process: public boost::enable_shared_from_this<Process> {
|
129
|
-
private
|
129
|
+
// Actually private, but marked public so that unit tests can access the fields.
|
130
|
+
public:
|
130
131
|
friend class Group;
|
131
132
|
|
132
133
|
/** A mutex to protect access to `lifeStatus`. */
|
@@ -147,6 +148,9 @@ private:
|
|
147
148
|
/** The handle inside the associated Group's process priority queue. */
|
148
149
|
PriorityQueue<Process>::Handle pqHandle;
|
149
150
|
|
151
|
+
void sendAbortLongRunningConnectionsMessage(const string &address);
|
152
|
+
static void realSendAbortLongRunningConnectionsMessage(string address);
|
153
|
+
|
150
154
|
static bool
|
151
155
|
isZombie(pid_t pid) {
|
152
156
|
string filename = "/proc/" + toString(pid) + "/status";
|
@@ -308,6 +312,7 @@ public:
|
|
308
312
|
} oobwStatus;
|
309
313
|
/** Caches whether or not the OS process still exists. */
|
310
314
|
mutable bool m_osProcessExists;
|
315
|
+
bool longRunningConnectionsAborted;
|
311
316
|
/** Time at which shutdown began. */
|
312
317
|
time_t shutdownStartTime;
|
313
318
|
/** Collected by Pool::collectAnalytics(). */
|
@@ -346,6 +351,7 @@ public:
|
|
346
351
|
enabled(ENABLED),
|
347
352
|
oobwStatus(OOBW_NOT_ACTIVE),
|
348
353
|
m_osProcessExists(true),
|
354
|
+
longRunningConnectionsAborted(false),
|
349
355
|
shutdownStartTime(0)
|
350
356
|
{
|
351
357
|
SpawnerConfigPtr config;
|
@@ -408,6 +414,13 @@ public:
|
|
408
414
|
this->group = group;
|
409
415
|
}
|
410
416
|
|
417
|
+
/**
|
418
|
+
* Thread-safe.
|
419
|
+
* @pre getLifeState() != DEAD
|
420
|
+
* @post result != NULL
|
421
|
+
*/
|
422
|
+
PoolPtr getPool() const;
|
423
|
+
|
411
424
|
/**
|
412
425
|
* Thread-safe.
|
413
426
|
* @pre getLifeState() != DEAD
|
@@ -439,6 +452,22 @@ public:
|
|
439
452
|
return lifeStatus;
|
440
453
|
}
|
441
454
|
|
455
|
+
bool abortLongRunningConnections() {
|
456
|
+
bool sent = false;
|
457
|
+
if (!longRunningConnectionsAborted) {
|
458
|
+
SocketList::iterator it, end = sockets->end();
|
459
|
+
for (it = sockets->begin(); it != end; it++) {
|
460
|
+
Socket *socket = &(*it);
|
461
|
+
if (socket->name == "control") {
|
462
|
+
sendAbortLongRunningConnectionsMessage(socket->address);
|
463
|
+
sent = true;
|
464
|
+
}
|
465
|
+
}
|
466
|
+
longRunningConnectionsAborted = true;
|
467
|
+
}
|
468
|
+
return sent;
|
469
|
+
}
|
470
|
+
|
442
471
|
bool canTriggerShutdown() const {
|
443
472
|
return getLifeStatus() == ALIVE && sessions == 0;
|
444
473
|
}
|
data/ext/common/Constants.h
CHANGED