passenger 3.0.9 → 3.0.10
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.
- data/NEWS +32 -0
- data/Rakefile +1 -1
- data/build/common_library.rb +6 -1
- data/build/config.rb +3 -1
- data/doc/Users guide Apache.html +120 -39
- data/doc/Users guide Apache.txt +64 -0
- data/doc/Users guide Nginx.html +50 -2
- data/doc/Users guide Nginx.txt +29 -0
- data/ext/apache2/Bucket.cpp +7 -5
- data/ext/apache2/Bucket.h +2 -1
- data/ext/apache2/Configuration.cpp +8 -0
- data/ext/apache2/Configuration.hpp +9 -5
- data/ext/apache2/HelperAgent.cpp +4 -5
- data/ext/apache2/Hooks.cpp +1 -6
- data/ext/boost/thread/exceptions.hpp +7 -1
- data/ext/boost/thread/locks.hpp +11 -11
- data/ext/common/AgentBase.cpp +21 -1
- data/ext/common/AgentsStarter.hpp +22 -21
- data/ext/common/ApplicationPool/Client.h +0 -8
- data/ext/common/ApplicationPool/Server.h +22 -21
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedMessageServer.h +6 -2
- data/ext/common/IniFile.h +4 -4
- data/ext/common/Logging.h +1 -1
- data/ext/common/LoggingAgent/LoggingServer.h +2 -2
- data/ext/common/LoggingAgent/Main.cpp +2 -2
- data/ext/common/MessageChannel.h +20 -62
- data/ext/common/MessageReadersWriters.h +4 -4
- data/ext/common/MessageServer.h +18 -18
- data/ext/common/Process.h +4 -5
- data/ext/common/Session.h +6 -40
- data/ext/common/SpawnManager.h +20 -25
- data/ext/common/Utils.cpp +1 -1
- data/ext/common/Utils/Dechunker.h +1 -1
- data/ext/common/Utils/MessageIO.h +109 -14
- data/ext/common/Utils/StreamBoyerMooreHorspool.h +20 -14
- data/ext/common/Utils/VariantMap.h +9 -27
- data/ext/common/Watchdog.cpp +53 -42
- data/ext/libev/config.h +122 -0
- data/ext/nginx/Configuration.c +62 -0
- data/ext/nginx/Configuration.h +5 -0
- data/ext/nginx/ContentHandler.c +46 -19
- data/ext/nginx/HelperAgent.cpp +6 -5
- data/ext/nginx/config +12 -12
- data/ext/oxt/system_calls.cpp +10 -1
- data/ext/ruby/extconf.rb +0 -1
- data/ext/ruby/passenger_native_support.c +2 -2
- data/helper-scripts/prespawn +1 -1
- data/lib/phusion_passenger.rb +4 -4
- data/lib/phusion_passenger/classic_rails/application_spawner.rb +2 -2
- data/lib/phusion_passenger/dependencies.rb +6 -1
- data/lib/phusion_passenger/platform_info.rb +9 -0
- data/lib/phusion_passenger/platform_info/compiler.rb +5 -0
- data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
- data/lib/phusion_passenger/platform_info/ruby.rb +5 -5
- data/lib/phusion_passenger/rack/application_spawner.rb +6 -3
- data/lib/phusion_passenger/utils.rb +2 -2
- data/lib/phusion_passenger/wsgi/application_spawner.rb +1 -1
- data/resources/mime.types +2 -0
- data/test/cxx/LoggingTest.cpp +10 -12
- data/test/cxx/MessageIOTest.cpp +53 -3
- data/test/cxx/MessageReadersWritersTest.cpp +5 -2
- data/test/cxx/MessageServerTest.cpp +3 -1
- data/test/integration_tests/nginx_tests.rb +14 -1
- data/test/stub/rack/config.ru +2 -0
- data/test/tut/tut.h +9 -3
- metadata +5 -4
data/doc/Users guide Nginx.html
CHANGED
@@ -2310,7 +2310,55 @@ applications, each which must be available at all times.</p></div>
|
|
2310
2310
|
The default value is <em>300</em>.</p></div>
|
2311
2311
|
</div>
|
2312
2312
|
<div class="sect3">
|
2313
|
-
<h4 id="
|
2313
|
+
<h4 id="PassengerMaxRequests">5.7.5. passenger_max_requests <integer></h4>
|
2314
|
+
<div class="paragraph"><p>The maximum number of requests an application instance will process. After
|
2315
|
+
serving that many requests, the application instance will be shut down and
|
2316
|
+
Phusion Passenger will restart it. A value of 0 means that there is no maximum:
|
2317
|
+
an application instance will thus be shut down when its idle timeout has been
|
2318
|
+
reached.</p></div>
|
2319
|
+
<div class="paragraph"><p>This option is useful if your application is leaking memory. By shutting
|
2320
|
+
it down after a certain number of requests, all of its memory is guaranteed
|
2321
|
+
to be freed by the operating system.</p></div>
|
2322
|
+
<div class="paragraph"><p>This option may occur in the following places:</p></div>
|
2323
|
+
<div class="ulist"><ul>
|
2324
|
+
<li>
|
2325
|
+
<p>
|
2326
|
+
In the <em>http</em> configuration block.
|
2327
|
+
</p>
|
2328
|
+
</li>
|
2329
|
+
<li>
|
2330
|
+
<p>
|
2331
|
+
In a <em>server</em> configuration block.
|
2332
|
+
</p>
|
2333
|
+
</li>
|
2334
|
+
<li>
|
2335
|
+
<p>
|
2336
|
+
In a <em>location</em> configuration block.
|
2337
|
+
</p>
|
2338
|
+
</li>
|
2339
|
+
<li>
|
2340
|
+
<p>
|
2341
|
+
In an <em>if</em> configuration scope.
|
2342
|
+
</p>
|
2343
|
+
</li>
|
2344
|
+
</ul></div>
|
2345
|
+
<div class="paragraph"><p>In each place, it may be specified at most once. The default value is <em>0</em>.</p></div>
|
2346
|
+
<div class="admonitionblock">
|
2347
|
+
<table><tr>
|
2348
|
+
<td class="icon">
|
2349
|
+
<img src="./images/icons/caution.png" alt="Caution">
|
2350
|
+
</td>
|
2351
|
+
<td class="content">
|
2352
|
+
<div class="paragraph"><p>The <a href="#PassengerMaxRequests">passenger_max_requests</a> directive should be considered
|
2353
|
+
as a workaround for misbehaving applications. It is advised that you fix the
|
2354
|
+
problem in your application rather than relying on these directives as a
|
2355
|
+
measure to avoid memory leaks.</p></div>
|
2356
|
+
</td>
|
2357
|
+
</tr></table>
|
2358
|
+
</div>
|
2359
|
+
</div>
|
2360
|
+
<div class="sect3">
|
2361
|
+
<h4 id="PassengerPreStart">5.7.6. passenger_pre_start <url></h4>
|
2314
2362
|
<div class="paragraph"><p>By default, Phusion Passenger does not start any application instances until said
|
2315
2363
|
web application is first accessed. The result is that the first visitor of said
|
2316
2364
|
web application might experience a small delay as Phusion Passenger is starting
|
@@ -3704,7 +3752,7 @@ has no effect.</p></div>
|
|
3704
3752
|
<div id="footnotes"><hr></div>
|
3705
3753
|
<div id="footer">
|
3706
3754
|
<div id="footer-text">
|
3707
|
-
Last updated 2011-
|
3755
|
+
Last updated 2011-09-15 09:09:01 CEST
|
3708
3756
|
</div>
|
3709
3757
|
</div>
|
3710
3758
|
</body>
|
data/doc/Users guide Nginx.txt
CHANGED
@@ -1032,6 +1032,35 @@ applications, each which must be available at all times.
|
|
1032
1032
|
This option may only occur once, in the 'http' configuration block.
|
1033
1033
|
The default value is '300'.
|
1034
1034
|
|
1035
|
+
[[PassengerMaxRequests]]
|
1036
|
+
==== passenger_max_requests <integer> ====
|
1037
|
+
The maximum number of requests an application instance will process. After
|
1038
|
+
serving that many requests, the application instance will be shut down and
|
1039
|
+
Phusion Passenger will restart it. A value of 0 means that there is no maximum:
|
1040
|
+
an application instance will thus be shut down when its idle timeout has been
|
1041
|
+
reached.
|
1042
|
+
|
1043
|
+
This option is useful if your application is leaking memory. By shutting
|
1044
|
+
it down after a certain number of requests, all of its memory is guaranteed
|
1045
|
+
to be freed by the operating system.
|
1046
|
+
|
1047
|
+
This option may occur in the following places:
|
1048
|
+
|
1049
|
+
* In the 'http' configuration block.
|
1050
|
+
* In a 'server' configuration block.
|
1051
|
+
* In a 'location' configuration block.
|
1052
|
+
* In an 'if' configuration scope.
|
1053
|
+
|
1054
|
+
In each place, it may be specified at most once. The default value is '0'.
|
1055
|
+
|
1056
|
+
[CAUTION]
|
1057
|
+
=====================================================
|
1058
|
+
The <<PassengerMaxRequests,passenger_max_requests>> directive should be considered
|
1059
|
+
as a workaround for misbehaving applications. It is advised that you fix the
|
1060
|
+
problem in your application rather than relying on these directives as a
|
1061
|
+
measure to avoid memory leaks.
|
1062
|
+
=====================================================
|
1063
|
+
|
1035
1064
|
[[PassengerPreStart]]
|
1036
1065
|
==== passenger_pre_start <url> ====
|
1037
1066
|
By default, Phusion Passenger does not start any application instances until said
|
data/ext/apache2/Bucket.cpp
CHANGED
@@ -44,6 +44,7 @@ struct BucketData {
|
|
44
44
|
SessionPtr session;
|
45
45
|
PassengerBucketStatePtr state;
|
46
46
|
int stream;
|
47
|
+
bool bufferResponse;
|
47
48
|
|
48
49
|
~BucketData() {
|
49
50
|
/* The session here is an ApplicationPoolServer::RemoteSession.
|
@@ -80,7 +81,7 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
80
81
|
*str = NULL;
|
81
82
|
*len = 0;
|
82
83
|
|
83
|
-
if (block == APR_NONBLOCK_READ) {
|
84
|
+
if (!data->bufferResponse && block == APR_NONBLOCK_READ) {
|
84
85
|
/*
|
85
86
|
* The bucket brigade that Hooks::handleRequest() passes using
|
86
87
|
* ap_pass_brigade() is always passed through ap_content_length_filter,
|
@@ -130,7 +131,7 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
130
131
|
* which can read the next chunk from the stream.
|
131
132
|
*/
|
132
133
|
APR_BUCKET_INSERT_AFTER(bucket, passenger_bucket_create(
|
133
|
-
data->session, data->state, bucket->list));
|
134
|
+
data->session, data->state, bucket->list, data->bufferResponse));
|
134
135
|
|
135
136
|
/* The newly created Passenger Bucket has a reference to the session
|
136
137
|
* object, so we can delete data here.
|
@@ -163,11 +164,12 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
|
|
163
164
|
}
|
164
165
|
|
165
166
|
static apr_bucket *
|
166
|
-
passenger_bucket_make(apr_bucket *bucket, SessionPtr session, PassengerBucketStatePtr state) {
|
167
|
+
passenger_bucket_make(apr_bucket *bucket, SessionPtr session, PassengerBucketStatePtr state, bool bufferResponse) {
|
167
168
|
BucketData *data = new BucketData();
|
168
169
|
data->session = session;
|
169
170
|
data->stream = session->getStream();
|
170
171
|
data->state = state;
|
172
|
+
data->bufferResponse = bufferResponse;
|
171
173
|
|
172
174
|
bucket->type = &apr_bucket_type_passenger_pipe;
|
173
175
|
bucket->length = (apr_size_t)(-1);
|
@@ -177,14 +179,14 @@ passenger_bucket_make(apr_bucket *bucket, SessionPtr session, PassengerBucketSta
|
|
177
179
|
}
|
178
180
|
|
179
181
|
apr_bucket *
|
180
|
-
passenger_bucket_create(SessionPtr session, PassengerBucketStatePtr state, apr_bucket_alloc_t *list) {
|
182
|
+
passenger_bucket_create(SessionPtr session, PassengerBucketStatePtr state, apr_bucket_alloc_t *list, bool bufferResponse) {
|
181
183
|
apr_bucket *bucket;
|
182
184
|
|
183
185
|
bucket = (apr_bucket *) apr_bucket_alloc(sizeof(*bucket), list);
|
184
186
|
APR_BUCKET_INIT(bucket);
|
185
187
|
bucket->free = apr_bucket_free;
|
186
188
|
bucket->list = list;
|
187
|
-
return passenger_bucket_make(bucket, session, state);
|
189
|
+
return passenger_bucket_make(bucket, session, state, bufferResponse);
|
188
190
|
}
|
189
191
|
|
190
192
|
} // namespace Passenger
|
data/ext/apache2/Bucket.h
CHANGED
@@ -80,7 +80,8 @@ typedef shared_ptr<PassengerBucketState> PassengerBucketStatePtr;
|
|
80
80
|
*/
|
81
81
|
apr_bucket *passenger_bucket_create(SessionPtr session,
|
82
82
|
PassengerBucketStatePtr state,
|
83
|
-
apr_bucket_alloc_t *list
|
83
|
+
apr_bucket_alloc_t *list,
|
84
|
+
bool bufferResponse);
|
84
85
|
|
85
86
|
} // namespace Passenger
|
86
87
|
|
@@ -209,6 +209,7 @@ passenger_config_create_dir(apr_pool_t *p, char *dirspec) {
|
|
209
209
|
config->uploadBufferDir = NULL;
|
210
210
|
config->friendlyErrorPages = DirConfig::UNSET;
|
211
211
|
config->unionStationSupport = DirConfig::UNSET;
|
212
|
+
config->bufferResponse = DirConfig::UNSET;
|
212
213
|
/*************************************/
|
213
214
|
return config;
|
214
215
|
}
|
@@ -259,6 +260,7 @@ passenger_config_merge_dir(apr_pool_t *p, void *basev, void *addv) {
|
|
259
260
|
MERGE_THREEWAY_CONFIG(allowEncodedSlashes);
|
260
261
|
MERGE_THREEWAY_CONFIG(friendlyErrorPages);
|
261
262
|
MERGE_THREEWAY_CONFIG(unionStationSupport);
|
263
|
+
MERGE_THREEWAY_CONFIG(bufferResponse);
|
262
264
|
/*************************************/
|
263
265
|
return config;
|
264
266
|
}
|
@@ -313,6 +315,7 @@ DEFINE_DIR_THREEWAY_CONFIG_SETTER(cmd_passenger_resolve_symlinks_in_document_roo
|
|
313
315
|
DEFINE_DIR_THREEWAY_CONFIG_SETTER(cmd_passenger_allow_encoded_slashes, allowEncodedSlashes)
|
314
316
|
DEFINE_DIR_THREEWAY_CONFIG_SETTER(cmd_passenger_friendly_error_pages, friendlyErrorPages)
|
315
317
|
DEFINE_DIR_THREEWAY_CONFIG_SETTER(cmd_union_station_support, unionStationSupport)
|
318
|
+
DEFINE_DIR_THREEWAY_CONFIG_SETTER(cmd_passenger_buffer_response, bufferResponse)
|
316
319
|
|
317
320
|
static const char *
|
318
321
|
cmd_passenger_spawn_method(cmd_parms *cmd, void *pcfg, const char *arg) {
|
@@ -586,6 +589,11 @@ const command_rec passenger_commands[] = {
|
|
586
589
|
NULL,
|
587
590
|
OR_ALL,
|
588
591
|
"A filter for Union Station data."),
|
592
|
+
AP_INIT_FLAG("PassengerBufferResponse",
|
593
|
+
(FlagFunc) cmd_passenger_buffer_response,
|
594
|
+
NULL,
|
595
|
+
OR_ALL,
|
596
|
+
"Whether to enable buffering response."),
|
589
597
|
AP_INIT_FLAG("PassengerResolveSymlinksInDocumentRoot",
|
590
598
|
(FlagFunc) cmd_passenger_resolve_symlinks_in_document_root,
|
591
599
|
NULL,
|
@@ -26,17 +26,12 @@
|
|
26
26
|
#define _PASSENGER_CONFIGURATION_HPP_
|
27
27
|
|
28
28
|
#include "Utils.h"
|
29
|
-
#include "MessageChannel.h"
|
30
29
|
#include "Logging.h"
|
31
30
|
#include "ServerInstanceDir.h"
|
32
31
|
#include "Constants.h"
|
33
32
|
|
34
33
|
/* The APR headers must come after the Passenger headers. See Hooks.cpp
|
35
34
|
* to learn why.
|
36
|
-
*
|
37
|
-
* MessageChannel.h must be included -- even though we don't actually use
|
38
|
-
* MessageChannel.h in here, it's necessary to make sure that apr_want.h
|
39
|
-
* doesn't b0rk on 'struct iovec'.
|
40
35
|
*/
|
41
36
|
#include "Configuration.h"
|
42
37
|
|
@@ -197,6 +192,11 @@ struct DirConfig {
|
|
197
192
|
*/
|
198
193
|
Threeway unionStationSupport;
|
199
194
|
|
195
|
+
/**
|
196
|
+
* Whether response buffering support is enabled.
|
197
|
+
*/
|
198
|
+
Threeway bufferResponse;
|
199
|
+
|
200
200
|
/*************************************/
|
201
201
|
/*************************************/
|
202
202
|
|
@@ -332,6 +332,10 @@ struct DirConfig {
|
|
332
332
|
bool useUnionStation() const {
|
333
333
|
return unionStationSupport == ENABLED;
|
334
334
|
}
|
335
|
+
|
336
|
+
bool getBufferResponse() const {
|
337
|
+
return bufferResponse != DISABLED;
|
338
|
+
}
|
335
339
|
|
336
340
|
string getUnionStationFilterString() const {
|
337
341
|
if (unionStationFilters.empty()) {
|
data/ext/apache2/HelperAgent.cpp
CHANGED
@@ -49,12 +49,12 @@
|
|
49
49
|
#include "MessageServer.h"
|
50
50
|
#include "ServerInstanceDir.h"
|
51
51
|
#include "ResourceLocator.h"
|
52
|
-
#include "MessageChannel.h"
|
53
52
|
#include "FileDescriptor.h"
|
54
53
|
#include "Logging.h"
|
55
54
|
#include "Exceptions.h"
|
56
55
|
#include "Utils.h"
|
57
56
|
#include "Utils/Timer.h"
|
57
|
+
#include "Utils/MessageIO.h"
|
58
58
|
|
59
59
|
using namespace std;
|
60
60
|
using namespace boost;
|
@@ -137,7 +137,6 @@ private:
|
|
137
137
|
ServerInstanceDir serverInstanceDir;
|
138
138
|
ServerInstanceDir::GenerationPtr generation;
|
139
139
|
FileDescriptor feedbackFd;
|
140
|
-
MessageChannel feedbackChannel;
|
141
140
|
AnalyticsLoggerPtr analyticsLogger;
|
142
141
|
AccountsDatabasePtr accountsDatabase;
|
143
142
|
MessageServerPtr messageServer;
|
@@ -152,7 +151,7 @@ private:
|
|
152
151
|
TRACE_POINT();
|
153
152
|
vector<string> args;
|
154
153
|
|
155
|
-
if (!
|
154
|
+
if (!readArrayMessage(feedbackFd, args)) {
|
156
155
|
throw IOException("The watchdog unexpectedly closed the connection.");
|
157
156
|
}
|
158
157
|
if (args[0] != "request socket password" && args[0] != "message socket password") {
|
@@ -218,7 +217,6 @@ public:
|
|
218
217
|
string loggingAgentPassword;
|
219
218
|
|
220
219
|
this->feedbackFd = feedbackFd;
|
221
|
-
feedbackChannel = MessageChannel(feedbackFd);
|
222
220
|
|
223
221
|
UPDATE_TRACE_POINT();
|
224
222
|
messageSocketPassword = Base64::decode(options.get("message_socket_password"));
|
@@ -259,7 +257,8 @@ public:
|
|
259
257
|
messageServer->addHandler(ptr(new ExitHandler(exitEvent)));
|
260
258
|
|
261
259
|
UPDATE_TRACE_POINT();
|
262
|
-
|
260
|
+
writeArrayMessage(feedbackFd,
|
261
|
+
"initialized",
|
263
262
|
"", // Request socket filename; not available in the Apache helper server.
|
264
263
|
messageServer->getSocketFilename().c_str(),
|
265
264
|
NULL);
|
data/ext/apache2/Hooks.cpp
CHANGED
@@ -54,16 +54,11 @@
|
|
54
54
|
#include "Logging.h"
|
55
55
|
#include "AgentsStarter.hpp"
|
56
56
|
#include "ApplicationPool/Client.h"
|
57
|
-
#include "MessageChannel.h"
|
58
57
|
#include "DirectoryMapper.h"
|
59
58
|
#include "Constants.h"
|
60
59
|
|
61
60
|
/* The Apache/APR headers *must* come after the Boost headers, otherwise
|
62
61
|
* compilation will fail on OpenBSD.
|
63
|
-
*
|
64
|
-
* apr_want.h *must* come after MessageChannel.h, otherwise compilation will
|
65
|
-
* fail on platforms on which apr_want.h tries to redefine 'struct iovec'.
|
66
|
-
* http://groups.google.com/group/phusion-passenger/browse_thread/thread/7e162f60df212e9c
|
67
62
|
*/
|
68
63
|
#include <ap_config.h>
|
69
64
|
#include <ap_release.h>
|
@@ -726,7 +721,7 @@ private:
|
|
726
721
|
/* Setup the bucket brigade. */
|
727
722
|
bucketState = ptr(new PassengerBucketState());
|
728
723
|
bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
|
729
|
-
b = passenger_bucket_create(session, bucketState, r->connection->bucket_alloc);
|
724
|
+
b = passenger_bucket_create(session, bucketState, r->connection->bucket_alloc, config->getBufferResponse());
|
730
725
|
|
731
726
|
/* The bucket (b) still has a reference to the session, so the reset()
|
732
727
|
* call here is guaranteed not to throw any exceptions.
|
@@ -38,7 +38,7 @@ namespace boost
|
|
38
38
|
std::string message;
|
39
39
|
|
40
40
|
thread_exception():
|
41
|
-
m_sys_err(
|
41
|
+
m_sys_err(-1)
|
42
42
|
{}
|
43
43
|
|
44
44
|
thread_exception(const std::string &description, int sys_err_code):
|
@@ -107,6 +107,12 @@ namespace boost
|
|
107
107
|
thread_exception(sys_err_code)
|
108
108
|
{}
|
109
109
|
|
110
|
+
lock_error(const std::string &message)
|
111
|
+
{
|
112
|
+
this->message = "boost::lock_error: ";
|
113
|
+
this->message.append(message);
|
114
|
+
}
|
115
|
+
|
110
116
|
~lock_error() throw()
|
111
117
|
{}
|
112
118
|
|
data/ext/boost/thread/locks.hpp
CHANGED
@@ -407,7 +407,7 @@ namespace boost
|
|
407
407
|
{
|
408
408
|
if(owns_lock())
|
409
409
|
{
|
410
|
-
boost::throw_exception(boost::lock_error());
|
410
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
411
411
|
}
|
412
412
|
m->lock();
|
413
413
|
is_locked=true;
|
@@ -416,7 +416,7 @@ namespace boost
|
|
416
416
|
{
|
417
417
|
if(owns_lock())
|
418
418
|
{
|
419
|
-
boost::throw_exception(boost::lock_error());
|
419
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
420
420
|
}
|
421
421
|
is_locked=m->try_lock();
|
422
422
|
return is_locked;
|
@@ -442,7 +442,7 @@ namespace boost
|
|
442
442
|
{
|
443
443
|
if(!owns_lock())
|
444
444
|
{
|
445
|
-
boost::throw_exception(boost::lock_error());
|
445
|
+
boost::throw_exception(boost::lock_error("lock not owned"));
|
446
446
|
}
|
447
447
|
m->unlock();
|
448
448
|
is_locked=false;
|
@@ -650,7 +650,7 @@ namespace boost
|
|
650
650
|
{
|
651
651
|
if(owns_lock())
|
652
652
|
{
|
653
|
-
boost::throw_exception(boost::lock_error());
|
653
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
654
654
|
}
|
655
655
|
m->lock_shared();
|
656
656
|
is_locked=true;
|
@@ -659,7 +659,7 @@ namespace boost
|
|
659
659
|
{
|
660
660
|
if(owns_lock())
|
661
661
|
{
|
662
|
-
boost::throw_exception(boost::lock_error());
|
662
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
663
663
|
}
|
664
664
|
is_locked=m->try_lock_shared();
|
665
665
|
return is_locked;
|
@@ -668,7 +668,7 @@ namespace boost
|
|
668
668
|
{
|
669
669
|
if(owns_lock())
|
670
670
|
{
|
671
|
-
boost::throw_exception(boost::lock_error());
|
671
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
672
672
|
}
|
673
673
|
is_locked=m->timed_lock_shared(target_time);
|
674
674
|
return is_locked;
|
@@ -678,7 +678,7 @@ namespace boost
|
|
678
678
|
{
|
679
679
|
if(owns_lock())
|
680
680
|
{
|
681
|
-
boost::throw_exception(boost::lock_error());
|
681
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
682
682
|
}
|
683
683
|
is_locked=m->timed_lock_shared(target_time);
|
684
684
|
return is_locked;
|
@@ -687,7 +687,7 @@ namespace boost
|
|
687
687
|
{
|
688
688
|
if(!owns_lock())
|
689
689
|
{
|
690
|
-
boost::throw_exception(boost::lock_error());
|
690
|
+
boost::throw_exception(boost::lock_error("lock not owned"));
|
691
691
|
}
|
692
692
|
m->unlock_shared();
|
693
693
|
is_locked=false;
|
@@ -847,7 +847,7 @@ namespace boost
|
|
847
847
|
{
|
848
848
|
if(owns_lock())
|
849
849
|
{
|
850
|
-
boost::throw_exception(boost::lock_error());
|
850
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
851
851
|
}
|
852
852
|
m->lock_upgrade();
|
853
853
|
is_locked=true;
|
@@ -856,7 +856,7 @@ namespace boost
|
|
856
856
|
{
|
857
857
|
if(owns_lock())
|
858
858
|
{
|
859
|
-
boost::throw_exception(boost::lock_error());
|
859
|
+
boost::throw_exception(boost::lock_error("lock already owned"));
|
860
860
|
}
|
861
861
|
is_locked=m->try_lock_upgrade();
|
862
862
|
return is_locked;
|
@@ -865,7 +865,7 @@ namespace boost
|
|
865
865
|
{
|
866
866
|
if(!owns_lock())
|
867
867
|
{
|
868
|
-
boost::throw_exception(boost::lock_error());
|
868
|
+
boost::throw_exception(boost::lock_error("lock not owned"));
|
869
869
|
}
|
870
870
|
m->unlock_upgrade();
|
871
871
|
is_locked=false;
|
data/ext/common/AgentBase.cpp
CHANGED
@@ -66,6 +66,24 @@ ignoreSigpipe() {
|
|
66
66
|
sigaction(SIGPIPE, &action, NULL);
|
67
67
|
}
|
68
68
|
|
69
|
+
static bool
|
70
|
+
hasEnvOption(const char *name, bool defaultValue = false) {
|
71
|
+
const char *value = getenv(name);
|
72
|
+
if (value != NULL) {
|
73
|
+
if (*value != '\0') {
|
74
|
+
return strcmp(value, "yes") == 0
|
75
|
+
|| strcmp(value, "y") == 0
|
76
|
+
|| strcmp(value, "1") == 0
|
77
|
+
|| strcmp(value, "on") == 0
|
78
|
+
|| strcmp(value, "true") == 0;
|
79
|
+
} else {
|
80
|
+
return defaultValue;
|
81
|
+
}
|
82
|
+
} else {
|
83
|
+
return defaultValue;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
69
87
|
// No idea whether strlen() is async signal safe, but let's not risk it
|
70
88
|
// and write our own version instead that's guaranteed to be safe.
|
71
89
|
static size_t
|
@@ -328,7 +346,9 @@ initializeAgent(int argc, char *argv[], const char *processName) {
|
|
328
346
|
VariantMap options;
|
329
347
|
|
330
348
|
ignoreSigpipe();
|
331
|
-
|
349
|
+
if (hasEnvOption("PASSENGER_ABORT_HANDLER", true)) {
|
350
|
+
installAbortHandler();
|
351
|
+
}
|
332
352
|
setup_syscall_interruption_support();
|
333
353
|
setvbuf(stdout, NULL, _IONBF, 0);
|
334
354
|
setvbuf(stderr, NULL, _IONBF, 0);
|