passenger 5.3.6 → 5.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +10 -0
- data/CONTRIBUTORS +1 -0
- data/build/support/cxx_dependency_map.rb +5 -0
- data/src/agent/Core/AdminPanelConnector.h +1 -1
- data/src/agent/Core/ApplicationPool/Group.h +2 -2
- data/src/agent/Core/ApplicationPool/Group/InternalUtils.cpp +2 -2
- data/src/agent/Core/ApplicationPool/Group/OutOfBandWork.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Socket.h +2 -2
- data/src/agent/Core/Config.h +1 -1
- data/src/agent/Core/Controller/Config.h +1 -1
- data/src/agent/Core/Controller/ForwardResponse.cpp +4 -0
- data/src/agent/Core/Controller/SendRequest.cpp +7 -7
- data/src/agent/Core/SecurityUpdateChecker.h +2 -0
- data/src/agent/Core/SpawningKit/DirectSpawner.h +1 -1
- data/src/agent/Core/SpawningKit/Exceptions.h +4 -0
- data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -1
- data/src/agent/Shared/Fundamentals/AbortHandler.cpp +18 -18
- data/src/agent/Shared/Fundamentals/AbortHandler.h +13 -1
- data/src/agent/Shared/Fundamentals/Initialization.cpp +0 -1
- data/src/agent/Shared/Fundamentals/Initialization.h +9 -1
- data/src/agent/TempDirToucher/TempDirToucherMain.cpp +3 -3
- data/src/agent/Watchdog/Config.h +1 -1
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/ServerKit/Server.h +0 -1
- data/src/cxx_supportlib/StrIntTools/StrIntUtilsNoStrictAliasing.cpp +10 -10
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- metadata +2 -3
- data/src/cxx_supportlib/vendor-modified/SmallVector.h +0 -653
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 857ea86d5ea2297a7491238a392c0a7d9e348542
|
4
|
+
data.tar.gz: a89b76d3df1a388920eb760a87b1a99346141f89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33bcfb347239ec371251917e7321b26459ebadc7d4d06fcfbbcb692e65a1554d8fb4ba3bae6f4857121d0ecc98a806597ac89fc4fc2b22bafc5fdebabb504a99
|
7
|
+
data.tar.gz: 15106f30ef5d620c369362a8e1763cd6d4a7a9af1d449ec24441b3406aaf07788e390a83a62e93a98cf17cb437d70b1ad7a52ad5eef1c77d99408bc63e0dd9bc
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
Release 5.3.7
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* Fixes package installation issues on Ubuntu 18.04. These issues were caused by an update released by Ubuntu on the nginx-common package. Closes GH-2122, GH-2140.
|
5
|
+
* Fixes compilation problems and warnings with GCC 8.2. Tested on Alpine Linux edge 2018-11-05. Closes GH-2139.
|
6
|
+
* Fixes compatibility with libcurl 7.62.0. Contributed by Po-Chuan Hsieh (@sunpoet).
|
7
|
+
* Changes minimum supported macOS version to 10.11 El Capitan.
|
8
|
+
* Removes packages for Ubuntu 17.10 Artful.
|
9
|
+
|
10
|
+
|
1
11
|
Release 5.3.6
|
2
12
|
-------------
|
3
13
|
|
data/CONTRIBUTORS
CHANGED
@@ -7752,6 +7752,7 @@ CXX_DEPENDENCY_MAP =
|
|
7752
7752
|
"src/cxx_supportlib/StrIntTools/DateParsing.h",
|
7753
7753
|
"src/cxx_supportlib/StrIntTools/StrIntUtils.h",
|
7754
7754
|
"src/cxx_supportlib/StrIntTools/StringScanning.h",
|
7755
|
+
"src/cxx_supportlib/SystemTools/ContainerHelpers.h",
|
7755
7756
|
"src/cxx_supportlib/SystemTools/ProcessMetricsCollector.h",
|
7756
7757
|
"src/cxx_supportlib/SystemTools/SystemMetricsCollector.h",
|
7757
7758
|
"src/cxx_supportlib/SystemTools/SystemTime.h",
|
@@ -9940,6 +9941,10 @@ CXX_DEPENDENCY_MAP =
|
|
9940
9941
|
"src/cxx_supportlib/StaticString.h",
|
9941
9942
|
"src/cxx_supportlib/StrIntTools/StrIntUtils.h",
|
9942
9943
|
"src/cxx_supportlib/oxt/macros.hpp"],
|
9944
|
+
"src/cxx_supportlib/SystemTools/ContainerHelpers.h"=>
|
9945
|
+
["src/cxx_supportlib/FileTools/FileManip.h",
|
9946
|
+
"src/cxx_supportlib/StaticString.h",
|
9947
|
+
"src/cxx_supportlib/oxt/macros.hpp"],
|
9943
9948
|
"src/cxx_supportlib/SystemTools/ProcessMetricsCollector.h"=>
|
9944
9949
|
["src/cxx_supportlib/Algorithms/Hasher.h",
|
9945
9950
|
"src/cxx_supportlib/DataStructures/HashedStaticString.h",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2011-
|
3
|
+
* Copyright (c) 2011-2018 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -36,6 +36,7 @@
|
|
36
36
|
#include <boost/shared_ptr.hpp>
|
37
37
|
#include <boost/make_shared.hpp>
|
38
38
|
#include <boost/container/vector.hpp>
|
39
|
+
#include <boost/container/small_vector.hpp>
|
39
40
|
#include <boost/atomic.hpp>
|
40
41
|
#include <oxt/macros.hpp>
|
41
42
|
#include <oxt/thread.hpp>
|
@@ -44,7 +45,6 @@
|
|
44
45
|
#include <sys/stat.h>
|
45
46
|
#include <cstdlib>
|
46
47
|
#include <cassert>
|
47
|
-
#include <SmallVector.h>
|
48
48
|
#include <MemoryKit/palloc.h>
|
49
49
|
#include <WrapperRegistry/Registry.h>
|
50
50
|
#include <Hooks.h>
|
@@ -295,7 +295,7 @@ Group::assignSessionsToGetWaitersQuickly(Lock &lock) {
|
|
295
295
|
return;
|
296
296
|
}
|
297
297
|
|
298
|
-
|
298
|
+
boost::container::small_vector<GetAction, 8> actions;
|
299
299
|
unsigned int i = 0;
|
300
300
|
bool done = false;
|
301
301
|
|
@@ -320,7 +320,7 @@ Group::assignSessionsToGetWaitersQuickly(Lock &lock) {
|
|
320
320
|
|
321
321
|
verifyInvariants();
|
322
322
|
lock.unlock();
|
323
|
-
|
323
|
+
boost::container::small_vector<GetAction, 50>::const_iterator it, end = actions.end();
|
324
324
|
for (it = actions.begin(); it != end; it++) {
|
325
325
|
it->callback(it->session, ExceptionPtr());
|
326
326
|
}
|
@@ -228,7 +228,7 @@ Group::spawnThreadOOBWRequest(GroupPtr self, ProcessPtr process) {
|
|
228
228
|
// This is copied from Core::Controller when it is sending data using the
|
229
229
|
// "session" protocol.
|
230
230
|
char sizeField[sizeof(boost::uint32_t)];
|
231
|
-
|
231
|
+
boost::container::small_vector<StaticString, 10> data;
|
232
232
|
|
233
233
|
data.push_back(StaticString(sizeField, sizeof(boost::uint32_t)));
|
234
234
|
data.push_back(P_STATIC_STRING_WITH_NULL("REQUEST_METHOD"));
|
@@ -31,9 +31,9 @@
|
|
31
31
|
#include <boost/thread.hpp>
|
32
32
|
#include <boost/shared_ptr.hpp>
|
33
33
|
#include <boost/weak_ptr.hpp>
|
34
|
+
#include <boost/container/small_vector.hpp>
|
34
35
|
#include <climits>
|
35
36
|
#include <cassert>
|
36
|
-
#include <SmallVector.h>
|
37
37
|
#include <LoggingKit/LoggingKit.h>
|
38
38
|
#include <StaticString.h>
|
39
39
|
#include <MemoryKit/palloc.h>
|
@@ -263,7 +263,7 @@ public:
|
|
263
263
|
}
|
264
264
|
};
|
265
265
|
|
266
|
-
class SocketList: public
|
266
|
+
class SocketList: public boost::container::small_vector<Socket, 1> {
|
267
267
|
public:
|
268
268
|
void add(pid_t pid, const StaticString &address, const StaticString &protocol,
|
269
269
|
const StaticString &description, int concurrency, bool acceptHttpRequests)
|
data/src/agent/Core/Config.h
CHANGED
@@ -157,7 +157,7 @@ using namespace std;
|
|
157
157
|
* security_update_checker_interval unsigned integer - default(86400)
|
158
158
|
* security_update_checker_proxy_url string - -
|
159
159
|
* security_update_checker_url string - default("https://securitycheck.phusionpassenger.com/v1/check.json")
|
160
|
-
* server_software string - default("Phusion_Passenger/5.3.
|
160
|
+
* server_software string - default("Phusion_Passenger/5.3.7")
|
161
161
|
* show_version_in_header boolean - default(true)
|
162
162
|
* single_app_mode_app_root string - default,read_only
|
163
163
|
* single_app_mode_app_type string - read_only
|
@@ -113,7 +113,7 @@ parseControllerBenchmarkMode(const StaticString &mode) {
|
|
113
113
|
* multi_app boolean - default(true),read_only
|
114
114
|
* request_freelist_limit unsigned integer - default(1024)
|
115
115
|
* response_buffer_high_watermark unsigned integer - default(134217728)
|
116
|
-
* server_software string - default("Phusion_Passenger/5.3.
|
116
|
+
* server_software string - default("Phusion_Passenger/5.3.7")
|
117
117
|
* show_version_in_header boolean - default(true)
|
118
118
|
* start_reading_after_accept boolean - default(true)
|
119
119
|
* stat_throttle_rate unsigned integer - default(10)
|
@@ -278,6 +278,7 @@ Controller::onAppSourceData(Client *client, Request *req, const MemoryKit::mbuf
|
|
278
278
|
endRequestWithAppSocketReadError(&client, &req, errcode);
|
279
279
|
return Channel::Result(0, true);
|
280
280
|
}
|
281
|
+
break; // Never reached, shut up compiler warning.
|
281
282
|
|
282
283
|
case AppResponse::PARSING_BODY_UNTIL_EOF:
|
283
284
|
case AppResponse::UPGRADED:
|
@@ -305,11 +306,14 @@ Controller::onAppSourceData(Client *client, Request *req, const MemoryKit::mbuf
|
|
305
306
|
endRequestWithAppSocketReadError(&client, &req, errcode);
|
306
307
|
return Channel::Result(0, false);
|
307
308
|
}
|
309
|
+
break; // Never reached, shut up compiler warning.
|
308
310
|
|
309
311
|
default:
|
310
312
|
P_BUG("Invalid request HTTP state " << (int) resp->httpState);
|
311
313
|
return Channel::Result(0, false);
|
312
314
|
}
|
315
|
+
|
316
|
+
return Channel::Result(0, false); // Never reached, shut up compiler warning.
|
313
317
|
}
|
314
318
|
|
315
319
|
void
|
@@ -305,13 +305,13 @@ httpHeaderToScgiUpperCase(unsigned char *data, unsigned int size) {
|
|
305
305
|
|
306
306
|
i = imax * 8;
|
307
307
|
switch (leftover) {
|
308
|
-
case 7: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
309
|
-
case 6: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
310
|
-
case 5: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
311
|
-
case 4: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
312
|
-
case 3: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
313
|
-
case 2: *data++ = (unsigned char) toUpperMap[buf[i++]];
|
314
|
-
case 1: *data++ = (unsigned char) toUpperMap[buf[i]];
|
308
|
+
case 7: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
309
|
+
case 6: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
310
|
+
case 5: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
311
|
+
case 4: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
312
|
+
case 3: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
313
|
+
case 2: *data++ = (unsigned char) toUpperMap[buf[i++]]; /* Falls through. */
|
314
|
+
case 1: *data++ = (unsigned char) toUpperMap[buf[i]]; /* Falls through. */
|
315
315
|
case 0: break;
|
316
316
|
}
|
317
317
|
}
|
@@ -256,9 +256,11 @@ private:
|
|
256
256
|
error.append(" for proxy address " + sessionState.config["proxy_url"].asString());
|
257
257
|
break;
|
258
258
|
|
259
|
+
#if LIBCURL_VERSION_NUM < 0x073e00
|
259
260
|
case CURLE_SSL_CACERT:
|
260
261
|
// Peer certificate cannot be authenticated with given / known CA certificates. This would happen
|
261
262
|
// for MITM but could also be a truststore issue.
|
263
|
+
#endif
|
262
264
|
case CURLE_PEER_FAILED_VERIFICATION:
|
263
265
|
// The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK.
|
264
266
|
error.append(" while connecting to " + sessionState.configRlz.url
|
@@ -122,6 +122,7 @@ private:
|
|
122
122
|
message = "A timeout occurred while spawning an application process";
|
123
123
|
break;
|
124
124
|
}
|
125
|
+
break;
|
125
126
|
default:
|
126
127
|
string categoryPhraseWithIndefiniteArticle =
|
127
128
|
getErrorCategoryPhraseWithIndefiniteArticle(
|
@@ -138,6 +139,7 @@ private:
|
|
138
139
|
+ " occurred while starting a preloader process";
|
139
140
|
break;
|
140
141
|
}
|
142
|
+
break;
|
141
143
|
default:
|
142
144
|
switch (journey.getFirstFailedStep()) {
|
143
145
|
case SPAWNING_KIT_PREPARATION:
|
@@ -173,7 +175,9 @@ private:
|
|
173
175
|
+ " occurred while spawning an application process";
|
174
176
|
break;
|
175
177
|
}
|
178
|
+
break;
|
176
179
|
}
|
180
|
+
break;
|
177
181
|
}
|
178
182
|
|
179
183
|
if (advancedProblemDetails.empty()) {
|
@@ -357,9 +357,9 @@ dumpUlimits(AbortHandlerWorkingState &state) {
|
|
357
357
|
dup2(fd, STDERR_FILENO);
|
358
358
|
}
|
359
359
|
closeAllFileDescriptors(2, true);
|
360
|
-
execlp("ulimit", "ulimit", "-a", (
|
360
|
+
execlp("ulimit", "ulimit", "-a", (char *) 0);
|
361
361
|
// On Linux 'ulimit' is a shell builtin, not a command.
|
362
|
-
execlp("/bin/sh", "/bin/sh", "-c", "ulimit -a", (
|
362
|
+
execlp("/bin/sh", "/bin/sh", "-c", "ulimit -a", (char *) 0);
|
363
363
|
_exit(1);
|
364
364
|
} else if (pid == -1) {
|
365
365
|
ASSU::printError("ERROR: Could not fork a process to dump the ulimit!\n");
|
@@ -393,7 +393,7 @@ dumpFileDescriptorInfoWithLsof(AbortHandlerWorkingState &state, void *userData)
|
|
393
393
|
|
394
394
|
closeAllFileDescriptors(2, true);
|
395
395
|
|
396
|
-
execlp("lsof", "lsof", "-p", state.messageBuf, "-nP", (
|
396
|
+
execlp("lsof", "lsof", "-p", state.messageBuf, "-nP", (char *) 0);
|
397
397
|
|
398
398
|
const char *command[] = { "lsof", NULL };
|
399
399
|
printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
|
@@ -432,7 +432,7 @@ dumpFileDescriptorInfoWithLs(AbortHandlerWorkingState &state, const char *path)
|
|
432
432
|
|
433
433
|
closeAllFileDescriptors(2, true);
|
434
434
|
// The '-v' is for natural sorting on Linux. On BSD -v means something else but it's harmless.
|
435
|
-
execlp("ls", "ls", "-lv", path, (
|
435
|
+
execlp("ls", "ls", "-lv", path, (char *) 0);
|
436
436
|
|
437
437
|
const char *command[] = { "ls", NULL };
|
438
438
|
printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
|
@@ -520,7 +520,7 @@ dumpWithCrashWatch(AbortHandlerWorkingState &state) {
|
|
520
520
|
execlp(ctx->config->ruby, ctx->config->ruby, ctx->crashWatchCommand,
|
521
521
|
ctx->rubyLibDir, ctx->installSpec, "--dump",
|
522
522
|
state.messageBuf, // PID string
|
523
|
-
(char *
|
523
|
+
(char *) 0);
|
524
524
|
|
525
525
|
const char *command[] = { "crash-watch", NULL };
|
526
526
|
printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
|
@@ -598,16 +598,16 @@ dumpWithCrashWatch(AbortHandlerWorkingState &state) {
|
|
598
598
|
}
|
599
599
|
*pos = '\0';
|
600
600
|
pos++;
|
601
|
-
execlp("/bin/sh", "/bin/sh", "-c", command, (
|
601
|
+
execlp("/bin/sh", "/bin/sh", "-c", command, (char *) 0);
|
602
602
|
|
603
603
|
pos = state.messageBuf;
|
604
604
|
pos = ASSU::appendData(pos, end, "ERROR: cannot execute '");
|
605
605
|
pos = ASSU::appendData(pos, end, ctx->backtraceSanitizerCommand);
|
606
606
|
pos = ASSU::appendData(pos, end, "' for sanitizing the backtrace, trying 'cat'...\n");
|
607
607
|
write_nowarn(STDERR_FILENO, state.messageBuf, pos - state.messageBuf);
|
608
|
-
execlp("cat", "cat", (
|
609
|
-
execlp("/bin/cat", "cat", (
|
610
|
-
execlp("/usr/bin/cat", "cat", (
|
608
|
+
execlp("cat", "cat", (char *) 0);
|
609
|
+
execlp("/bin/cat", "cat", (char *) 0);
|
610
|
+
execlp("/usr/bin/cat", "cat", (char *) 0);
|
611
611
|
|
612
612
|
const char *commandArray[] = { "cat", NULL };
|
613
613
|
printExecError2(commandArray, errno, state.messageBuf, sizeof(state.messageBuf));
|
@@ -686,7 +686,7 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
|
|
686
686
|
pid = asyncFork();
|
687
687
|
if (pid == 0) {
|
688
688
|
closeAllFileDescriptors(2, true);
|
689
|
-
execlp("date", "date", (
|
689
|
+
execlp("date", "date", (char *) 0);
|
690
690
|
_exit(1);
|
691
691
|
} else if (pid == -1) {
|
692
692
|
ASSU::printError("ERROR: Could not fork a process to dump the time!\n");
|
@@ -698,7 +698,7 @@ dumpDiagnostics(AbortHandlerWorkingState &state) {
|
|
698
698
|
pid = asyncFork();
|
699
699
|
if (pid == 0) {
|
700
700
|
closeAllFileDescriptors(2, true);
|
701
|
-
execlp("uname", "uname", "-mprsv", (
|
701
|
+
execlp("uname", "uname", "-mprsv", (char *) 0);
|
702
702
|
_exit(1);
|
703
703
|
} else if (pid == -1) {
|
704
704
|
ASSU::printError("ERROR: Could not fork a process to dump the uname!\n");
|
@@ -891,11 +891,11 @@ forkAndRedirectToTeeAndMainLogFile(const char *crashLogDir) {
|
|
891
891
|
if (pid == 0) {
|
892
892
|
close(p[1]);
|
893
893
|
dup2(p[0], STDIN_FILENO);
|
894
|
-
execlp("tee", "tee", filename, (
|
895
|
-
execlp("/usr/bin/tee", "tee", filename, (
|
896
|
-
execlp("cat", "cat", (
|
897
|
-
execlp("/bin/cat", "cat", (
|
898
|
-
execlp("/usr/bin/cat", "cat", (
|
894
|
+
execlp("tee", "tee", filename, (char *) 0);
|
895
|
+
execlp("/usr/bin/tee", "tee", filename, (char *) 0);
|
896
|
+
execlp("cat", "cat", (char *) 0);
|
897
|
+
execlp("/bin/cat", "cat", (char *) 0);
|
898
|
+
execlp("/usr/bin/cat", "cat", (char *) 0);
|
899
899
|
ASSU::printError("ERROR: cannot execute 'tee' or 'cat'; crash log will be lost!\n");
|
900
900
|
_exit(1);
|
901
901
|
return false;
|
@@ -1031,11 +1031,11 @@ abortHandler(int signo, siginfo_t *info, void *_unused) {
|
|
1031
1031
|
closeAllFileDescriptors(2, true);
|
1032
1032
|
#ifdef __APPLE__
|
1033
1033
|
const char *command[] = { "osascript", NULL };
|
1034
|
-
execlp("osascript", "osascript", "-e", "beep 2", (
|
1034
|
+
execlp("osascript", "osascript", "-e", "beep 2", (char *) 0);
|
1035
1035
|
printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
|
1036
1036
|
#else
|
1037
1037
|
const char *command[] = { "beep", NULL };
|
1038
|
-
execlp("beep", "beep", (
|
1038
|
+
execlp("beep", "beep", (char *) 0);
|
1039
1039
|
printExecError2(command, errno, state.messageBuf, sizeof(state.messageBuf));
|
1040
1040
|
#endif
|
1041
1041
|
_exit(1);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-
|
3
|
+
* Copyright (c) 2010-2018 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -26,6 +26,8 @@
|
|
26
26
|
#ifndef _PASSENGER_AGENT_FUNDAMENTALS_ABORT_HANDLER_H_
|
27
27
|
#define _PASSENGER_AGENT_FUNDAMENTALS_ABORT_HANDLER_H_
|
28
28
|
|
29
|
+
#include <cstddef>
|
30
|
+
|
29
31
|
namespace Passenger {
|
30
32
|
class ResourceLocator;
|
31
33
|
}
|
@@ -62,6 +64,16 @@ struct AbortHandlerConfig {
|
|
62
64
|
bool stopProcess;
|
63
65
|
ResourceLocator *resourceLocator;
|
64
66
|
DiagnosticsDumper diagnosticsDumpers[MAX_DIAGNOSTICS_DUMPERS];
|
67
|
+
|
68
|
+
AbortHandlerConfig()
|
69
|
+
: ruby(NULL),
|
70
|
+
origArgv(NULL),
|
71
|
+
randomSeed(0),
|
72
|
+
dumpWithCrashWatch(false),
|
73
|
+
beep(false),
|
74
|
+
stopProcess(false),
|
75
|
+
resourceLocator(NULL)
|
76
|
+
{ }
|
65
77
|
};
|
66
78
|
|
67
79
|
void installAbortHandler(const AbortHandlerConfig *config);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2010-
|
3
|
+
* Copyright (c) 2010-2018 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -47,6 +47,14 @@ struct Context {
|
|
47
47
|
char **origArgv;
|
48
48
|
bool feedbackFdAvailable;
|
49
49
|
AbortHandlerConfig abortHandlerConfig;
|
50
|
+
|
51
|
+
Context()
|
52
|
+
: resourceLocator(NULL),
|
53
|
+
randomSeed(0),
|
54
|
+
origArgc(0),
|
55
|
+
origArgv(NULL),
|
56
|
+
feedbackFdAvailable(false)
|
57
|
+
{ }
|
50
58
|
};
|
51
59
|
|
52
60
|
typedef void (*OptionParserFunc)(int argc, const char **argv, ConfigKit::Store &config);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
* Copyright (c) 2013-
|
3
|
+
* Copyright (c) 2013-2018 Phusion Holding B.V.
|
4
4
|
*
|
5
5
|
* "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
* trademarks of Phusion Holding B.V.
|
@@ -361,7 +361,7 @@ touchDir(const char *dir) {
|
|
361
361
|
}
|
362
362
|
execlp("/bin/sh", "/bin/sh", "-c",
|
363
363
|
"find \"$1\" | xargs touch", "/bin/sh", ".",
|
364
|
-
(
|
364
|
+
(char *) 0);
|
365
365
|
e = errno;
|
366
366
|
fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
|
367
367
|
strerror(e), e);
|
@@ -432,7 +432,7 @@ performCleanup(const char *dir) {
|
|
432
432
|
close(terminationPipe[1]);
|
433
433
|
execlp("/bin/sh", "/bin/sh", "-c",
|
434
434
|
"rm -rf \"$1\"", "/bin/sh", dir,
|
435
|
-
(
|
435
|
+
(char *) 0);
|
436
436
|
e = errno;
|
437
437
|
fprintf(stderr, ERROR_PREFIX ": cannot execute /bin/sh: %s (errno %d)\n",
|
438
438
|
strerror(e), e);
|
data/src/agent/Watchdog/Config.h
CHANGED
@@ -146,7 +146,7 @@ using namespace std;
|
|
146
146
|
* security_update_checker_interval unsigned integer - default(86400)
|
147
147
|
* security_update_checker_proxy_url string - -
|
148
148
|
* security_update_checker_url string - default("https://securitycheck.phusionpassenger.com/v1/check.json")
|
149
|
-
* server_software string - default("Phusion_Passenger/5.3.
|
149
|
+
* server_software string - default("Phusion_Passenger/5.3.7")
|
150
150
|
* setsid boolean - default(false)
|
151
151
|
* show_version_in_header boolean - default(true)
|
152
152
|
* single_app_mode_app_root string - default,read_only
|
@@ -81,7 +81,7 @@
|
|
81
81
|
#define PASSENGER_API_VERSION_MAJOR 0
|
82
82
|
#define PASSENGER_API_VERSION_MINOR 3
|
83
83
|
#define PASSENGER_DEFAULT_USER "nobody"
|
84
|
-
#define PASSENGER_VERSION "5.3.
|
84
|
+
#define PASSENGER_VERSION "5.3.7"
|
85
85
|
#define POOL_HELPER_THREAD_STACK_SIZE 262144
|
86
86
|
#define PROCESS_SHUTDOWN_TIMEOUT 60
|
87
87
|
#define PROCESS_SHUTDOWN_TIMEOUT_DISPLAY "1 minute"
|
@@ -135,13 +135,13 @@ convertLowerCase(const unsigned char * restrict data,
|
|
135
135
|
i = imax * 8;
|
136
136
|
output = (unsigned char *) d;
|
137
137
|
switch (leftover) {
|
138
|
-
case 7: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
139
|
-
case 6: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
140
|
-
case 5: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
141
|
-
case 4: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
142
|
-
case 3: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
143
|
-
case 2: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
144
|
-
case 1: *output++ = (unsigned char) gsToLowerMap[ustr[i]];
|
138
|
+
case 7: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
139
|
+
case 6: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
140
|
+
case 5: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
141
|
+
case 4: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
142
|
+
case 3: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
143
|
+
case 2: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
144
|
+
case 1: *output++ = (unsigned char) gsToLowerMap[ustr[i]]; /* Falls through. */
|
145
145
|
case 0: break;
|
146
146
|
}
|
147
147
|
#elif defined(__x86__)
|
@@ -167,9 +167,9 @@ convertLowerCase(const unsigned char * restrict data,
|
|
167
167
|
i = imax * 4;
|
168
168
|
output = (unsigned char *) d;
|
169
169
|
switch (leftover) {
|
170
|
-
case 3: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
171
|
-
case 2: *output++ = (unsigned char) gsToLowerMap[ustr[i++]];
|
172
|
-
case 1: *output++ = (unsigned char) gsToLowerMap[ustr[i]];
|
170
|
+
case 3: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
171
|
+
case 2: *output++ = (unsigned char) gsToLowerMap[ustr[i++]]; /* Falls through. */
|
172
|
+
case 1: *output++ = (unsigned char) gsToLowerMap[ustr[i]]; /* Falls through. */
|
173
173
|
case 0: break;
|
174
174
|
}
|
175
175
|
#else
|
@@ -31,7 +31,7 @@ module PhusionPassenger
|
|
31
31
|
|
32
32
|
PACKAGE_NAME = 'passenger'
|
33
33
|
# Run 'rake src/cxx_supportlib/Constants.h configkit_schemas_inline_comments' after changing this number.
|
34
|
-
VERSION_STRING = '5.3.
|
34
|
+
VERSION_STRING = '5.3.7'
|
35
35
|
|
36
36
|
PREFERRED_NGINX_VERSION = '1.14.0'
|
37
37
|
NGINX_SHA256_CHECKSUM = '5d15becbf69aba1fe33f8d416d97edd95ea8919ea9ac519eff9bafebb6022cb5'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.3.
|
4
|
+
version: 5.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phusion - http://www.phusion.nl/
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -715,7 +715,6 @@ files:
|
|
715
715
|
- src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/utf8_validator.hpp
|
716
716
|
- src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/utilities.hpp
|
717
717
|
- src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/version.hpp
|
718
|
-
- src/cxx_supportlib/vendor-modified/SmallVector.h
|
719
718
|
- src/cxx_supportlib/vendor-modified/boost/algorithm/string/case_conv.hpp
|
720
719
|
- src/cxx_supportlib/vendor-modified/boost/algorithm/string/classification.hpp
|
721
720
|
- src/cxx_supportlib/vendor-modified/boost/algorithm/string/compare.hpp
|
@@ -1,653 +0,0 @@
|
|
1
|
-
//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
|
2
|
-
//
|
3
|
-
// The LLVM Compiler Infrastructure
|
4
|
-
//
|
5
|
-
// This file is distributed under the University of Illinois Open Source
|
6
|
-
// License.
|
7
|
-
// ==============================================================================
|
8
|
-
// LLVM Release License
|
9
|
-
// ==============================================================================
|
10
|
-
// University of Illinois/NCSA
|
11
|
-
// Open Source License
|
12
|
-
//
|
13
|
-
// Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.
|
14
|
-
// All rights reserved.
|
15
|
-
//
|
16
|
-
// Developed by:
|
17
|
-
//
|
18
|
-
// LLVM Team
|
19
|
-
//
|
20
|
-
// University of Illinois at Urbana-Champaign
|
21
|
-
//
|
22
|
-
// http://llvm.org
|
23
|
-
//
|
24
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
25
|
-
// this software and associated documentation files (the "Software"), to deal with
|
26
|
-
// the Software without restriction, including without limitation the rights to
|
27
|
-
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
28
|
-
// of the Software, and to permit persons to whom the Software is furnished to do
|
29
|
-
// so, subject to the following conditions:
|
30
|
-
//
|
31
|
-
// * Redistributions of source code must retain the above copyright notice,
|
32
|
-
// this list of conditions and the following disclaimers.
|
33
|
-
//
|
34
|
-
// * Redistributions in binary form must reproduce the above copyright notice,
|
35
|
-
// this list of conditions and the following disclaimers in the
|
36
|
-
// documentation and/or other materials provided with the distribution.
|
37
|
-
//
|
38
|
-
// * Neither the names of the LLVM Team, University of Illinois at
|
39
|
-
// Urbana-Champaign, nor the names of its contributors may be used to
|
40
|
-
// endorse or promote products derived from this Software without specific
|
41
|
-
// prior written permission.
|
42
|
-
//
|
43
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
44
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
45
|
-
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
46
|
-
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
47
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
48
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
49
|
-
// SOFTWARE.
|
50
|
-
//
|
51
|
-
//===----------------------------------------------------------------------===//
|
52
|
-
//
|
53
|
-
// This file defines the SmallVector class. Slightly modified for use in
|
54
|
-
// Phusion Passenger.
|
55
|
-
//
|
56
|
-
//===----------------------------------------------------------------------===//
|
57
|
-
|
58
|
-
#ifndef LLVM_ADT_SMALLVECTOR_H
|
59
|
-
#define LLVM_ADT_SMALLVECTOR_H
|
60
|
-
|
61
|
-
#include <iterator>
|
62
|
-
#include <boost/type_traits/is_class.hpp>
|
63
|
-
#include <algorithm>
|
64
|
-
#include <cassert>
|
65
|
-
#include <cstring>
|
66
|
-
#include <memory>
|
67
|
-
|
68
|
-
#ifdef _MSC_VER
|
69
|
-
namespace std {
|
70
|
-
#if _MSC_VER <= 1310
|
71
|
-
// Work around flawed VC++ implementation of std::uninitialized_copy. Define
|
72
|
-
// additional overloads so that elements with pointer types are recognized as
|
73
|
-
// scalars and not objects, causing bizarre type conversion errors.
|
74
|
-
template<class T1, class T2>
|
75
|
-
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
|
76
|
-
_Scalar_ptr_iterator_tag _Cat;
|
77
|
-
return _Cat;
|
78
|
-
}
|
79
|
-
|
80
|
-
template<class T1, class T2>
|
81
|
-
inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
|
82
|
-
_Scalar_ptr_iterator_tag _Cat;
|
83
|
-
return _Cat;
|
84
|
-
}
|
85
|
-
#else
|
86
|
-
// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
|
87
|
-
// is that the above hack won't work if it wasn't fixed.
|
88
|
-
#endif
|
89
|
-
}
|
90
|
-
#endif
|
91
|
-
|
92
|
-
namespace Passenger {
|
93
|
-
|
94
|
-
/// SmallVectorImpl - This class consists of common code factored out of the
|
95
|
-
/// SmallVector class to reduce code duplication based on the SmallVector 'N'
|
96
|
-
/// template parameter.
|
97
|
-
template <typename T>
|
98
|
-
class SmallVectorImpl {
|
99
|
-
protected:
|
100
|
-
T *Begin, *End, *Capacity;
|
101
|
-
|
102
|
-
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
|
103
|
-
// don't want it to be automatically run, so we need to represent the space as
|
104
|
-
// something else. An array of char would work great, but might not be
|
105
|
-
// aligned sufficiently. Instead, we either use GCC extensions, or some
|
106
|
-
// number of union instances for the space, which guarantee maximal alignment.
|
107
|
-
protected:
|
108
|
-
#ifdef __GNUC__
|
109
|
-
typedef char U;
|
110
|
-
U FirstEl __attribute__((aligned));
|
111
|
-
#else
|
112
|
-
union U {
|
113
|
-
double D;
|
114
|
-
long double LD;
|
115
|
-
long long L;
|
116
|
-
void *P;
|
117
|
-
} FirstEl;
|
118
|
-
#endif
|
119
|
-
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
|
120
|
-
public:
|
121
|
-
// Default ctor - Initialize to empty.
|
122
|
-
explicit SmallVectorImpl(unsigned N)
|
123
|
-
: Begin(reinterpret_cast<T*>(&FirstEl)),
|
124
|
-
End(reinterpret_cast<T*>(&FirstEl)),
|
125
|
-
Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
|
126
|
-
}
|
127
|
-
|
128
|
-
~SmallVectorImpl() {
|
129
|
-
// Destroy the constructed elements in the vector.
|
130
|
-
destroy_range(Begin, End);
|
131
|
-
|
132
|
-
// If this wasn't grown from the inline copy, deallocate the old space.
|
133
|
-
if (!isSmall())
|
134
|
-
operator delete(Begin);
|
135
|
-
}
|
136
|
-
|
137
|
-
typedef size_t size_type;
|
138
|
-
typedef ptrdiff_t difference_type;
|
139
|
-
typedef T value_type;
|
140
|
-
typedef T* iterator;
|
141
|
-
typedef const T* const_iterator;
|
142
|
-
|
143
|
-
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
144
|
-
typedef std::reverse_iterator<iterator> reverse_iterator;
|
145
|
-
|
146
|
-
typedef T& reference;
|
147
|
-
typedef const T& const_reference;
|
148
|
-
typedef T* pointer;
|
149
|
-
typedef const T* const_pointer;
|
150
|
-
|
151
|
-
bool empty() const { return Begin == End; }
|
152
|
-
size_type size() const { return End-Begin; }
|
153
|
-
size_type max_size() const { return size_type(-1) / sizeof(T); }
|
154
|
-
|
155
|
-
// forward iterator creation methods.
|
156
|
-
iterator begin() { return Begin; }
|
157
|
-
const_iterator begin() const { return Begin; }
|
158
|
-
iterator end() { return End; }
|
159
|
-
const_iterator end() const { return End; }
|
160
|
-
|
161
|
-
// reverse iterator creation methods.
|
162
|
-
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
163
|
-
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
|
164
|
-
reverse_iterator rend() { return reverse_iterator(begin()); }
|
165
|
-
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
|
166
|
-
|
167
|
-
|
168
|
-
/* These asserts could be "Begin + idx < End", but there are lots of places
|
169
|
-
in llvm where we use &v[v.size()] instead of v.end(). */
|
170
|
-
reference operator[](unsigned idx) {
|
171
|
-
assert (Begin + idx <= End);
|
172
|
-
return Begin[idx];
|
173
|
-
}
|
174
|
-
const_reference operator[](unsigned idx) const {
|
175
|
-
assert (Begin + idx <= End);
|
176
|
-
return Begin[idx];
|
177
|
-
}
|
178
|
-
|
179
|
-
reference front() {
|
180
|
-
return begin()[0];
|
181
|
-
}
|
182
|
-
const_reference front() const {
|
183
|
-
return begin()[0];
|
184
|
-
}
|
185
|
-
|
186
|
-
reference back() {
|
187
|
-
return end()[-1];
|
188
|
-
}
|
189
|
-
const_reference back() const {
|
190
|
-
return end()[-1];
|
191
|
-
}
|
192
|
-
|
193
|
-
void push_back(const_reference Elt) {
|
194
|
-
if (End < Capacity) {
|
195
|
-
Retry:
|
196
|
-
new (End) T(Elt);
|
197
|
-
++End;
|
198
|
-
return;
|
199
|
-
}
|
200
|
-
grow();
|
201
|
-
goto Retry;
|
202
|
-
}
|
203
|
-
|
204
|
-
void pop_back() {
|
205
|
-
--End;
|
206
|
-
End->~T();
|
207
|
-
}
|
208
|
-
|
209
|
-
T pop_back_val() {
|
210
|
-
T Result = back();
|
211
|
-
pop_back();
|
212
|
-
return Result;
|
213
|
-
}
|
214
|
-
|
215
|
-
void clear() {
|
216
|
-
destroy_range(Begin, End);
|
217
|
-
End = Begin;
|
218
|
-
}
|
219
|
-
|
220
|
-
void resize(unsigned N) {
|
221
|
-
if (N < size()) {
|
222
|
-
destroy_range(Begin+N, End);
|
223
|
-
End = Begin+N;
|
224
|
-
} else if (N > size()) {
|
225
|
-
if (unsigned(Capacity-Begin) < N)
|
226
|
-
grow(N);
|
227
|
-
construct_range(End, Begin+N, T());
|
228
|
-
End = Begin+N;
|
229
|
-
}
|
230
|
-
}
|
231
|
-
|
232
|
-
void resize(unsigned N, const T &NV) {
|
233
|
-
if (N < size()) {
|
234
|
-
destroy_range(Begin+N, End);
|
235
|
-
End = Begin+N;
|
236
|
-
} else if (N > size()) {
|
237
|
-
if (unsigned(Capacity-Begin) < N)
|
238
|
-
grow(N);
|
239
|
-
construct_range(End, Begin+N, NV);
|
240
|
-
End = Begin+N;
|
241
|
-
}
|
242
|
-
}
|
243
|
-
|
244
|
-
void reserve(unsigned N) {
|
245
|
-
if (unsigned(Capacity-Begin) < N)
|
246
|
-
grow(N);
|
247
|
-
}
|
248
|
-
|
249
|
-
void swap(SmallVectorImpl &RHS);
|
250
|
-
|
251
|
-
/// append - Add the specified range to the end of the SmallVector.
|
252
|
-
///
|
253
|
-
template<typename in_iter>
|
254
|
-
void append(in_iter in_start, in_iter in_end) {
|
255
|
-
size_type NumInputs = std::distance(in_start, in_end);
|
256
|
-
// Grow allocated space if needed.
|
257
|
-
if (NumInputs > size_type(Capacity-End))
|
258
|
-
grow(size()+NumInputs);
|
259
|
-
|
260
|
-
// Copy the new elements over.
|
261
|
-
std::uninitialized_copy(in_start, in_end, End);
|
262
|
-
End += NumInputs;
|
263
|
-
}
|
264
|
-
|
265
|
-
/// append - Add the specified range to the end of the SmallVector.
|
266
|
-
///
|
267
|
-
void append(size_type NumInputs, const T &Elt) {
|
268
|
-
// Grow allocated space if needed.
|
269
|
-
if (NumInputs > size_type(Capacity-End))
|
270
|
-
grow(size()+NumInputs);
|
271
|
-
|
272
|
-
// Copy the new elements over.
|
273
|
-
std::uninitialized_fill_n(End, NumInputs, Elt);
|
274
|
-
End += NumInputs;
|
275
|
-
}
|
276
|
-
|
277
|
-
void assign(unsigned NumElts, const T &Elt) {
|
278
|
-
clear();
|
279
|
-
if (unsigned(Capacity-Begin) < NumElts)
|
280
|
-
grow(NumElts);
|
281
|
-
End = Begin+NumElts;
|
282
|
-
construct_range(Begin, End, Elt);
|
283
|
-
}
|
284
|
-
|
285
|
-
iterator erase(iterator I) {
|
286
|
-
iterator N = I;
|
287
|
-
// Shift all elts down one.
|
288
|
-
std::copy(I+1, End, I);
|
289
|
-
// Drop the last elt.
|
290
|
-
pop_back();
|
291
|
-
return(N);
|
292
|
-
}
|
293
|
-
|
294
|
-
iterator erase(iterator S, iterator E) {
|
295
|
-
iterator N = S;
|
296
|
-
// Shift all elts down.
|
297
|
-
iterator I = std::copy(E, End, S);
|
298
|
-
// Drop the last elts.
|
299
|
-
destroy_range(I, End);
|
300
|
-
End = I;
|
301
|
-
return(N);
|
302
|
-
}
|
303
|
-
|
304
|
-
iterator insert(iterator I, const T &Elt) {
|
305
|
-
if (I == End) { // Important special case for empty vector.
|
306
|
-
push_back(Elt);
|
307
|
-
return end()-1;
|
308
|
-
}
|
309
|
-
|
310
|
-
if (End < Capacity) {
|
311
|
-
Retry:
|
312
|
-
new (End) T(back());
|
313
|
-
++End;
|
314
|
-
// Push everything else over.
|
315
|
-
std::copy_backward(I, End-1, End);
|
316
|
-
*I = Elt;
|
317
|
-
return I;
|
318
|
-
}
|
319
|
-
size_t EltNo = I-Begin;
|
320
|
-
grow();
|
321
|
-
I = Begin+EltNo;
|
322
|
-
goto Retry;
|
323
|
-
}
|
324
|
-
|
325
|
-
iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
|
326
|
-
if (I == End) { // Important special case for empty vector.
|
327
|
-
append(NumToInsert, Elt);
|
328
|
-
return end()-1;
|
329
|
-
}
|
330
|
-
|
331
|
-
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
|
332
|
-
size_t InsertElt = I-begin();
|
333
|
-
|
334
|
-
// Ensure there is enough space.
|
335
|
-
reserve(static_cast<unsigned>(size() + NumToInsert));
|
336
|
-
|
337
|
-
// Uninvalidate the iterator.
|
338
|
-
I = begin()+InsertElt;
|
339
|
-
|
340
|
-
// If there are more elements between the insertion point and the end of the
|
341
|
-
// range than there are being inserted, we can use a simple approach to
|
342
|
-
// insertion. Since we already reserved space, we know that this won't
|
343
|
-
// reallocate the vector.
|
344
|
-
if (size_t(end()-I) >= NumToInsert) {
|
345
|
-
T *OldEnd = End;
|
346
|
-
append(End-NumToInsert, End);
|
347
|
-
|
348
|
-
// Copy the existing elements that get replaced.
|
349
|
-
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
|
350
|
-
|
351
|
-
std::fill_n(I, NumToInsert, Elt);
|
352
|
-
return I;
|
353
|
-
}
|
354
|
-
|
355
|
-
// Otherwise, we're inserting more elements than exist already, and we're
|
356
|
-
// not inserting at the end.
|
357
|
-
|
358
|
-
// Copy over the elements that we're about to overwrite.
|
359
|
-
T *OldEnd = End;
|
360
|
-
End += NumToInsert;
|
361
|
-
size_t NumOverwritten = OldEnd-I;
|
362
|
-
std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
|
363
|
-
|
364
|
-
// Replace the overwritten part.
|
365
|
-
std::fill_n(I, NumOverwritten, Elt);
|
366
|
-
|
367
|
-
// Insert the non-overwritten middle part.
|
368
|
-
std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
|
369
|
-
return I;
|
370
|
-
}
|
371
|
-
|
372
|
-
template<typename ItTy>
|
373
|
-
iterator insert(iterator I, ItTy From, ItTy To) {
|
374
|
-
if (I == End) { // Important special case for empty vector.
|
375
|
-
append(From, To);
|
376
|
-
return end()-1;
|
377
|
-
}
|
378
|
-
|
379
|
-
size_t NumToInsert = std::distance(From, To);
|
380
|
-
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
|
381
|
-
size_t InsertElt = I-begin();
|
382
|
-
|
383
|
-
// Ensure there is enough space.
|
384
|
-
reserve(static_cast<unsigned>(size() + NumToInsert));
|
385
|
-
|
386
|
-
// Uninvalidate the iterator.
|
387
|
-
I = begin()+InsertElt;
|
388
|
-
|
389
|
-
// If there are more elements between the insertion point and the end of the
|
390
|
-
// range than there are being inserted, we can use a simple approach to
|
391
|
-
// insertion. Since we already reserved space, we know that this won't
|
392
|
-
// reallocate the vector.
|
393
|
-
if (size_t(end()-I) >= NumToInsert) {
|
394
|
-
T *OldEnd = End;
|
395
|
-
append(End-NumToInsert, End);
|
396
|
-
|
397
|
-
// Copy the existing elements that get replaced.
|
398
|
-
std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
|
399
|
-
|
400
|
-
std::copy(From, To, I);
|
401
|
-
return I;
|
402
|
-
}
|
403
|
-
|
404
|
-
// Otherwise, we're inserting more elements than exist already, and we're
|
405
|
-
// not inserting at the end.
|
406
|
-
|
407
|
-
// Copy over the elements that we're about to overwrite.
|
408
|
-
T *OldEnd = End;
|
409
|
-
End += NumToInsert;
|
410
|
-
size_t NumOverwritten = OldEnd-I;
|
411
|
-
std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
|
412
|
-
|
413
|
-
// Replace the overwritten part.
|
414
|
-
std::copy(From, From+NumOverwritten, I);
|
415
|
-
|
416
|
-
// Insert the non-overwritten middle part.
|
417
|
-
std::uninitialized_copy(From+NumOverwritten, To, OldEnd);
|
418
|
-
return I;
|
419
|
-
}
|
420
|
-
|
421
|
-
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
|
422
|
-
|
423
|
-
bool operator==(const SmallVectorImpl &RHS) const {
|
424
|
-
if (size() != RHS.size()) return false;
|
425
|
-
for (T *This = Begin, *That = RHS.Begin, *E = Begin+size();
|
426
|
-
This != E; ++This, ++That)
|
427
|
-
if (*This != *That)
|
428
|
-
return false;
|
429
|
-
return true;
|
430
|
-
}
|
431
|
-
bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); }
|
432
|
-
|
433
|
-
bool operator<(const SmallVectorImpl &RHS) const {
|
434
|
-
return std::lexicographical_compare(begin(), end(),
|
435
|
-
RHS.begin(), RHS.end());
|
436
|
-
}
|
437
|
-
|
438
|
-
private:
|
439
|
-
/// isSmall - Return true if this is a smallvector which has not had dynamic
|
440
|
-
/// memory allocated for it.
|
441
|
-
bool isSmall() const {
|
442
|
-
return static_cast<const void*>(Begin) ==
|
443
|
-
static_cast<const void*>(&FirstEl);
|
444
|
-
}
|
445
|
-
|
446
|
-
/// grow - double the size of the allocated memory, guaranteeing space for at
|
447
|
-
/// least one more element or MinSize if specified.
|
448
|
-
void grow(size_type MinSize = 0);
|
449
|
-
|
450
|
-
void construct_range(T *S, T *E, const T &Elt) {
|
451
|
-
for (; S != E; ++S)
|
452
|
-
new (S) T(Elt);
|
453
|
-
}
|
454
|
-
|
455
|
-
void destroy_range(T *S, T *E) {
|
456
|
-
while (S != E) {
|
457
|
-
--E;
|
458
|
-
E->~T();
|
459
|
-
}
|
460
|
-
}
|
461
|
-
};
|
462
|
-
|
463
|
-
// Define this out-of-line to dissuade the C++ compiler from inlining it.
|
464
|
-
template <typename T>
|
465
|
-
void SmallVectorImpl<T>::grow(size_t MinSize) {
|
466
|
-
size_t CurCapacity = Capacity-Begin;
|
467
|
-
size_t CurSize = size();
|
468
|
-
size_t NewCapacity = 2*CurCapacity;
|
469
|
-
if (NewCapacity < MinSize)
|
470
|
-
NewCapacity = MinSize;
|
471
|
-
T *NewElts = static_cast<T*>(operator new(NewCapacity*sizeof(T)));
|
472
|
-
|
473
|
-
// Copy the elements over.
|
474
|
-
if (boost::is_class<T>::value)
|
475
|
-
std::uninitialized_copy(Begin, End, NewElts);
|
476
|
-
else
|
477
|
-
// Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
|
478
|
-
memcpy(NewElts, Begin, CurSize * sizeof(T));
|
479
|
-
|
480
|
-
// Destroy the original elements.
|
481
|
-
destroy_range(Begin, End);
|
482
|
-
|
483
|
-
// If this wasn't grown from the inline copy, deallocate the old space.
|
484
|
-
if (!isSmall())
|
485
|
-
operator delete(Begin);
|
486
|
-
|
487
|
-
Begin = NewElts;
|
488
|
-
End = NewElts+CurSize;
|
489
|
-
Capacity = Begin+NewCapacity;
|
490
|
-
}
|
491
|
-
|
492
|
-
template <typename T>
|
493
|
-
void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
|
494
|
-
if (this == &RHS) return;
|
495
|
-
|
496
|
-
// We can only avoid copying elements if neither vector is small.
|
497
|
-
if (!isSmall() && !RHS.isSmall()) {
|
498
|
-
std::swap(Begin, RHS.Begin);
|
499
|
-
std::swap(End, RHS.End);
|
500
|
-
std::swap(Capacity, RHS.Capacity);
|
501
|
-
return;
|
502
|
-
}
|
503
|
-
if (RHS.size() > size_type(Capacity-Begin))
|
504
|
-
grow(RHS.size());
|
505
|
-
if (size() > size_type(RHS.Capacity-RHS.begin()))
|
506
|
-
RHS.grow(size());
|
507
|
-
|
508
|
-
// Swap the shared elements.
|
509
|
-
size_t NumShared = size();
|
510
|
-
if (NumShared > RHS.size()) NumShared = RHS.size();
|
511
|
-
for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
|
512
|
-
std::swap(Begin[i], RHS[i]);
|
513
|
-
|
514
|
-
// Copy over the extra elts.
|
515
|
-
if (size() > RHS.size()) {
|
516
|
-
size_t EltDiff = size() - RHS.size();
|
517
|
-
std::uninitialized_copy(Begin+NumShared, End, RHS.End);
|
518
|
-
RHS.End += EltDiff;
|
519
|
-
destroy_range(Begin+NumShared, End);
|
520
|
-
End = Begin+NumShared;
|
521
|
-
} else if (RHS.size() > size()) {
|
522
|
-
size_t EltDiff = RHS.size() - size();
|
523
|
-
std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
|
524
|
-
End += EltDiff;
|
525
|
-
destroy_range(RHS.Begin+NumShared, RHS.End);
|
526
|
-
RHS.End = RHS.Begin+NumShared;
|
527
|
-
}
|
528
|
-
}
|
529
|
-
|
530
|
-
template <typename T>
|
531
|
-
const SmallVectorImpl<T> &
|
532
|
-
SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
|
533
|
-
// Avoid self-assignment.
|
534
|
-
if (this == &RHS) return *this;
|
535
|
-
|
536
|
-
// If we already have sufficient space, assign the common elements, then
|
537
|
-
// destroy any excess.
|
538
|
-
unsigned RHSSize = unsigned(RHS.size());
|
539
|
-
unsigned CurSize = unsigned(size());
|
540
|
-
if (CurSize >= RHSSize) {
|
541
|
-
// Assign common elements.
|
542
|
-
iterator NewEnd;
|
543
|
-
if (RHSSize)
|
544
|
-
NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
|
545
|
-
else
|
546
|
-
NewEnd = Begin;
|
547
|
-
|
548
|
-
// Destroy excess elements.
|
549
|
-
destroy_range(NewEnd, End);
|
550
|
-
|
551
|
-
// Trim.
|
552
|
-
End = NewEnd;
|
553
|
-
return *this;
|
554
|
-
}
|
555
|
-
|
556
|
-
// If we have to grow to have enough elements, destroy the current elements.
|
557
|
-
// This allows us to avoid copying them during the grow.
|
558
|
-
if (unsigned(Capacity-Begin) < RHSSize) {
|
559
|
-
// Destroy current elements.
|
560
|
-
destroy_range(Begin, End);
|
561
|
-
End = Begin;
|
562
|
-
CurSize = 0;
|
563
|
-
grow(RHSSize);
|
564
|
-
} else if (CurSize) {
|
565
|
-
// Otherwise, use assignment for the already-constructed elements.
|
566
|
-
std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
|
567
|
-
}
|
568
|
-
|
569
|
-
// Copy construct the new elements in place.
|
570
|
-
std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
|
571
|
-
|
572
|
-
// Set end.
|
573
|
-
End = Begin+RHSSize;
|
574
|
-
return *this;
|
575
|
-
}
|
576
|
-
|
577
|
-
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
|
578
|
-
/// for the case when the array is small. It contains some number of elements
|
579
|
-
/// in-place, which allows it to avoid heap allocation when the actual number of
|
580
|
-
/// elements is below that threshold. This allows normal "small" cases to be
|
581
|
-
/// fast without losing generality for large inputs.
|
582
|
-
///
|
583
|
-
/// Note that this does not attempt to be exception safe.
|
584
|
-
///
|
585
|
-
template <typename T, unsigned N>
|
586
|
-
class SmallVector : public SmallVectorImpl<T> {
|
587
|
-
/// InlineElts - These are 'N-1' elements that are stored inline in the body
|
588
|
-
/// of the vector. The extra '1' element is stored in SmallVectorImpl.
|
589
|
-
typedef typename SmallVectorImpl<T>::U U;
|
590
|
-
enum {
|
591
|
-
// MinUs - The number of U's require to cover N T's.
|
592
|
-
MinUs = (static_cast<unsigned int>(sizeof(T))*N +
|
593
|
-
static_cast<unsigned int>(sizeof(U)) - 1) /
|
594
|
-
static_cast<unsigned int>(sizeof(U)),
|
595
|
-
|
596
|
-
// NumInlineEltsElts - The number of elements actually in this array. There
|
597
|
-
// is already one in the parent class, and we have to round up to avoid
|
598
|
-
// having a zero-element array.
|
599
|
-
NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
|
600
|
-
|
601
|
-
// NumTsAvailable - The number of T's we actually have space for, which may
|
602
|
-
// be more than N due to rounding.
|
603
|
-
NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
|
604
|
-
static_cast<unsigned int>(sizeof(T))
|
605
|
-
};
|
606
|
-
U InlineElts[NumInlineEltsElts];
|
607
|
-
public:
|
608
|
-
SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
|
609
|
-
}
|
610
|
-
|
611
|
-
explicit SmallVector(unsigned Size, const T &Value = T())
|
612
|
-
: SmallVectorImpl<T>(NumTsAvailable) {
|
613
|
-
this->reserve(Size);
|
614
|
-
while (Size--)
|
615
|
-
this->push_back(Value);
|
616
|
-
}
|
617
|
-
|
618
|
-
template<typename ItTy>
|
619
|
-
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
|
620
|
-
this->append(S, E);
|
621
|
-
}
|
622
|
-
|
623
|
-
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
|
624
|
-
if (!RHS.empty())
|
625
|
-
SmallVectorImpl<T>::operator=(RHS);
|
626
|
-
}
|
627
|
-
|
628
|
-
const SmallVector &operator=(const SmallVector &RHS) {
|
629
|
-
SmallVectorImpl<T>::operator=(RHS);
|
630
|
-
return *this;
|
631
|
-
}
|
632
|
-
|
633
|
-
};
|
634
|
-
|
635
|
-
} // End Passenger namespace
|
636
|
-
|
637
|
-
namespace std {
|
638
|
-
/// Implement std::swap in terms of SmallVector swap.
|
639
|
-
template<typename T>
|
640
|
-
inline void
|
641
|
-
swap(Passenger::SmallVectorImpl<T> &LHS, Passenger::SmallVectorImpl<T> &RHS) {
|
642
|
-
LHS.swap(RHS);
|
643
|
-
}
|
644
|
-
|
645
|
-
/// Implement std::swap in terms of SmallVector swap.
|
646
|
-
template<typename T, unsigned N>
|
647
|
-
inline void
|
648
|
-
swap(Passenger::SmallVector<T, N> &LHS, Passenger::SmallVector<T, N> &RHS) {
|
649
|
-
LHS.swap(RHS);
|
650
|
-
}
|
651
|
-
}
|
652
|
-
|
653
|
-
#endif
|