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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +11 -1
  3. data/CONTRIBUTORS +2 -0
  4. data/bin/passenger-install-apache2-module +6 -3
  5. data/bin/passenger-install-nginx-module +8 -3
  6. data/build/support/cxx_dependency_map.rb +3 -621
  7. data/dev/index_cxx_dependencies.rb +4 -0
  8. data/package.json +1 -1
  9. data/src/agent/Core/ApplicationPool/Implementation.cpp +1 -1
  10. data/src/agent/Core/ApplicationPool/Socket.h +3 -3
  11. data/src/agent/Core/ApplicationPool/TestSession.h +3 -4
  12. data/src/agent/Core/Config.h +1 -6
  13. data/src/agent/Core/Controller/Config.h +1 -1
  14. data/src/agent/Core/CoreMain.cpp +1 -0
  15. data/src/agent/Core/SecurityUpdateChecker.h +10 -1
  16. data/src/agent/Core/SpawningKit/Exceptions.h +0 -1
  17. data/src/agent/Core/SpawningKit/Handshake/Perform.h +13 -2
  18. data/src/agent/Shared/Fundamentals/AbortHandler.cpp +23 -5
  19. data/src/agent/Shared/Fundamentals/AbortHandler.h +10 -22
  20. data/src/agent/Shared/Fundamentals/Initialization.cpp +1 -0
  21. data/src/agent/Watchdog/Config.h +1 -1
  22. data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +5 -0
  23. data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +5 -0
  24. data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +14 -0
  25. data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +3 -0
  26. data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +3 -0
  27. data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +11 -0
  28. data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +7 -0
  29. data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +17 -0
  30. data/src/apache2_module/Hooks.cpp +0 -6
  31. data/src/cxx_supportlib/ConfigKit/IN_PRACTICE.md +2 -12
  32. data/src/cxx_supportlib/ConfigKit/Store.h +1 -6
  33. data/src/cxx_supportlib/Constants.h +1 -1
  34. data/src/cxx_supportlib/DataStructures/StringKeyTable.h +1 -7
  35. data/src/cxx_supportlib/Exceptions.cpp +178 -0
  36. data/src/cxx_supportlib/Exceptions.h +62 -177
  37. data/src/cxx_supportlib/IOTools/IOUtils.cpp +255 -228
  38. data/src/cxx_supportlib/IOTools/IOUtils.h +84 -121
  39. data/src/cxx_supportlib/ServerKit/Config.h +1 -6
  40. data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +1 -1
  41. data/src/cxx_supportlib/StaticString.h +1 -6
  42. data/src/cxx_supportlib/Utils/Curl.h +1 -6
  43. data/src/cxx_supportlib/Utils/ScopeGuard.h +0 -32
  44. data/src/cxx_supportlib/oxt/implementation.cpp +2 -2
  45. data/src/cxx_supportlib/oxt/spin_lock.hpp +94 -23
  46. data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +6 -10
  47. data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +2 -2
  48. data/src/ruby_supportlib/phusion_passenger/rack_handler.rb +2 -2
  49. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  50. metadata +3 -7
  51. data/src/cxx_supportlib/oxt/detail/spin_lock_darwin.hpp +0 -75
  52. data/src/cxx_supportlib/oxt/detail/spin_lock_gcc_x86.hpp +0 -85
  53. data/src/cxx_supportlib/oxt/detail/spin_lock_portable.hpp +0 -38
  54. 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
- /** State structure for non-blocking connectToUnixServer(). */
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
- * Setup a Unix domain socket for non-blocking connecting. When done,
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 state A state structure.
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
- void setupNonBlockingUnixSocket(NUnix_State & restrict_ref state,
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
- * Connect a Unix domain socket in non-blocking mode.
246
+ * Establish a Unix domain socket connection in non-blocking mode.
291
247
  *
292
- * @param state A state structure.
293
- * @return True if the socket was successfully connected, false if the socket isn't
294
- * ready yet, in which case the caller should select() on the socket until it's writable.
295
- * @throws RuntimeException Something went wrong.
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 connectToUnixServer(NUnix_State &state);
259
+ std::pair<int, bool> createNonBlockingUnixSocketConnection(const StaticString &filename, const char *file, unsigned int line);
301
260
 
302
261
  /**
303
- * Setup a TCP socket for non-blocking connecting. When done,
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
- void setupNonBlockingTcpSocket(NTCP_State & restrict_ref state,
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
- struct NConnect_State {
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
- NUnix_State s_unix;
336
- NTCP_State s_tcp;
284
+ int mFd = -1;
337
285
 
338
286
  public:
339
- ServerAddressType type;
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
- * Setup a socket for non-blocking connecting to the given address.
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
- NUnix_State &asNUnix_State();
357
- NTCP_State &asNTCP_State();
297
+ /** Don't close file descriptor at object destruction. */
298
+ void clear() noexcept;
358
299
 
359
300
  /**
360
- * Connect a socket in non-blocking mode.
301
+ * Close file descriptor now. Idempotent.
361
302
  *
362
- * @return True if the socket was successfully connected, false if the socket isn't
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
- bool connectToServer();
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
- // for std::swap()
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
- // for std::swap()
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>
@@ -47,12 +47,7 @@
47
47
  * don't do anything.
48
48
  */
49
49
 
50
- // for std::swap()
51
- #if __cplusplus >= 201103L
52
- #include <utility>
53
- #else
54
- #include <algorithm>
55
- #endif
50
+ #include <utility>
56
51
  #include <string>
57
52
  #include <cstring>
58
53
  #include <curl/curl.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 (auto p: backtrace_copy) {
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 auto p2: other.backtrace_copy) {
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 "macros.hpp"
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
- #endif /* _OXT_SPIN_LOCK_HPP_ */
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.cxx_11_flag
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++11 compiler flag", :cxx, source, '-std=gnu++11')
546
- return "-std=gnu++11"
547
- elsif try_compile("Checking for C++ -std=c++11 compiler flag", :cxx, source, '-std=c++11')
548
- return "-std=c++11"
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 :cxx_11_flag, true
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 << cxx_11_flag if cxx_11_flag
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 << cxx_11_flag if cc_or_cxx == :cxx && cxx_11_flag
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? :Rackup
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.27'
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.27
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-04-01 00:00:00.000000000 Z
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.0/CHANGELOG
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