passenger 4.0.48 → 4.0.49

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +36 -2
  5. data/.travis.yml +1 -1
  6. data/CHANGELOG +16 -0
  7. data/Rakefile +0 -1
  8. data/build/apache2.rb +4 -4
  9. data/build/common_library.rb +18 -18
  10. data/build/cplusplus_support.rb +2 -2
  11. data/build/documentation.rb +1 -1
  12. data/build/integration_tests.rb +12 -4
  13. data/build/misc.rb +12 -7
  14. data/build/packaging.rb +14 -14
  15. data/build/preprocessor.rb +10 -10
  16. data/build/rake_extensions.rb +11 -11
  17. data/build/ruby_extension.rb +2 -2
  18. data/dev/ci/inituidgid +24 -0
  19. data/dev/ci/run_jenkins.sh +57 -0
  20. data/dev/ci/run_rpm_tests.sh +77 -0
  21. data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
  22. data/doc/Users guide Nginx.txt +2 -2
  23. data/doc/users_guide_snippets/environment_variables.txt +0 -2
  24. data/doc/users_guide_snippets/tips.txt +20 -1
  25. data/ext/apache2/Bucket.cpp +18 -18
  26. data/ext/apache2/Bucket.h +4 -4
  27. data/ext/apache2/Configuration.cpp +7 -7
  28. data/ext/apache2/Configuration.hpp +43 -43
  29. data/ext/apache2/DirectoryMapper.h +5 -5
  30. data/ext/apache2/Hooks.cpp +142 -142
  31. data/ext/apache2/MergeDirConfig.cpp +40 -40
  32. data/ext/common/Account.h +17 -17
  33. data/ext/common/AccountsDatabase.h +9 -9
  34. data/ext/common/AgentsStarter.cpp +2 -2
  35. data/ext/common/AgentsStarter.h +40 -40
  36. data/ext/common/ApplicationPool2/Common.h +10 -6
  37. data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
  38. data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
  39. data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
  40. data/ext/common/ApplicationPool2/Group.h +54 -38
  41. data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
  42. data/ext/common/ApplicationPool2/Options.h +98 -91
  43. data/ext/common/ApplicationPool2/Pool.h +70 -69
  44. data/ext/common/ApplicationPool2/Process.h +21 -21
  45. data/ext/common/ApplicationPool2/Session.h +11 -11
  46. data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
  47. data/ext/common/ApplicationPool2/Socket.h +19 -19
  48. data/ext/common/ApplicationPool2/Spawner.h +64 -72
  49. data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
  50. data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
  51. data/ext/common/BackgroundEventLoop.cpp +1 -1
  52. data/ext/common/BackgroundEventLoop.h +2 -2
  53. data/ext/common/Constants.h +1 -1
  54. data/ext/common/EventedBufferedInput.h +5 -5
  55. data/ext/common/EventedClient.h +51 -51
  56. data/ext/common/EventedMessageServer.h +39 -39
  57. data/ext/common/EventedServer.h +32 -32
  58. data/ext/common/Exceptions.h +23 -23
  59. data/ext/common/FileDescriptor.h +18 -18
  60. data/ext/common/Logging.cpp +1 -1
  61. data/ext/common/MessageClient.h +27 -27
  62. data/ext/common/MessageReadersWriters.h +79 -79
  63. data/ext/common/MessageServer.h +59 -59
  64. data/ext/common/RandomGenerator.h +12 -12
  65. data/ext/common/ResourceLocator.h +8 -8
  66. data/ext/common/SafeLibev.h +54 -25
  67. data/ext/common/ServerInstanceDir.h +31 -31
  68. data/ext/common/StaticString.h +50 -48
  69. data/ext/common/Utils.cpp +73 -78
  70. data/ext/common/Utils.h +6 -6
  71. data/ext/common/Utils/Base64.cpp +3 -3
  72. data/ext/common/Utils/Base64.h +7 -7
  73. data/ext/common/Utils/BlockingQueue.h +9 -9
  74. data/ext/common/Utils/BufferedIO.h +17 -17
  75. data/ext/common/Utils/CachedFileStat.hpp +16 -16
  76. data/ext/common/Utils/Dechunker.h +25 -25
  77. data/ext/common/Utils/FileChangeChecker.h +10 -10
  78. data/ext/common/Utils/MemZeroGuard.h +5 -5
  79. data/ext/common/Utils/MemoryBarrier.h +1 -1
  80. data/ext/common/Utils/MessageIO.h +61 -61
  81. data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
  82. data/ext/common/Utils/ScopeGuard.h +7 -7
  83. data/ext/common/Utils/SpeedMeter.h +1 -1
  84. data/ext/common/Utils/StrIntUtils.cpp +13 -13
  85. data/ext/common/Utils/StrIntUtils.h +3 -3
  86. data/ext/common/Utils/StringScanning.h +5 -5
  87. data/ext/common/Utils/SystemMetricsCollector.h +2 -2
  88. data/ext/common/Utils/SystemTime.h +10 -10
  89. data/ext/common/Utils/Template.h +2 -2
  90. data/ext/common/Utils/Timer.h +6 -6
  91. data/ext/common/Utils/VariantMap.h +29 -29
  92. data/ext/common/agents/Base.cpp +19 -19
  93. data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
  94. data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
  95. data/ext/common/agents/HelperAgent/Main.cpp +44 -43
  96. data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
  97. data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
  98. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
  99. data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
  100. data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
  101. data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
  102. data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
  103. data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
  104. data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
  105. data/ext/common/agents/SpawnPreparer.cpp +4 -4
  106. data/ext/common/agents/TempDirToucher.c +2 -2
  107. data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
  108. data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
  109. data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
  110. data/ext/common/agents/Watchdog/Main.cpp +22 -22
  111. data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
  112. data/ext/libeio/eio.c +1 -1
  113. data/ext/nginx/Configuration.c +30 -30
  114. data/ext/nginx/Configuration.h +1 -1
  115. data/ext/nginx/ContentHandler.c +54 -54
  116. data/ext/nginx/ContentHandler.h +3 -3
  117. data/ext/nginx/StaticContentHandler.c +2 -2
  118. data/ext/nginx/ngx_http_passenger_module.c +21 -21
  119. data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
  120. data/ext/oxt/detail/context.hpp +1 -1
  121. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
  122. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
  123. data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
  124. data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
  125. data/ext/oxt/dynamic_thread_group.hpp +18 -18
  126. data/ext/oxt/implementation.cpp +9 -8
  127. data/ext/oxt/macros.hpp +2 -2
  128. data/ext/oxt/system_calls.cpp +11 -11
  129. data/ext/oxt/system_calls.hpp +13 -13
  130. data/ext/oxt/thread.hpp +22 -14
  131. data/ext/ruby/passenger_native_support.c +55 -55
  132. data/lib/phusion_passenger.rb +24 -24
  133. data/lib/phusion_passenger/common_library.rb +2 -0
  134. data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
  135. data/lib/phusion_passenger/packaging.rb +9 -4
  136. data/lib/phusion_passenger/platform_info/apache.rb +45 -31
  137. data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
  138. data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
  139. data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
  140. data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
  141. data/lib/phusion_passenger/standalone/command.rb +22 -22
  142. data/packaging/rpm/LICENSE.txt +19 -0
  143. data/packaging/rpm/Makefile +13 -0
  144. data/packaging/rpm/README.md +41 -0
  145. data/packaging/rpm/Vagrantfile +38 -0
  146. data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
  147. data/packaging/rpm/build +170 -0
  148. data/packaging/rpm/create_project +41 -0
  149. data/packaging/rpm/git_update +88 -0
  150. data/packaging/rpm/image/Dockerfile +37 -0
  151. data/packaging/rpm/image/Gemfile +3 -0
  152. data/packaging/rpm/image/Gemfile.lock +12 -0
  153. data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
  154. data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
  155. data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
  156. data/packaging/rpm/image/site-defaults.cfg +168 -0
  157. data/packaging/rpm/internal/build_tasks.rb +238 -0
  158. data/packaging/rpm/internal/dummygpg +11 -0
  159. data/packaging/rpm/internal/exec_build +42 -0
  160. data/packaging/rpm/internal/get_distro_arch +14 -0
  161. data/packaging/rpm/internal/get_distro_id +10 -0
  162. data/packaging/rpm/internal/git_update +27 -0
  163. data/packaging/rpm/internal/inituidgid +17 -0
  164. data/packaging/rpm/internal/my_init +344 -0
  165. data/packaging/rpm/internal/python27 +3 -0
  166. data/packaging/rpm/internal/repo_update +46 -0
  167. data/packaging/rpm/internal/setuser +26 -0
  168. data/packaging/rpm/internal/tracking_helper +40 -0
  169. data/packaging/rpm/jenkins_release +99 -0
  170. data/packaging/rpm/lib/build_tasks_support.rb +402 -0
  171. data/packaging/rpm/lib/preprocessor.rb +341 -0
  172. data/packaging/rpm/nginx_spec/404.html +119 -0
  173. data/packaging/rpm/nginx_spec/50x.html +119 -0
  174. data/packaging/rpm/nginx_spec/index.html +116 -0
  175. data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
  176. data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
  177. data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
  178. data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
  179. data/packaging/rpm/nginx_spec/nginx.conf +131 -0
  180. data/packaging/rpm/nginx_spec/nginx.init +144 -0
  181. data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
  182. data/packaging/rpm/nginx_spec/nginx.service +15 -0
  183. data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
  184. data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
  185. data/packaging/rpm/nginx_spec/passenger.conf +9 -0
  186. data/packaging/rpm/nginx_spec/poweredby.png +0 -0
  187. data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
  188. data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
  189. data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
  190. data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
  191. data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
  192. data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
  193. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
  194. data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
  195. data/packaging/rpm/repo_update +114 -0
  196. data/packaging/rpm/setup-system +60 -0
  197. data/packaging/rpm/shell +10 -0
  198. data/resources/templates/standalone/config.erb +3 -1
  199. data/test/config.json.rpm-automation +1 -1
  200. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
  201. data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
  202. data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
  203. data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
  204. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
  205. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
  206. data/test/cxx/ScgiRequestParserTest.cpp +75 -61
  207. data/test/cxx/UtilsTest.cpp +86 -85
  208. data/test/gdbinit.example +3 -0
  209. data/test/integration_tests/nginx_tests.rb +3 -3
  210. data/test/integration_tests/source_packaging_test.rb +3 -1
  211. data/test/stub/nginx/nginx.conf.erb +8 -1
  212. data/test/support/nginx_controller.rb +7 -7
  213. metadata +62 -17
  214. metadata.gz.asc +7 -7
  215. data/build/rpm.rb +0 -128
  216. data/dev/rpmtool +0 -21
  217. data/dev/test_rpm_packaging.sh +0 -28
  218. data/rpm/get_distro_id.py +0 -4
@@ -44,7 +44,7 @@ private:
44
44
  boost::mutex syncher;
45
45
  SpawnerConfigPtr config;
46
46
  DummySpawnerPtr dummySpawner;
47
-
47
+
48
48
  SpawnerPtr tryCreateSmartSpawner(const Options &options) {
49
49
  string dir = config->resourceLocator.getHelperScriptsDir();
50
50
  vector<string> preloaderCommand;
@@ -60,16 +60,16 @@ private:
60
60
  return boost::make_shared<SmartSpawner>(generation, preloaderCommand,
61
61
  options, config);
62
62
  }
63
-
63
+
64
64
  public:
65
65
  SpawnerFactory(const ServerInstanceDir::GenerationPtr &_generation,
66
66
  const SpawnerConfigPtr &_config)
67
67
  : generation(_generation),
68
68
  config(_config)
69
69
  { }
70
-
70
+
71
71
  virtual ~SpawnerFactory() { }
72
-
72
+
73
73
  virtual SpawnerPtr create(const Options &options) {
74
74
  if (options.spawnMethod == "smart" || options.spawnMethod == "smart-lv2") {
75
75
  SpawnerPtr spawner = tryCreateSmartSpawner(options);
@@ -122,12 +122,12 @@ public:
122
122
  * failed it will transition to `DESTROYED`.
123
123
  */
124
124
  INITIALIZING,
125
-
125
+
126
126
  /** This SuperGroup is loaded and is ready for action. From
127
127
  * here the state can transition to `RESTARTING` or `DESTROYING`.
128
128
  */
129
129
  READY,
130
-
130
+
131
131
  /** This SuperGroup is being restarted. The SuperGroup
132
132
  * information is being reloaded from the data source
133
133
  * and processes are being restarted. In this state
@@ -143,7 +143,7 @@ public:
143
143
  * cause a transition to `DESTROYING`.
144
144
  */
145
145
  RESTARTING,
146
-
146
+
147
147
  /** This SuperGroup is being destroyed. Processes are being shut
148
148
  * down and other resources are being cleaned up. In this state,
149
149
  * `groups` is empty.
@@ -151,7 +151,7 @@ public:
151
151
  * transition to `INITIALIZING`.
152
152
  */
153
153
  DESTROYING,
154
-
154
+
155
155
  /** This SuperGroup has been destroyed and all resources have been
156
156
  * freed. Restarting won't have any effect but calling `get()` will
157
157
  * make it transition to `INITIALIZING`.
@@ -169,11 +169,11 @@ public:
169
169
  };
170
170
 
171
171
  typedef boost::function<void (ShutdownResult result)> ShutdownCallback;
172
-
172
+
173
173
  private:
174
174
  friend class Pool;
175
175
  friend class Group;
176
-
176
+
177
177
  Options options;
178
178
  /** A number for concurrency control, incremented every time the state changes.
179
179
  * Every background thread that SuperGroup spawns knows the generation number
@@ -186,8 +186,8 @@ private:
186
186
  * problems.
187
187
  */
188
188
  unsigned int generation;
189
-
190
-
189
+
190
+
191
191
  // Thread-safe.
192
192
  static boost::mutex &getPoolSyncher(const PoolPtr &pool);
193
193
  static void runAllActions(const vector<Callback> &actions);
@@ -195,13 +195,13 @@ private:
195
195
  void runInitializationHooks() const;
196
196
  void runDestructionHooks() const;
197
197
  void setupInitializationOrDestructionHook(HookScriptOptions &options) const;
198
-
198
+
199
199
  void createInterruptableThread(const boost::function<void ()> &func, const string &name,
200
200
  unsigned int stackSize);
201
-
201
+
202
202
  void verifyInvariants() const {
203
203
  // !a || b: logical equivalent of a IMPLIES b.
204
-
204
+
205
205
  assert(groups.empty() ==
206
206
  (state == INITIALIZING || state == DESTROYING || state == DESTROYED));
207
207
  assert((defaultGroup == NULL) ==
@@ -210,7 +210,7 @@ private:
210
210
  ( getWaitlist.empty() ));
211
211
  assert(!( state == DESTROYED ) || ( detachedGroups.empty() ));
212
212
  }
213
-
213
+
214
214
  void setState(State newState) {
215
215
  state = newState;
216
216
  generation++;
@@ -224,10 +224,10 @@ private:
224
224
  infos.push_back(info);
225
225
  return infos;
226
226
  }
227
-
227
+
228
228
  Group *findDefaultGroup(const vector<GroupPtr> &groups) const {
229
229
  vector<GroupPtr>::const_iterator it;
230
-
230
+
231
231
  for (it = groups.begin(); it != groups.end(); it++) {
232
232
  const GroupPtr &group = *it;
233
233
  if (group->componentInfo.isDefault) {
@@ -236,7 +236,7 @@ private:
236
236
  }
237
237
  return NULL;
238
238
  }
239
-
239
+
240
240
  pair<GroupPtr, unsigned int> findGroupCorrespondingToComponent(
241
241
  const vector<GroupPtr> &groups, const ComponentInfo &info) const
242
242
  {
@@ -249,7 +249,7 @@ private:
249
249
  }
250
250
  return make_pair(GroupPtr(), 0);
251
251
  }
252
-
252
+
253
253
  static void oneGroupHasBeenShutDown(SuperGroupPtr self, GroupPtr group) {
254
254
  // This function is either called from the pool event loop or directly from
255
255
  // the detachAllGroups post lock actions. In both cases getPool() is never NULL.
@@ -264,7 +264,7 @@ private:
264
264
  }
265
265
  }
266
266
  }
267
-
267
+
268
268
  /** One of the post lock actions can potentially perform a long-running
269
269
  * operation, so running them in a thread is advised.
270
270
  */
@@ -274,7 +274,7 @@ private:
274
274
  if (group == NULL) {
275
275
  continue;
276
276
  }
277
-
277
+
278
278
  while (!group->getWaitlist.empty()) {
279
279
  getWaitlist.push_back(group->getWaitlist.front());
280
280
  group->getWaitlist.pop_front();
@@ -290,7 +290,7 @@ private:
290
290
 
291
291
  groups.clear();
292
292
  }
293
-
293
+
294
294
  void assignGetWaitlistToGroups(vector<Callback> &postLockActions) {
295
295
  while (!getWaitlist.empty()) {
296
296
  GetWaiter &waiter = getWaitlist.front();
@@ -306,7 +306,7 @@ private:
306
306
  getWaitlist.pop_front();
307
307
  }
308
308
  }
309
-
309
+
310
310
  void adjustOptions(Options &options, const Group *group) const {
311
311
  // No-op.
312
312
  }
@@ -321,12 +321,12 @@ private:
321
321
 
322
322
  void realDoInitialize(const Options &options, unsigned int generation);
323
323
  void realDoRestart(const Options &options, unsigned int generation);
324
-
324
+
325
325
  void doDestroy(SuperGroupPtr self, unsigned int generation, ShutdownCallback callback) {
326
326
  TRACE_POINT();
327
-
327
+
328
328
  runDestructionHooks();
329
-
329
+
330
330
  // Wait until 'detachedGroups' is empty.
331
331
  UPDATE_TRACE_POINT();
332
332
  PoolPtr pool = getPool();
@@ -350,7 +350,7 @@ private:
350
350
  verifyInvariants();
351
351
  }
352
352
  }
353
-
353
+
354
354
  UPDATE_TRACE_POINT();
355
355
  assert(state == DESTROYING);
356
356
  state = DESTROYED;
@@ -361,29 +361,29 @@ private:
361
361
  callback(SUCCESS);
362
362
  }
363
363
  }
364
-
364
+
365
365
  /*********************/
366
-
366
+
367
367
  /*********************/
368
-
368
+
369
369
  public:
370
370
  mutable boost::mutex backrefSyncher;
371
371
  const boost::weak_ptr<Pool> pool;
372
-
372
+
373
373
  State state;
374
374
  string name;
375
375
  string secret;
376
-
376
+
377
377
  /** Invariant:
378
378
  * groups.empty() == (state == INITIALIZING || state == DESTROYING || state == DESTROYED)
379
379
  */
380
380
  vector<GroupPtr> groups;
381
-
381
+
382
382
  /** Invariant:
383
383
  * (defaultGroup == NULL) == (state == INITIALIZING || state == DESTROYING || state == DESTROYED)
384
384
  */
385
385
  Group *defaultGroup;
386
-
386
+
387
387
  /**
388
388
  * get() requests for this super group that cannot be immediately satisfied
389
389
  * are put on this wait list, which must be processed as soon as the
@@ -413,7 +413,7 @@ public:
413
413
  * detachedGroups.empty()
414
414
  */
415
415
  vector<GroupPtr> detachedGroups;
416
-
416
+
417
417
  /** One MUST call initialize() after construction because shared_from_this()
418
418
  * is not available in the constructor.
419
419
  */
@@ -446,7 +446,7 @@ public:
446
446
  "SuperGroup initializer: " + name,
447
447
  POOL_HELPER_THREAD_STACK_SIZE);
448
448
  }
449
-
449
+
450
450
  /**
451
451
  * Thread-safe.
452
452
  *
@@ -462,7 +462,7 @@ public:
462
462
  bool isAlive() const {
463
463
  return state != DESTROYING && state != DESTROYED;
464
464
  }
465
-
465
+
466
466
  const char *getStateName() const {
467
467
  switch (state) {
468
468
  case INITIALIZING:
@@ -551,7 +551,7 @@ public:
551
551
  verifyInvariants();
552
552
  }
553
553
  }
554
-
554
+
555
555
  /**
556
556
  * @post
557
557
  * if result:
@@ -561,7 +561,7 @@ public:
561
561
  /* if (state == READY) {
562
562
  vector<GroupPtr>::const_iterator it, end = groups.end();
563
563
  bool result = true;
564
-
564
+
565
565
  for (it = groups.begin(); result && it != end; it++) {
566
566
  result = result && (*it)->garbageCollectable(now);
567
567
  }
@@ -573,7 +573,7 @@ public:
573
573
  } */
574
574
  return false;
575
575
  }
576
-
576
+
577
577
  SessionPtr get(const Options &newOptions, const GetCallback &callback,
578
578
  vector<Callback> &postLockActions)
579
579
  {
@@ -616,15 +616,15 @@ public:
616
616
  return SessionPtr(); // Shut up compiler warning.
617
617
  };
618
618
  }
619
-
619
+
620
620
  Group *route(const Options &options) const {
621
621
  return defaultGroup;
622
622
  }
623
-
623
+
624
624
  unsigned int capacityUsed() const {
625
625
  vector<GroupPtr>::const_iterator it, end = groups.end();
626
626
  unsigned int result = 0;
627
-
627
+
628
628
  for (it = groups.begin(); it != end; it++) {
629
629
  result += (*it)->capacityUsed();
630
630
  }
@@ -647,7 +647,7 @@ public:
647
647
  bool needsRestart() const {
648
648
  return false;
649
649
  }
650
-
650
+
651
651
  void restart(const Options &options) {
652
652
  verifyInvariants();
653
653
  if (state == READY) {
@@ -63,7 +63,7 @@ startBackgroundLoop(BackgroundEventLoop *bg) {
63
63
 
64
64
  BackgroundEventLoop::BackgroundEventLoop(bool scalable) {
65
65
  TRACE_POINT();
66
-
66
+
67
67
  if (scalable) {
68
68
  loop = ev_loop_new(EVBACKEND_KQUEUE);
69
69
  if (loop == NULL) {
@@ -48,10 +48,10 @@ namespace Passenger {
48
48
  ev_async *async;
49
49
  boost::shared_ptr<SafeLibev> safe;
50
50
  BackgroundEventLoopPrivate *priv;
51
-
51
+
52
52
  BackgroundEventLoop(bool scalable = false);
53
53
  ~BackgroundEventLoop();
54
-
54
+
55
55
  void start(const string &threadName = "", unsigned int stackSize = 1024 * 1024);
56
56
  void stop();
57
57
  bool isStarted() const;
@@ -90,7 +90,7 @@
90
90
 
91
91
  #define NGINX_DOC_URL "https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html"
92
92
 
93
- #define PASSENGER_VERSION "4.0.48"
93
+ #define PASSENGER_VERSION "4.0.49"
94
94
 
95
95
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
96
96
 
@@ -90,7 +90,7 @@ private:
90
90
  /**
91
91
  * Whether this EventedBufferedInput is paused (not started). If it's
92
92
  * paused it should not emit data events.
93
- *
93
+ *
94
94
  * @invariant
95
95
  * if paused:
96
96
  * socketPaused
@@ -123,13 +123,13 @@ private:
123
123
 
124
124
  void verifyInvariants() {
125
125
  // !a || b: logical equivalent of a IMPLIES b.
126
-
126
+
127
127
  assert(!( state == END_OF_STREAM ) || ( paused ));
128
128
  assert(!( state == END_OF_STREAM ) || ( socketPaused ));
129
-
129
+
130
130
  assert(!( state == READ_ERROR ) || ( paused ));
131
131
  assert(!( state == READ_ERROR ) || ( socketPaused ));
132
-
132
+
133
133
  assert(!( paused ) || ( socketPaused ));
134
134
  }
135
135
 
@@ -381,7 +381,7 @@ public:
381
381
  EBI_TRACE("start()");
382
382
  verifyInvariants();
383
383
  assert(socketPaused);
384
-
384
+
385
385
  paused = false;
386
386
  if (!buffer.empty()) {
387
387
  processBufferInNextTick();
@@ -91,7 +91,7 @@ using namespace oxt;
91
91
  * void onReadable(EventedClient *client) {
92
92
  * // do whatever you want
93
93
  * }
94
- *
94
+ *
95
95
  * ...
96
96
  * client->onReadable = onReadable;
97
97
  * client->notifyReads(true);
@@ -107,7 +107,7 @@ class EventedClient {
107
107
  public:
108
108
  typedef void (*Callback)(EventedClient *client);
109
109
  typedef void (*SystemErrorCallback)(EventedClient *client, const string &message, int code);
110
-
110
+
111
111
  protected:
112
112
  enum {
113
113
  /**
@@ -117,7 +117,7 @@ protected:
117
117
  * only be watching for read events.
118
118
  */
119
119
  EC_CONNECTED,
120
-
120
+
121
121
  /**
122
122
  * This state is entered from EC_CONNECTED when the write()
123
123
  * method fails to send all data immediately and EventedClient
@@ -127,7 +127,7 @@ protected:
127
127
  * will transition back to EC_CONNECTED.
128
128
  */
129
129
  EC_WRITES_PENDING,
130
-
130
+
131
131
  /**
132
132
  * This state is entered from EC_WRITES_PENDING or from EC_CONNECTED
133
133
  * when the write() method fails to send all data immediately, and
@@ -139,14 +139,14 @@ protected:
139
139
  * to EC_CONNECTED.
140
140
  */
141
141
  EC_TOO_MANY_WRITES_PENDING,
142
-
142
+
143
143
  /**
144
144
  * This state is like EC_CONNECTED, but indicates that the write
145
145
  * side of the connection has been closed. In this state write()
146
146
  * calls won't have any effect.
147
147
  */
148
148
  EC_RO_CONNECTED,
149
-
149
+
150
150
  /**
151
151
  * This state is entered from EC_WRITES_PENDING when
152
152
  * closeWrite() has been called. The system will continue
@@ -155,7 +155,7 @@ protected:
155
155
  * the system will transition to EC_RO_CONNECTED.
156
156
  */
157
157
  EC_RO_CONNECTED_WITH_WRITES_PENDING,
158
-
158
+
159
159
  /**
160
160
  * This state is entered from the EC_WRITES_PENDING,
161
161
  * EC_TOO_MANY_WRITES_PENDING, EC_RO_CONNECTED_WITH_WIRTES_PENDING
@@ -167,14 +167,14 @@ protected:
167
167
  * I/O should be allowed.
168
168
  */
169
169
  EC_DISCONNECTING_WITH_WRITES_PENDING,
170
-
170
+
171
171
  /**
172
172
  * Final state. Client connection has been closed. No
173
173
  * I/O with the client is possible.
174
174
  */
175
175
  EC_DISCONNECTED
176
176
  } state;
177
-
177
+
178
178
  /** A libev watcher on for watching read events on <tt>fd</tt>. */
179
179
  ev::io readWatcher;
180
180
  /** A libev watcher on for watching write events on <tt>fd</tt>. */
@@ -184,21 +184,21 @@ protected:
184
184
  int refcount;
185
185
  unsigned int outboxLimit;
186
186
  bool m_notifyReads;
187
-
187
+
188
188
  void _onReadable(ev::io &w, int revents) {
189
189
  emitEvent(onReadable);
190
190
  }
191
-
191
+
192
192
  void onWritable(ev::io &w, int revents) {
193
193
  assert(state != EC_CONNECTED);
194
194
  assert(state != EC_RO_CONNECTED);
195
195
  assert(state != EC_DISCONNECTED);
196
-
196
+
197
197
  this_thread::disable_interruption di;
198
198
  this_thread::disable_syscall_interruption dsi;
199
199
  size_t sent = 0;
200
200
  bool done = outbox.empty();
201
-
201
+
202
202
  while (!done) {
203
203
  ssize_t ret = syscalls::write(fd,
204
204
  outbox.data() + sent,
@@ -223,17 +223,17 @@ protected:
223
223
  if (sent > 0) {
224
224
  outbox.erase(0, sent);
225
225
  }
226
-
226
+
227
227
  updateWatcherStates();
228
228
  if (outbox.empty()) {
229
229
  emitEvent(onPendingDataFlushed);
230
230
  }
231
231
  }
232
-
232
+
233
233
  bool outboxTooLarge() {
234
234
  return outbox.size() > 0 && outbox.size() >= outboxLimit;
235
235
  }
236
-
236
+
237
237
  void updateWatcherStates() {
238
238
  if (outbox.empty()) {
239
239
  switch (state) {
@@ -303,7 +303,7 @@ protected:
303
303
  }
304
304
  }
305
305
  }
306
-
306
+
307
307
  void watchReadEvents(bool enable = true) {
308
308
  if (readWatcher.is_active() && !enable) {
309
309
  readWatcher.stop();
@@ -311,7 +311,7 @@ protected:
311
311
  readWatcher.start();
312
312
  }
313
313
  }
314
-
314
+
315
315
  void watchWriteEvents(bool enable = true) {
316
316
  if (writeWatcher.is_active() && !enable) {
317
317
  writeWatcher.stop();
@@ -319,23 +319,23 @@ protected:
319
319
  writeWatcher.start();
320
320
  }
321
321
  }
322
-
322
+
323
323
  void emitEvent(Callback callback) {
324
324
  if (callback != NULL) {
325
325
  callback(this);
326
326
  }
327
327
  }
328
-
328
+
329
329
  void emitSystemErrorEvent(const string &message, int code) {
330
330
  if (onSystemError != NULL) {
331
331
  onSystemError(this, message, code);
332
332
  }
333
333
  }
334
-
334
+
335
335
  public:
336
336
  /** The client's file descriptor. Could be -1: see <tt>ioAllowed()</tt>. */
337
337
  FileDescriptor fd;
338
-
338
+
339
339
  /** Controls what to do when a write error is encountered. */
340
340
  enum {
341
341
  /** Forcefully disconnect the client. */
@@ -343,7 +343,7 @@ public:
343
343
  /** Close the writer side of the connection, but continue allowing reading. */
344
344
  DISCONNECT_WRITE
345
345
  } writeErrorAction;
346
-
346
+
347
347
  /**
348
348
  * Called when the file descriptor becomes readable and read notifications
349
349
  * are enabled (see <tt>notifyRead()</tt>). When there's too much pending
@@ -351,7 +351,7 @@ public:
351
351
  * <tt>write()</tt> for details.
352
352
  */
353
353
  Callback onReadable;
354
-
354
+
355
355
  /**
356
356
  * Called when the client is disconnected. This happens either immediately
357
357
  * when <tt>disconnect()</tt> is called, or a short amount of time later.
@@ -361,12 +361,12 @@ public:
361
361
  * this callback to be called.
362
362
  */
363
363
  Callback onDisconnect;
364
-
364
+
365
365
  /**
366
366
  * Called when <tt>detach()</tt> is called for the first time.
367
367
  */
368
368
  Callback onDetach;
369
-
369
+
370
370
  /**
371
371
  * Called after all pending outgoing data have been written out.
372
372
  * If <tt>write()</tt> can be completed immediately without scheduling
@@ -374,17 +374,17 @@ public:
374
374
  * immediately after writing.
375
375
  */
376
376
  Callback onPendingDataFlushed;
377
-
377
+
378
378
  /**
379
379
  * System call errors are reported with this callback.
380
380
  */
381
381
  SystemErrorCallback onSystemError;
382
-
382
+
383
383
  /**
384
384
  * EventedClient doesn't do anything with this. Set it to whatever you want.
385
385
  */
386
386
  void *userData;
387
-
387
+
388
388
  /**
389
389
  * Creates a new EventedClient with the given libev loop and file descriptor.
390
390
  * The initial reference count is 1.
@@ -410,21 +410,21 @@ public:
410
410
  writeWatcher.set<EventedClient, &EventedClient::onWritable>(this);
411
411
  writeWatcher.set(fd, ev::WRITE);
412
412
  }
413
-
413
+
414
414
  virtual ~EventedClient() {
415
415
  // Unregister file descriptor from the event loop poller before
416
416
  // closing the file descriptor.
417
417
  watchReadEvents(false);
418
418
  watchWriteEvents(false);
419
419
  }
420
-
420
+
421
421
  /**
422
422
  * Increase reference count.
423
423
  */
424
424
  void ref() {
425
425
  refcount++;
426
426
  }
427
-
427
+
428
428
  /**
429
429
  * Decrease reference count. Upon reaching 0, this EventedClient object
430
430
  * will be destroyed.
@@ -436,7 +436,7 @@ public:
436
436
  delete this;
437
437
  }
438
438
  }
439
-
439
+
440
440
  /**
441
441
  * Returns whether it is allowed to perform some kind of I/O with
442
442
  * this client, either reading or writing.
@@ -452,7 +452,7 @@ public:
452
452
  return state != EC_DISCONNECTING_WITH_WRITES_PENDING
453
453
  && state != EC_DISCONNECTED;
454
454
  }
455
-
455
+
456
456
  /**
457
457
  * Returns whether it is allowed to write data to the client.
458
458
  * Usually true, and false when the client is either being disconnected
@@ -466,22 +466,22 @@ public:
466
466
  || state == EC_TOO_MANY_WRITES_PENDING
467
467
  || state == EC_RO_CONNECTED_WITH_WRITES_PENDING;
468
468
  }
469
-
469
+
470
470
  /** Used by unit tests. */
471
471
  bool readWatcherActive() const {
472
472
  return readWatcher.is_active();
473
473
  }
474
-
474
+
475
475
  /**
476
476
  * Returns the number of bytes that are scheduled to be sent to the
477
477
  * client at a later time.
478
- *
478
+ *
479
479
  * @see write()
480
480
  */
481
481
  size_t pendingWrites() const {
482
482
  return outbox.size();
483
483
  }
484
-
484
+
485
485
  /**
486
486
  * Sets whether you're interested in read events. This will start or
487
487
  * stop the input readiness watcher appropriately according to the
@@ -494,13 +494,13 @@ public:
494
494
  if (!ioAllowed()) {
495
495
  return;
496
496
  }
497
-
497
+
498
498
  this_thread::disable_interruption di;
499
499
  this_thread::disable_syscall_interruption dsi;
500
500
  m_notifyReads = enable;
501
501
  updateWatcherStates();
502
502
  }
503
-
503
+
504
504
  /**
505
505
  * Sets a limit on the client outbox. The outbox is where data is stored
506
506
  * that could not be immediately sent to the client, e.g. because of
@@ -521,17 +521,17 @@ public:
521
521
  if (!ioAllowed()) {
522
522
  return;
523
523
  }
524
-
524
+
525
525
  this_thread::disable_interruption di;
526
526
  this_thread::disable_syscall_interruption dsi;
527
527
  outboxLimit = size;
528
528
  updateWatcherStates();
529
529
  }
530
-
530
+
531
531
  void write(const StaticString &data) {
532
532
  write(&data, 1);
533
533
  }
534
-
534
+
535
535
  /**
536
536
  * Sends data to this client. This method will try to send the data
537
537
  * immediately (in which no intermediate copies of the data will be made),
@@ -558,11 +558,11 @@ public:
558
558
  if (!writeAllowed()) {
559
559
  return;
560
560
  }
561
-
561
+
562
562
  ssize_t ret;
563
563
  this_thread::disable_interruption di;
564
564
  this_thread::disable_syscall_interruption dsi;
565
-
565
+
566
566
  ret = gatheredWrite(fd, data, count, outbox);
567
567
  if (ret == -1) {
568
568
  int e = errno;
@@ -579,7 +579,7 @@ public:
579
579
  }
580
580
  }
581
581
  }
582
-
582
+
583
583
  /**
584
584
  * Close only the writer side of the client connection.
585
585
  * After calling this method, subsequent write() calls won't do anything
@@ -591,7 +591,7 @@ public:
591
591
  */
592
592
  void closeWrite() {
593
593
  this_thread::disable_syscall_interruption dsi;
594
-
594
+
595
595
  switch (state) {
596
596
  case EC_CONNECTED:
597
597
  assert(outbox.empty());
@@ -612,7 +612,7 @@ public:
612
612
  }
613
613
  updateWatcherStates();
614
614
  }
615
-
615
+
616
616
  /**
617
617
  * Disconnects the client. This actually closes the underlying file
618
618
  * descriptor, even if the FileDescriptor object still has references.
@@ -642,10 +642,10 @@ public:
642
642
  if (!ioAllowed() && !(state == EC_DISCONNECTING_WITH_WRITES_PENDING && force)) {
643
643
  return;
644
644
  }
645
-
645
+
646
646
  this_thread::disable_interruption di;
647
647
  this_thread::disable_syscall_interruption dsi;
648
-
648
+
649
649
  if (state == EC_CONNECTED || state == EC_RO_CONNECTED || force) {
650
650
  state = EC_DISCONNECTED;
651
651
  watchReadEvents(false);
@@ -668,7 +668,7 @@ public:
668
668
  }
669
669
  }
670
670
  }
671
-
671
+
672
672
  /**
673
673
  * Detaches the client file descriptor so that this EventedClient no longer
674
674
  * has any control over it. Any EventedClient I/O watchers on the client file