passenger 6.0.27 → 6.1.0
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 +11 -1
- data/CONTRIBUTORS +2 -0
- data/bin/passenger-install-apache2-module +6 -3
- data/bin/passenger-install-nginx-module +8 -3
- data/build/support/cxx_dependency_map.rb +3 -621
- data/dev/index_cxx_dependencies.rb +4 -0
- data/package.json +1 -1
- data/src/agent/Core/ApplicationPool/Implementation.cpp +1 -1
- data/src/agent/Core/ApplicationPool/Socket.h +3 -3
- data/src/agent/Core/ApplicationPool/TestSession.h +3 -4
- data/src/agent/Core/Config.h +1 -6
- data/src/agent/Core/Controller/Config.h +1 -1
- data/src/agent/Core/CoreMain.cpp +1 -0
- data/src/agent/Core/SecurityUpdateChecker.h +10 -1
- data/src/agent/Core/SpawningKit/Exceptions.h +0 -1
- data/src/agent/Core/SpawningKit/Handshake/Perform.h +13 -2
- data/src/agent/Shared/Fundamentals/AbortHandler.cpp +23 -5
- data/src/agent/Shared/Fundamentals/AbortHandler.h +10 -22
- data/src/agent/Shared/Fundamentals/Initialization.cpp +1 -0
- data/src/agent/Watchdog/Config.h +1 -1
- data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +5 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +14 -0
- data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +3 -0
- data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +3 -0
- data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +11 -0
- data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +7 -0
- data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +17 -0
- data/src/apache2_module/Hooks.cpp +0 -6
- data/src/cxx_supportlib/ConfigKit/IN_PRACTICE.md +2 -12
- data/src/cxx_supportlib/ConfigKit/Store.h +1 -6
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/DataStructures/StringKeyTable.h +1 -7
- data/src/cxx_supportlib/Exceptions.cpp +178 -0
- data/src/cxx_supportlib/Exceptions.h +62 -177
- data/src/cxx_supportlib/IOTools/IOUtils.cpp +255 -228
- data/src/cxx_supportlib/IOTools/IOUtils.h +84 -121
- data/src/cxx_supportlib/ServerKit/Config.h +1 -6
- data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +1 -1
- data/src/cxx_supportlib/StaticString.h +1 -6
- data/src/cxx_supportlib/Utils/Curl.h +1 -6
- data/src/cxx_supportlib/Utils/ScopeGuard.h +0 -32
- data/src/cxx_supportlib/oxt/implementation.cpp +2 -2
- data/src/cxx_supportlib/oxt/spin_lock.hpp +94 -23
- data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +6 -10
- data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/rack_handler.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- metadata +3 -7
- data/src/cxx_supportlib/oxt/detail/spin_lock_darwin.hpp +0 -75
- data/src/cxx_supportlib/oxt/detail/spin_lock_gcc_x86.hpp +0 -85
- data/src/cxx_supportlib/oxt/detail/spin_lock_portable.hpp +0 -38
- data/src/cxx_supportlib/oxt/detail/spin_lock_pthreads.hpp +0 -111
@@ -43,16 +43,15 @@ namespace Passenger {
|
|
43
43
|
|
44
44
|
using namespace std;
|
45
45
|
|
46
|
+
|
47
|
+
/****** Server address types support ******/
|
48
|
+
|
46
49
|
enum ServerAddressType {
|
47
50
|
SAT_UNIX,
|
48
51
|
SAT_TCP,
|
49
52
|
SAT_UNKNOWN
|
50
53
|
};
|
51
54
|
|
52
|
-
typedef ssize_t (*WritevFunction)(int fildes, const struct iovec *iov, int iovcnt);
|
53
|
-
|
54
|
-
bool purgeStdio(FILE *f);
|
55
|
-
|
56
55
|
/**
|
57
56
|
* Accepts a server address in one of the following formats, and returns which one it is:
|
58
57
|
*
|
@@ -95,30 +94,8 @@ void parseTcpSocketAddress(const StaticString & restrict_ref address,
|
|
95
94
|
*/
|
96
95
|
bool isLocalSocketAddress(const StaticString &address);
|
97
96
|
|
98
|
-
/**
|
99
|
-
* Sets a socket in blocking mode.
|
100
|
-
*
|
101
|
-
* @throws SystemException Something went wrong.
|
102
|
-
* @ingroup Support
|
103
|
-
*/
|
104
|
-
void setBlocking(int fd);
|
105
97
|
|
106
|
-
|
107
|
-
* Sets a socket in non-blocking mode.
|
108
|
-
*
|
109
|
-
* @throws SystemException Something went wrong.
|
110
|
-
* @ingroup Support
|
111
|
-
*/
|
112
|
-
void setNonBlocking(int fd);
|
113
|
-
|
114
|
-
/**
|
115
|
-
* Try to call the Linux accept4() system call. If the system call is
|
116
|
-
* not available, then -1 is returned and errno is set to ENOSYS.
|
117
|
-
*/
|
118
|
-
int callAccept4(int sock,
|
119
|
-
struct sockaddr * restrict addr,
|
120
|
-
socklen_t * restrict addr_len,
|
121
|
-
int options);
|
98
|
+
/****** Server socket creation ******/
|
122
99
|
|
123
100
|
/**
|
124
101
|
* Create a new Unix or TCP server socket, depending on the address type.
|
@@ -139,7 +116,7 @@ int callAccept4(int sock,
|
|
139
116
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
140
117
|
* @ingroup Support
|
141
118
|
*/
|
142
|
-
int createServer(const StaticString &address,
|
119
|
+
int createServer(const StaticString &address,
|
143
120
|
unsigned int backlogSize = 0,
|
144
121
|
bool autoDelete = true,
|
145
122
|
const char *file = __FILE__,
|
@@ -191,6 +168,9 @@ int createTcpServer(const char *address = "0.0.0.0",
|
|
191
168
|
const char *file = __FILE__,
|
192
169
|
unsigned int line = __LINE__);
|
193
170
|
|
171
|
+
|
172
|
+
/****** Socket connection establishment (blocking) ******/
|
173
|
+
|
194
174
|
/**
|
195
175
|
* Connect to a server at the given address in a blocking manner.
|
196
176
|
*
|
@@ -206,7 +186,7 @@ int createTcpServer(const char *address = "0.0.0.0",
|
|
206
186
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
207
187
|
* @ingroup Support
|
208
188
|
*/
|
209
|
-
int connectToServer(const StaticString &address, const char *file,
|
189
|
+
int connectToServer(const StaticString &address, const char *file,
|
210
190
|
unsigned int line);
|
211
191
|
|
212
192
|
/**
|
@@ -243,138 +223,120 @@ int connectToTcpServer(const StaticString &hostname, unsigned int port,
|
|
243
223
|
const char *file, unsigned int line);
|
244
224
|
|
245
225
|
|
246
|
-
|
247
|
-
struct NUnix_State {
|
248
|
-
FileDescriptor fd;
|
249
|
-
string filename;
|
250
|
-
};
|
251
|
-
|
252
|
-
/** State structure for non-blocking connectToTcpServer(). */
|
253
|
-
struct NTCP_State {
|
254
|
-
FileDescriptor fd;
|
255
|
-
struct addrinfo hints, *res;
|
256
|
-
string hostname;
|
257
|
-
int port;
|
258
|
-
|
259
|
-
NTCP_State() {
|
260
|
-
memset(&hints, 0, sizeof(hints));
|
261
|
-
res = NULL;
|
262
|
-
port = 0;
|
263
|
-
}
|
264
|
-
|
265
|
-
~NTCP_State() {
|
266
|
-
if (res != NULL) {
|
267
|
-
freeaddrinfo(res);
|
268
|
-
}
|
269
|
-
}
|
270
|
-
};
|
226
|
+
/****** Socket connection establishment (non-blocking) ******/
|
271
227
|
|
272
228
|
/**
|
273
|
-
*
|
274
|
-
* the file descriptor can be accessed through <tt>state.fd</tt>.
|
229
|
+
* Establish a socket connection in non-blocking mode.
|
275
230
|
*
|
276
|
-
* @param
|
277
|
-
* @param filename The filename of the socket to connect to.
|
231
|
+
* @param address An address as accepted by getSocketAddressType().
|
278
232
|
* @param file The name of the source file that called this function,
|
279
233
|
* for file descriptor logging purposes.
|
280
234
|
* @param line The line in the source file that called this function.
|
235
|
+
* @return The file descriptor of the connected client socket, plus whether
|
236
|
+
* it was immediately connected (true) or pending (false). If pending,
|
237
|
+
* the caller should poll() on the socket until it's writable.
|
238
|
+
* @throws ArgumentException Something went wrong.
|
239
|
+
* @throws IOException Something went wrong.
|
281
240
|
* @throws SystemException Something went wrong.
|
282
241
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
283
|
-
* @ingroup Support
|
284
242
|
*/
|
285
|
-
|
286
|
-
const StaticString & restrict_ref filename, const char *file,
|
287
|
-
unsigned int line);
|
243
|
+
std::pair<int, bool> createNonBlockingSocketConnection(const StaticString &address, const char *file, unsigned int line);
|
288
244
|
|
289
245
|
/**
|
290
|
-
*
|
246
|
+
* Establish a Unix domain socket connection in non-blocking mode.
|
291
247
|
*
|
292
|
-
* @param
|
293
|
-
* @
|
294
|
-
*
|
295
|
-
* @
|
248
|
+
* @param filename The filename of the socket to connect to.
|
249
|
+
* @param file The name of the source file that called this function,
|
250
|
+
* for file descriptor logging purposes.
|
251
|
+
* @param line The line in the source file that called this function.
|
252
|
+
* @return The file descriptor of the connected client socket, plus whether
|
253
|
+
* it was immediately connected (true) or pending (false). If pending,
|
254
|
+
* the caller should poll() on the socket until it's writable.
|
255
|
+
* @throws ArgumentException Something went wrong.
|
296
256
|
* @throws SystemException Something went wrong while connecting to the Unix server.
|
297
257
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
298
|
-
* @ingroup Support
|
299
258
|
*/
|
300
|
-
bool
|
259
|
+
std::pair<int, bool> createNonBlockingUnixSocketConnection(const StaticString &filename, const char *file, unsigned int line);
|
301
260
|
|
302
261
|
/**
|
303
|
-
*
|
304
|
-
* the file descriptor can be accessed through <tt>state.fd</tt>.
|
262
|
+
* Establish a TCP socket connection in non-blocking mode.
|
305
263
|
*
|
306
|
-
* @param state A state structure.
|
307
264
|
* @param hostname The host name of the TCP server.
|
308
265
|
* @param port The port number of the TCP server.
|
309
266
|
* @param file The name of the source file that called this function,
|
310
267
|
* for file descriptor logging purposes.
|
311
268
|
* @param line The line in the source file that called this function.
|
269
|
+
* @return The file descriptor of the connected client socket, plus whether
|
270
|
+
* it was immediately connected (true) or pending (false). If pending,
|
271
|
+
* the caller should poll() on the socket until it's writable.
|
312
272
|
* @throws IOException Something went wrong.
|
313
273
|
* @throws SystemException Something went wrong.
|
314
274
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
315
|
-
* @ingroup Support
|
316
275
|
*/
|
317
|
-
|
318
|
-
const StaticString & restrict_ref hostname,
|
319
|
-
int port, const char *file, unsigned int line);
|
276
|
+
std::pair<int, bool> createNonBlockingTcpSocketConnection(const StaticString &hostname, unsigned int port, const char *file, unsigned int line);
|
320
277
|
|
321
|
-
/**
|
322
|
-
* Connect a TCP socket in non-blocking mode.
|
323
|
-
*
|
324
|
-
* @param state A state structure.
|
325
|
-
* @return True if the socket was successfully connected, false if the socket isn't
|
326
|
-
* ready yet, in which case the caller should select() on the socket until it's writable.
|
327
|
-
* @throws SystemException Something went wrong while connecting to the server.
|
328
|
-
* @throws boost::thread_interrupted A system call has been interrupted.
|
329
|
-
* @ingroup Support
|
330
|
-
*/
|
331
|
-
bool connectToTcpServer(NTCP_State &state);
|
332
278
|
|
333
|
-
|
279
|
+
/****** Scope guards ******/
|
280
|
+
|
281
|
+
/** RAII construct for ensuring that a file descriptor gets closed at scope exit. */
|
282
|
+
class FdGuard {
|
334
283
|
private:
|
335
|
-
|
336
|
-
NTCP_State s_tcp;
|
284
|
+
int mFd = -1;
|
337
285
|
|
338
286
|
public:
|
339
|
-
|
287
|
+
FdGuard() { }
|
288
|
+
FdGuard(const FdGuard &other) = delete;
|
289
|
+
FdGuard(FdGuard &&other);
|
290
|
+
FdGuard(int fd, const char *sourceFile, unsigned int sourceLine);
|
291
|
+
/** @throws SystemException File descriptor close error. If exception is already being thrown, then only warns. */
|
292
|
+
~FdGuard() noexcept(false);
|
340
293
|
|
341
|
-
|
342
|
-
|
343
|
-
*
|
344
|
-
* @param address An address as accepted by getSocketAddressType().
|
345
|
-
* @param file The name of the source file that called this function,
|
346
|
-
* for file descriptor logging purposes.
|
347
|
-
* @param line The line in the source file that called this function.
|
348
|
-
* @throws ArgumentException Unknown address type.
|
349
|
-
* @throws RuntimeException Something went wrong.
|
350
|
-
* @throws SystemException Something went wrong.
|
351
|
-
* @throws IOException Something went wrong.
|
352
|
-
* @throws boost::thread_interrupted A system call has been interrupted.
|
353
|
-
*/
|
354
|
-
NConnect_State(const StaticString & restrict_ref address, const char *file, unsigned int line);
|
294
|
+
FdGuard &operator=(const FdGuard &other) = delete;
|
295
|
+
FdGuard &operator=(FdGuard &&other);
|
355
296
|
|
356
|
-
|
357
|
-
|
297
|
+
/** Don't close file descriptor at object destruction. */
|
298
|
+
void clear() noexcept;
|
358
299
|
|
359
300
|
/**
|
360
|
-
*
|
301
|
+
* Close file descriptor now. Idempotent.
|
361
302
|
*
|
362
|
-
* @
|
363
|
-
* ready yet, in which case the caller should select() on the socket until it's writable.
|
364
|
-
* @throws RuntimeException Something went wrong.
|
365
|
-
* @throws SystemException Something went wrong.
|
366
|
-
* @throws boost::thread_interrupted A system call has been interrupted.
|
303
|
+
* @throws SystemException
|
367
304
|
*/
|
368
|
-
|
369
|
-
|
370
|
-
/**
|
371
|
-
* Gets the connection file descriptor.
|
372
|
-
*
|
373
|
-
* @pre \c connectToServer() was called
|
374
|
-
*/
|
375
|
-
FileDescriptor &getFd();
|
305
|
+
void runNow() noexcept(false);
|
376
306
|
};
|
377
307
|
|
308
|
+
|
309
|
+
/****** Other ******/
|
310
|
+
|
311
|
+
typedef ssize_t (*WritevFunction)(int fildes, const struct iovec *iov, int iovcnt);
|
312
|
+
|
313
|
+
bool purgeStdio(FILE *f);
|
314
|
+
|
315
|
+
/**
|
316
|
+
* Sets a socket in blocking mode.
|
317
|
+
*
|
318
|
+
* @throws SystemException Something went wrong.
|
319
|
+
* @ingroup Support
|
320
|
+
*/
|
321
|
+
void setBlocking(int fd);
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Sets a socket in non-blocking mode.
|
325
|
+
*
|
326
|
+
* @throws SystemException Something went wrong.
|
327
|
+
* @ingroup Support
|
328
|
+
*/
|
329
|
+
void setNonBlocking(int fd);
|
330
|
+
|
331
|
+
/**
|
332
|
+
* Try to call the Linux accept4() system call. If the system call is
|
333
|
+
* not available, then -1 is returned and errno is set to ENOSYS.
|
334
|
+
*/
|
335
|
+
int callAccept4(int sock,
|
336
|
+
struct sockaddr * restrict addr,
|
337
|
+
socklen_t * restrict addr_len,
|
338
|
+
int options);
|
339
|
+
|
378
340
|
/**
|
379
341
|
* Checks whether the given TCP server is connectable. Because this check
|
380
342
|
* can take (in theory) an arbitrary amount of time, you must also supply
|
@@ -382,6 +344,7 @@ public:
|
|
382
344
|
* deducted from the `*timeout` value. A timeout of 100000 microseconds is
|
383
345
|
* recommended for most use cases.
|
384
346
|
*
|
347
|
+
* @throws ArgumentException Something went wrong.
|
385
348
|
* @throws IOException Something went wrong.
|
386
349
|
* @throws SystemException Something went wrong.
|
387
350
|
* @throws boost::thread_interrupted A system call has been interrupted.
|
@@ -26,12 +26,7 @@
|
|
26
26
|
#ifndef _PASSENGER_SERVER_KIT_CONFIG_H_
|
27
27
|
#define _PASSENGER_SERVER_KIT_CONFIG_H_
|
28
28
|
|
29
|
-
|
30
|
-
#if __cplusplus >= 201103L
|
31
|
-
#include <utility>
|
32
|
-
#else
|
33
|
-
#include <algorithm>
|
34
|
-
#endif
|
29
|
+
#include <utility>
|
35
30
|
#include <string>
|
36
31
|
#include <boost/config.hpp>
|
37
32
|
#include <boost/scoped_ptr.hpp>
|
@@ -933,7 +933,7 @@ private:
|
|
933
933
|
if (req->result >= 0) {
|
934
934
|
FBC_DEBUG_FROM_CALLBACK(fcContext,
|
935
935
|
"Writer: creation of file " << fcContext->path <<
|
936
|
-
"canceled. Deleting file in the background");
|
936
|
+
" canceled. Deleting file in the background");
|
937
937
|
closeBufferFileInBackground(fcContext);
|
938
938
|
// Will take care of deleting fcContext
|
939
939
|
unlinkBufferFileInBackground(fcContext);
|
@@ -26,12 +26,7 @@
|
|
26
26
|
#ifndef _PASSENGER_STATIC_STRING_H_
|
27
27
|
#define _PASSENGER_STATIC_STRING_H_
|
28
28
|
|
29
|
-
|
30
|
-
#if __cplusplus >= 201103L
|
31
|
-
#include <utility>
|
32
|
-
#else
|
33
|
-
#include <algorithm>
|
34
|
-
#endif
|
29
|
+
#include <utility>
|
35
30
|
#include <boost/config.hpp>
|
36
31
|
#include <oxt/macros.hpp>
|
37
32
|
#include <sys/types.h>
|
@@ -117,38 +117,6 @@ public:
|
|
117
117
|
}
|
118
118
|
};
|
119
119
|
|
120
|
-
class FdGuard: public noncopyable {
|
121
|
-
private:
|
122
|
-
int fd;
|
123
|
-
bool ignoreErrors;
|
124
|
-
|
125
|
-
public:
|
126
|
-
FdGuard(int _fd, const char *file, unsigned int line, bool _ignoreErrors = false)
|
127
|
-
: fd(_fd),
|
128
|
-
ignoreErrors(_ignoreErrors)
|
129
|
-
{
|
130
|
-
if (_fd != -1 && file != NULL) {
|
131
|
-
P_LOG_FILE_DESCRIPTOR_OPEN3(_fd, file, line);
|
132
|
-
}
|
133
|
-
}
|
134
|
-
|
135
|
-
~FdGuard() {
|
136
|
-
runNow();
|
137
|
-
}
|
138
|
-
|
139
|
-
void clear() {
|
140
|
-
fd = -1;
|
141
|
-
}
|
142
|
-
|
143
|
-
void runNow() {
|
144
|
-
if (fd != -1) {
|
145
|
-
safelyClose(fd, ignoreErrors);
|
146
|
-
P_LOG_FILE_DESCRIPTOR_CLOSE(fd);
|
147
|
-
fd = -1;
|
148
|
-
}
|
149
|
-
}
|
150
|
-
};
|
151
|
-
|
152
120
|
|
153
121
|
} // namespace Passenger
|
154
122
|
|
@@ -272,14 +272,14 @@ tracable_exception &
|
|
272
272
|
tracable_exception::operator=(const tracable_exception &other) {
|
273
273
|
if (this != &other) {
|
274
274
|
// Clean up existing backtrace points
|
275
|
-
for (
|
275
|
+
for (trace_point * p: backtrace_copy) {
|
276
276
|
delete p;
|
277
277
|
}
|
278
278
|
backtrace_copy.clear();
|
279
279
|
|
280
280
|
// Copy backtrace points from other
|
281
281
|
backtrace_copy.reserve(other.backtrace_copy.size());
|
282
|
-
for (const
|
282
|
+
for (const trace_point *const p2: other.backtrace_copy) {
|
283
283
|
trace_point *p;
|
284
284
|
if (p2->m_hasDataFunc) {
|
285
285
|
p = new trace_point(
|
@@ -25,28 +25,99 @@
|
|
25
25
|
#ifndef _OXT_SPIN_LOCK_HPP_
|
26
26
|
#define _OXT_SPIN_LOCK_HPP_
|
27
27
|
|
28
|
-
#include
|
29
|
-
|
30
|
-
// These operating systems don't support pthread spin locks:
|
31
|
-
// - OpenBSD 4.3 (last checked: July 22, 2008)
|
32
|
-
// - Solaris 9 (last checked: July 22, 2008)
|
33
|
-
// - MacOS X (last checked: July 22, 2012)
|
34
|
-
#if defined(__OpenBSD__) || defined(__SOLARIS9__) || defined(__APPLE__)
|
35
|
-
#define OXT_NO_PTHREAD_SPINLOCKS
|
36
|
-
#endif
|
37
|
-
|
38
|
-
#if defined(__APPLE__)
|
39
|
-
#include "detail/spin_lock_darwin.hpp"
|
40
|
-
#elif (OXT_GCC_VERSION > 40100 && (defined(__i386__) || defined(__x86_64__))) || defined(IN_DOXYGEN)
|
41
|
-
// GCC 4.0 doesn't support __sync instructions while GCC 4.2
|
42
|
-
// does. I'm not sure whether support for it started in 4.1 or
|
43
|
-
// 4.2, so the above version check may have to be changed later.
|
44
|
-
#include "detail/spin_lock_gcc_x86.hpp"
|
45
|
-
#elif !defined(WIN32) && !defined(OXT_NO_PTHREAD_SPINLOCKS)
|
46
|
-
#include "detail/spin_lock_pthreads.hpp"
|
47
|
-
#else
|
48
|
-
#include "detail/spin_lock_portable.hpp"
|
49
|
-
#endif
|
28
|
+
#include <thread>
|
29
|
+
#include <atomic>
|
50
30
|
|
51
|
-
|
31
|
+
namespace oxt {
|
32
|
+
|
33
|
+
/**
|
34
|
+
* A spin lock that's specifically designed to yield the CPU once in a while to
|
35
|
+
* avoid starving other threads.
|
36
|
+
*
|
37
|
+
* We use spin locks because on many platforms, mutexes are slower when there's little
|
38
|
+
* or no contention. OS-native mutexes work better in highly contended scenarios due
|
39
|
+
* to better scheduler integration. However, in Passenger we have a couple of scenarios
|
40
|
+
* where we know there's going to be little or no contention. In oxt::system_calls,
|
41
|
+
* contention is rare and mostly limited to thread interruption during aborts or process
|
42
|
+
* shutdown. As a result, we use spin locks to prioritize performance in the uncontended
|
43
|
+
* case.
|
44
|
+
*
|
45
|
+
* We avoid OS-native spinlocks for two reasons:
|
46
|
+
* - There's no widely-available standard spinlock. We want to keep the code simple,
|
47
|
+
* avoiding OS-specific implementations.
|
48
|
+
* - OS-native spinlocks such as pthread_spin_lock_t don't guarantee scheduler integration,
|
49
|
+
* but we need it in order to avoid starvation that would interfere with thread
|
50
|
+
* interruption.
|
51
|
+
*/
|
52
|
+
class spin_lock {
|
53
|
+
private:
|
54
|
+
// Our main use case is to allow threads to only be interruptable when
|
55
|
+
// blocked on certain system calls (oxt::thread_local_context::syscall_interruption_lock).
|
56
|
+
// That is locked most of the time, only unlocked during a syscall.
|
57
|
+
// An oxt::thread::interrupt() call may need to wait for a long time before it's unlocked.
|
58
|
+
// So keep the spin count low so we yield the CPU often.
|
59
|
+
static constexpr unsigned int MAX_SPINS = 100;
|
60
|
+
|
61
|
+
std::atomic_flag flag = ATOMIC_FLAG_INIT;
|
62
|
+
|
63
|
+
public:
|
64
|
+
/**
|
65
|
+
* Instantiate this class to lock a spin lock within a scope.
|
66
|
+
*/
|
67
|
+
class scoped_lock {
|
68
|
+
private:
|
69
|
+
spin_lock &l;
|
70
|
+
|
71
|
+
public:
|
72
|
+
scoped_lock(const scoped_lock &other) = delete;
|
73
|
+
scoped_lock &operator=(const scoped_lock &other) = delete;
|
52
74
|
|
75
|
+
scoped_lock(spin_lock &lock) noexcept: l(lock) {
|
76
|
+
l.lock();
|
77
|
+
}
|
78
|
+
|
79
|
+
~scoped_lock() noexcept {
|
80
|
+
l.unlock();
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Lock this spin lock.
|
86
|
+
*/
|
87
|
+
void lock() noexcept {
|
88
|
+
while (true) {
|
89
|
+
for (unsigned int i = 0; i < MAX_SPINS; i++) {
|
90
|
+
if (flag.test_and_set(std::memory_order_acquire)) {
|
91
|
+
#if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
|
92
|
+
flag.wait(true, std::memory_order_relaxed);
|
93
|
+
#endif
|
94
|
+
} else {
|
95
|
+
return; // lock acquired
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
// Yield the CPU every once in a while to allow other threads to
|
100
|
+
// run. On systems with bad schedulers (including Valgrind),
|
101
|
+
// not yielding can lead to starvation, which looks like a deadlock.
|
102
|
+
std::this_thread::yield();
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Unlock this spin lock.
|
108
|
+
*/
|
109
|
+
void unlock() noexcept {
|
110
|
+
flag.clear(std::memory_order_release);
|
111
|
+
#if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
|
112
|
+
flag.notify_one();
|
113
|
+
#endif
|
114
|
+
}
|
115
|
+
|
116
|
+
bool try_lock() noexcept {
|
117
|
+
return !flag.test_and_set(std::memory_order_acquire);
|
118
|
+
}
|
119
|
+
};
|
120
|
+
|
121
|
+
} // namespace oxt
|
122
|
+
|
123
|
+
#endif /* _OXT_SPIN_LOCK_HPP_ */
|
@@ -532,25 +532,21 @@ module PhusionPassenger
|
|
532
532
|
end
|
533
533
|
end
|
534
534
|
|
535
|
-
def self.
|
536
|
-
# C++11 support on FreeBSD 10.0 + Clang seems to be bugged.
|
537
|
-
# http://llvm.org/bugs/show_bug.cgi?id=18310
|
538
|
-
return nil if os_name_simple == "freebsd"
|
539
|
-
|
535
|
+
def self.cxx_14_flag
|
540
536
|
source = %{
|
541
537
|
struct Foo {
|
542
538
|
Foo(Foo &&f) { }
|
543
539
|
};
|
544
540
|
}
|
545
|
-
if try_compile("Checking for C++ -std=gnu++
|
546
|
-
return "-std=gnu++
|
547
|
-
elsif try_compile("Checking for C++ -std=c++
|
548
|
-
return "-std=c++
|
541
|
+
if try_compile("Checking for C++ -std=gnu++14 compiler flag", :cxx, source, '-std=gnu++14')
|
542
|
+
return "-std=gnu++14"
|
543
|
+
elsif try_compile("Checking for C++ -std=c++14 compiler flag", :cxx, source, '-std=c++14')
|
544
|
+
return "-std=c++14"
|
549
545
|
else
|
550
546
|
return nil
|
551
547
|
end
|
552
548
|
end
|
553
|
-
memoize :
|
549
|
+
memoize :cxx_14_flag, true
|
554
550
|
|
555
551
|
def self.has_rt_library?
|
556
552
|
return try_link("Checking for -lrt support",
|
@@ -138,7 +138,7 @@ module PhusionPassenger
|
|
138
138
|
|
139
139
|
if cc_or_cxx == :cxx
|
140
140
|
flags << debugging_cxxflags
|
141
|
-
flags <<
|
141
|
+
flags << cxx_14_flag if cxx_14_flag
|
142
142
|
|
143
143
|
if cxx_supports_wno_unused_local_typedefs_flag?
|
144
144
|
# Avoids some compilaton warnings with Boost on Ubuntu 14.04.
|
@@ -192,7 +192,7 @@ module PhusionPassenger
|
|
192
192
|
|
193
193
|
def self.portability_c_or_cxx_ldflags(cc_or_cxx)
|
194
194
|
result = ''
|
195
|
-
result <<
|
195
|
+
result << cxx_14_flag if cc_or_cxx == :cxx && cxx_14_flag
|
196
196
|
if os_name_simple == "solaris"
|
197
197
|
result << ' -lxnet -lsocket -lnsl -lpthread'
|
198
198
|
else
|
@@ -41,7 +41,7 @@ require 'rbconfig'
|
|
41
41
|
require 'rackup' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
42
42
|
|
43
43
|
# Rackup was removed in Rack 3, it is now a separate gem
|
44
|
-
if Object.const_defined? :
|
44
|
+
if Object.const_defined?(:Rackup) && ::Rackup.const_defined?(:Handler)
|
45
45
|
module Rackup
|
46
46
|
module Handler
|
47
47
|
module PhusionPassenger
|
@@ -57,7 +57,7 @@ if Object.const_defined? :Rackup
|
|
57
57
|
register :passenger, PhusionPassenger
|
58
58
|
end
|
59
59
|
end
|
60
|
-
elsif Object.const_defined?(:Rack) && Rack.release < '3'
|
60
|
+
elsif Object.const_defined?(:Rack) && ::Rack.release < '3'
|
61
61
|
module Rack
|
62
62
|
module Handler
|
63
63
|
module PhusionPassenger
|
@@ -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 = '6.0
|
34
|
+
VERSION_STRING = '6.1.0'
|
35
35
|
|
36
36
|
# Tip: find the SHA-256 with ./dev/nginx_version_sha256 <VERSION>
|
37
37
|
PREFERRED_NGINX_VERSION = '1.26.3'
|
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: 6.0
|
4
|
+
version: 6.1.0
|
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: 2025-
|
11
|
+
date: 2025-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -536,10 +536,6 @@ files:
|
|
536
536
|
- src/cxx_supportlib/oxt/detail/backtrace_disabled.hpp
|
537
537
|
- src/cxx_supportlib/oxt/detail/backtrace_enabled.hpp
|
538
538
|
- src/cxx_supportlib/oxt/detail/context.hpp
|
539
|
-
- src/cxx_supportlib/oxt/detail/spin_lock_darwin.hpp
|
540
|
-
- src/cxx_supportlib/oxt/detail/spin_lock_gcc_x86.hpp
|
541
|
-
- src/cxx_supportlib/oxt/detail/spin_lock_portable.hpp
|
542
|
-
- src/cxx_supportlib/oxt/detail/spin_lock_pthreads.hpp
|
543
539
|
- src/cxx_supportlib/oxt/detail/tracable_exception_disabled.hpp
|
544
540
|
- src/cxx_supportlib/oxt/detail/tracable_exception_enabled.hpp
|
545
541
|
- src/cxx_supportlib/oxt/dynamic_thread_group.hpp
|
@@ -4386,7 +4382,7 @@ homepage: https://www.phusionpassenger.com/
|
|
4386
4382
|
licenses: []
|
4387
4383
|
metadata:
|
4388
4384
|
bug_tracker_uri: https://github.com/phusion/passenger/issues
|
4389
|
-
changelog_uri: https://github.com/phusion/passenger/blob/stable-6.
|
4385
|
+
changelog_uri: https://github.com/phusion/passenger/blob/stable-6.1/CHANGELOG
|
4390
4386
|
documentation_uri: https://www.phusionpassenger.com/docs/
|
4391
4387
|
homepage_uri: https://www.phusionpassenger.com/
|
4392
4388
|
source_code_uri: https://github.com/phusion/passenger
|