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
@@ -29,6 +29,7 @@
29
29
  #include <boost/bind.hpp>
30
30
  #include <boost/make_shared.hpp>
31
31
  #include <boost/date_time/posix_time/posix_time_types.hpp>
32
+ #include "macros.hpp"
32
33
  #include "system_calls.hpp"
33
34
  #include "detail/context.hpp"
34
35
  #include <string>
@@ -38,6 +39,13 @@
38
39
 
39
40
  namespace oxt {
40
41
 
42
+ #ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
43
+ /** A thread-specific signature that you can use for identifying threads.
44
+ * It defaults to NULL. You have to set it manually in every thread.
45
+ */
46
+ extern __thread void *thread_signature;
47
+ #endif
48
+
41
49
  /**
42
50
  * Enhanced thread class with support for:
43
51
  * - user-defined stack size.
@@ -50,7 +58,7 @@ private:
50
58
 
51
59
  static std::string make_thread_name(const std::string &given_name);
52
60
  static void thread_main(const boost::function<void ()> func, thread_local_context_ptr ctx);
53
-
61
+
54
62
  public:
55
63
  /**
56
64
  * Create a new thread.
@@ -82,7 +90,7 @@ public:
82
90
  unsigned long min_stack_size;
83
91
  bool stack_min_size_defined;
84
92
  bool round_stack_size;
85
-
93
+
86
94
  #ifdef PTHREAD_STACK_MIN
87
95
  // PTHREAD_STACK_MIN may not be a constant macro so we need
88
96
  // to evaluate it dynamically.
@@ -99,7 +107,7 @@ public:
99
107
  } else {
100
108
  round_stack_size = true;
101
109
  }
102
-
110
+
103
111
  if (round_stack_size) {
104
112
  // Round stack size up to page boundary.
105
113
  long page_size;
@@ -123,23 +131,23 @@ public:
123
131
  attrs.set_stack_size(stack_size);
124
132
  start_thread(attrs);
125
133
  }
126
-
134
+
127
135
  /**
128
136
  * Return this thread's name. The name was set during construction.
129
137
  */
130
138
  std::string name() const throw();
131
-
139
+
132
140
  /**
133
141
  * Return the current backtrace of the thread of execution, as a string.
134
142
  */
135
143
  std::string backtrace() const throw();
136
-
144
+
137
145
  /**
138
146
  * Return the backtraces of all oxt::thread threads, as well as that of the
139
147
  * main thread, in a nicely formatted string.
140
148
  */
141
149
  static std::string all_backtraces() throw();
142
-
150
+
143
151
  /**
144
152
  * Interrupt the thread. This method behaves just like
145
153
  * boost::thread::interrupt(), but if <em>interruptSyscalls</em> is true
@@ -153,7 +161,7 @@ public:
153
161
  * pattern.
154
162
  */
155
163
  void interrupt(bool interruptSyscalls = true);
156
-
164
+
157
165
  /**
158
166
  * Keep interrupting the thread until it's done, then join it.
159
167
  *
@@ -169,7 +177,7 @@ public:
169
177
  done = timed_join(boost::posix_time::millisec(10));
170
178
  }
171
179
  }
172
-
180
+
173
181
  /**
174
182
  * Keep interrupting the thread until it's done, then join it.
175
183
  * This method will keep trying for at most <em>timeout</em> milliseconds.
@@ -195,7 +203,7 @@ public:
195
203
  }
196
204
  return joined;
197
205
  }
198
-
206
+
199
207
  /**
200
208
  * Interrupt and join multiple threads in a way that's more efficient than calling
201
209
  * interrupt_and_join() on each thread individually. It iterates over all threads,
@@ -217,11 +225,11 @@ public:
217
225
  std::list<oxt::thread *>::iterator it, current;
218
226
  oxt::thread *thread;
219
227
  unsigned int i;
220
-
228
+
221
229
  for (i = 0; i < size; i++) {
222
230
  remaining_threads.push_back(threads[i]);
223
231
  }
224
-
232
+
225
233
  while (!remaining_threads.empty()) {
226
234
  for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
227
235
  thread = *it;
@@ -252,7 +260,7 @@ private:
252
260
  public:
253
261
  interruptable_lock_guard(TimedLockable &m): mutex(m) {
254
262
  bool locked = false;
255
-
263
+
256
264
  while (!locked) {
257
265
  locked = m.timed_lock(boost::posix_time::milliseconds(20));
258
266
  if (!locked) {
@@ -260,7 +268,7 @@ public:
260
268
  }
261
269
  }
262
270
  }
263
-
271
+
264
272
  ~interruptable_lock_guard() {
265
273
  mutex.unlock();
266
274
  }
@@ -119,7 +119,7 @@ split_by_null_into_hash(VALUE self, VALUE data) {
119
119
  const char *current = cdata;
120
120
  const char *end = cdata + len;
121
121
  VALUE result, key, value;
122
-
122
+
123
123
  result = rb_hash_new();
124
124
  while (current < end) {
125
125
  if (*current == '\0') {
@@ -145,10 +145,10 @@ split_by_null_into_hash(VALUE self, VALUE data) {
145
145
  typedef struct {
146
146
  /* The IO vectors in this group. */
147
147
  struct iovec *io_vectors;
148
-
148
+
149
149
  /* The number of IO vectors in io_vectors. */
150
150
  unsigned int count;
151
-
151
+
152
152
  /* The combined size of all IO vectors in this group. */
153
153
  ssize_t total_size;
154
154
  } IOVectorGroup;
@@ -162,7 +162,7 @@ update_group_written_info(IOVectorGroup *group, ssize_t bytes_written) {
162
162
  unsigned int i;
163
163
  size_t counter;
164
164
  struct iovec *current_vec;
165
-
165
+
166
166
  /* Find the last vector that contains data that had already been written. */
167
167
  counter = 0;
168
168
  for (i = 0; i < group->count; i++) {
@@ -198,7 +198,7 @@ update_group_written_info(IOVectorGroup *group, ssize_t bytes_written) {
198
198
  const struct iovec *iov;
199
199
  int iovcnt;
200
200
  } WritevWrapperData;
201
-
201
+
202
202
  static VALUE
203
203
  writev_wrapper(void *ptr) {
204
204
  WritevWrapperData *data = (WritevWrapperData *) ptr;
@@ -218,7 +218,7 @@ f_generic_writev(VALUE fd, VALUE *array_of_components, unsigned int count) {
218
218
  #ifndef TRAP_BEG
219
219
  WritevWrapperData writev_wrapper_data;
220
220
  #endif
221
-
221
+
222
222
  /* First determine the number of components that we have. */
223
223
  total_components = 0;
224
224
  for (i = 0; i < count; i++) {
@@ -228,7 +228,7 @@ f_generic_writev(VALUE fd, VALUE *array_of_components, unsigned int count) {
228
228
  if (total_components == 0) {
229
229
  return NUM2INT(0);
230
230
  }
231
-
231
+
232
232
  /* A single writev() call can only accept IOV_MAX vectors, so we
233
233
  * may have to split the components into groups and perform
234
234
  * multiple writev() calls, one per group. Determine the number
@@ -269,7 +269,7 @@ f_generic_writev(VALUE fd, VALUE *array_of_components, unsigned int count) {
269
269
  }
270
270
  groups[ngroups - 1].count = total_components % IOV_MAX;
271
271
  }
272
-
272
+
273
273
  /* Now distribute the components among the groups, filling the iovec
274
274
  * array in each group. Also calculate the total data size while we're
275
275
  * at it.
@@ -297,19 +297,19 @@ f_generic_writev(VALUE fd, VALUE *array_of_components, unsigned int count) {
297
297
  }
298
298
  }
299
299
  }
300
-
300
+
301
301
  /* We don't compare to SSIZE_MAX directly in order to shut up a compiler warning on OS X Snow Leopard. */
302
302
  ssize_max = SSIZE_MAX;
303
303
  if (total_size > ssize_max) {
304
304
  rb_raise(rb_eArgError, "The total size of the components may not be larger than SSIZE_MAX.");
305
305
  }
306
-
306
+
307
307
  /* Write the data. */
308
308
  fd_num = NUM2INT(fd);
309
309
  for (i = 0; i < ngroups; i++) {
310
310
  /* Wait until the file descriptor becomes writable before writing things. */
311
311
  rb_thread_fd_writable(fd_num);
312
-
312
+
313
313
  done = 0;
314
314
  while (!done) {
315
315
  #ifdef TRAP_BEG
@@ -399,11 +399,11 @@ static VALUE
399
399
  process_times(VALUE self) {
400
400
  struct rusage usage;
401
401
  unsigned long long utime, stime;
402
-
402
+
403
403
  if (getrusage(RUSAGE_SELF, &usage) == -1) {
404
404
  rb_sys_fail("getrusage()");
405
405
  }
406
-
406
+
407
407
  utime = (unsigned long long) usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec;
408
408
  stime = (unsigned long long) usage.ru_stime.tv_sec * 1000000 + usage.ru_stime.tv_usec;
409
409
  return rb_struct_new(S_ProcessTimes, rb_ull2inum(utime), rb_ull2inum(stime));
@@ -424,11 +424,11 @@ detach_process(VALUE self, VALUE pid) {
424
424
  pthread_t thr;
425
425
  pthread_attr_t attr;
426
426
  size_t stack_size = 96 * 1024;
427
-
427
+
428
428
  unsigned long min_stack_size;
429
429
  int stack_min_size_defined;
430
430
  int round_stack_size;
431
-
431
+
432
432
  #ifdef PTHREAD_STACK_MIN
433
433
  // PTHREAD_STACK_MIN may not be a constant macro so we need
434
434
  // to evaluate it dynamically.
@@ -445,7 +445,7 @@ detach_process(VALUE self, VALUE pid) {
445
445
  } else {
446
446
  round_stack_size = 1;
447
447
  }
448
-
448
+
449
449
  if (round_stack_size) {
450
450
  // Round stack size up to page boundary.
451
451
  long page_size;
@@ -464,7 +464,7 @@ detach_process(VALUE self, VALUE pid) {
464
464
  stack_size = stack_size - (stack_size % page_size) + page_size;
465
465
  }
466
466
  }
467
-
467
+
468
468
  pthread_attr_init(&attr);
469
469
  pthread_attr_setdetachstate(&attr, 1);
470
470
  pthread_attr_setstacksize(&attr, stack_size);
@@ -490,24 +490,24 @@ typedef struct {
490
490
  VALUE klass;
491
491
  VALUE filenames;
492
492
  VALUE termination_pipe;
493
-
493
+
494
494
  /* File descriptor of termination_pipe. */
495
495
  int termination_fd;
496
-
496
+
497
497
  /* Whether something went wrong during initialization. */
498
498
  int preparation_error;
499
-
499
+
500
500
  /* Information for kqueue. */
501
501
  unsigned int events_len;
502
502
  int *fds;
503
503
  unsigned int fds_len;
504
504
  int kq;
505
-
505
+
506
506
  /* When the watcher thread is done it'll write to this pipe
507
507
  * to signal the main (Ruby) thread.
508
508
  */
509
509
  int notification_fd[2];
510
-
510
+
511
511
  /* When the main (Ruby) thread is interrupted it'll write to
512
512
  * this pipe to tell the watcher thread to exit.
513
513
  */
@@ -524,7 +524,7 @@ typedef struct {
524
524
  static void
525
525
  fs_watcher_real_close(FSWatcher *watcher) {
526
526
  unsigned int i;
527
-
527
+
528
528
  if (watcher->kq != -1) {
529
529
  close(watcher->kq);
530
530
  watcher->kq = -1;
@@ -572,9 +572,9 @@ fs_watcher_init(VALUE arg) {
572
572
  VALUE filenum;
573
573
  struct stat buf;
574
574
  int fd;
575
-
575
+
576
576
  /* Open each file in the filenames list and add each one to the events array. */
577
-
577
+
578
578
  /* +2 for the termination pipe and the interruption pipe. */
579
579
  events = alloca((RARRAY_LEN(watcher->filenames) + 2) * sizeof(struct kevent));
580
580
  watcher->fds = malloc(RARRAY_LEN(watcher->filenames) * sizeof(int));
@@ -587,12 +587,12 @@ fs_watcher_init(VALUE arg) {
587
587
  if (TYPE(filename) != T_STRING) {
588
588
  filename = rb_obj_as_string(filename);
589
589
  }
590
-
590
+
591
591
  if (stat(RSTRING_PTR(filename), &buf) == -1) {
592
592
  watcher->preparation_error = 1;
593
593
  goto end;
594
594
  }
595
-
595
+
596
596
  #ifdef O_EVTONLY
597
597
  fd = open(RSTRING_PTR(filename), O_EVTONLY);
598
598
  #else
@@ -602,18 +602,18 @@ fs_watcher_init(VALUE arg) {
602
602
  watcher->preparation_error = 1;
603
603
  goto end;
604
604
  }
605
-
605
+
606
606
  watcher->fds[i] = fd;
607
607
  watcher->fds_len++;
608
608
  fflags = NOTE_WRITE | NOTE_EXTEND | NOTE_RENAME | NOTE_DELETE | NOTE_REVOKE;
609
609
  EV_SET(&events[i], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
610
610
  fflags, 0, 0);
611
611
  }
612
-
612
+
613
613
  watcher->events_len = watcher->fds_len;
614
-
614
+
615
615
  /* Create pipes for inter-thread communication. */
616
-
616
+
617
617
  if (pipe(watcher->notification_fd) == -1) {
618
618
  rb_sys_fail("pipe()");
619
619
  return Qnil;
@@ -622,15 +622,15 @@ fs_watcher_init(VALUE arg) {
622
622
  rb_sys_fail("pipe()");
623
623
  return Qnil;
624
624
  }
625
-
625
+
626
626
  /* Create a kqueue and register all events. */
627
-
627
+
628
628
  watcher->kq = kqueue();
629
629
  if (watcher->kq == -1) {
630
630
  rb_sys_fail("kqueue()");
631
631
  return Qnil;
632
632
  }
633
-
633
+
634
634
  if (watcher->termination_pipe != Qnil) {
635
635
  filenum = rb_funcall(watcher->termination_pipe,
636
636
  rb_intern("fileno"), 0);
@@ -642,12 +642,12 @@ fs_watcher_init(VALUE arg) {
642
642
  EV_SET(&events[watcher->events_len], watcher->interruption_fd[0],
643
643
  EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0);
644
644
  watcher->events_len++;
645
-
645
+
646
646
  if (kevent(watcher->kq, events, watcher->events_len, NULL, 0, NULL) == -1) {
647
647
  rb_sys_fail("kevent()");
648
648
  return Qnil;
649
649
  }
650
-
650
+
651
651
  end:
652
652
  if (watcher->preparation_error) {
653
653
  for (i = 0; i < watcher->fds_len; i++) {
@@ -665,7 +665,7 @@ fs_watcher_new(VALUE klass, VALUE filenames, VALUE termination_pipe) {
665
665
  FSWatcher *watcher;
666
666
  VALUE result;
667
667
  int status;
668
-
668
+
669
669
  Check_Type(filenames, T_ARRAY);
670
670
  watcher = (FSWatcher *) calloc(1, sizeof(FSWatcher));
671
671
  if (watcher == NULL) {
@@ -681,7 +681,7 @@ fs_watcher_new(VALUE klass, VALUE filenames, VALUE termination_pipe) {
681
681
  watcher->notification_fd[1] = -1;
682
682
  watcher->interruption_fd[0] = -1;
683
683
  watcher->interruption_fd[1] = -1;
684
-
684
+
685
685
  result = rb_protect(fs_watcher_init, (VALUE) watcher, &status);
686
686
  if (status) {
687
687
  fs_watcher_free(watcher);
@@ -698,7 +698,7 @@ fs_watcher_wait_on_kqueue(void *arg) {
698
698
  struct kevent *events;
699
699
  int nevents;
700
700
  ssize_t ret;
701
-
701
+
702
702
  events = alloca(sizeof(struct kevent) * watcher->events_len);
703
703
  nevents = kevent(watcher->kq, NULL, 0, events, watcher->events_len, NULL);
704
704
  if (nevents == -1) {
@@ -760,27 +760,27 @@ fs_watcher_wait_for_change(VALUE self) {
760
760
  ssize_t ret;
761
761
  int e, interrupted = 0;
762
762
  FSWatcherReadByteData read_data;
763
-
763
+
764
764
  Data_Get_Struct(self, FSWatcher, watcher);
765
-
765
+
766
766
  if (watcher->preparation_error) {
767
767
  return Qfalse;
768
768
  }
769
-
769
+
770
770
  /* Spawn a thread, and let the thread perform the blocking kqueue
771
771
  * wait. When kevent() returns the thread will write its status to the
772
772
  * notification pipe. In the mean time we let the Ruby interpreter wait
773
773
  * on the other side of the pipe for us so that we don't block Ruby
774
774
  * threads.
775
775
  */
776
-
776
+
777
777
  e = pthread_create(&thr, NULL, fs_watcher_wait_on_kqueue, watcher);
778
778
  if (e != 0) {
779
779
  errno = e;
780
780
  rb_sys_fail("pthread_create()");
781
781
  return Qnil;
782
782
  }
783
-
783
+
784
784
  /* Note that rb_thread_wait() does not wait for the fd when the app
785
785
  * is single threaded, so we must join the thread after we've read
786
786
  * from the notification fd.
@@ -797,13 +797,13 @@ fs_watcher_wait_for_change(VALUE self) {
797
797
  return Qnil;
798
798
  }
799
799
  pthread_join(thr, NULL);
800
-
800
+
801
801
  /* Now clean up stuff. */
802
802
  fs_watcher_real_close(watcher);
803
803
  rb_jump_tag(interrupted);
804
804
  return Qnil;
805
805
  }
806
-
806
+
807
807
  read_data.fd = watcher->notification_fd[0];
808
808
  rb_protect(fs_watcher_read_byte_from_fd, (VALUE) &read_data, &interrupted);
809
809
  if (interrupted) {
@@ -817,15 +817,15 @@ fs_watcher_wait_for_change(VALUE self) {
817
817
  return Qnil;
818
818
  }
819
819
  pthread_join(thr, NULL);
820
-
820
+
821
821
  /* Now clean up stuff. */
822
822
  fs_watcher_real_close(watcher);
823
823
  rb_jump_tag(interrupted);
824
824
  return Qnil;
825
825
  }
826
-
826
+
827
827
  pthread_join(thr, NULL);
828
-
828
+
829
829
  if (read_data.ret == -1) {
830
830
  fs_watcher_real_close(watcher);
831
831
  errno = read_data.error;
@@ -865,7 +865,7 @@ fs_watcher_close(VALUE self) {
865
865
  void
866
866
  Init_passenger_native_support() {
867
867
  struct sockaddr_un addr;
868
-
868
+
869
869
  /* Only defined on Ruby >= 1.9.3 */
870
870
  #ifdef RUBY_API_VERSION_CODE
871
871
  if (ruby_api_version[0] != RUBY_API_VERSION_MAJOR
@@ -939,14 +939,14 @@ Init_passenger_native_support() {
939
939
  #endif
940
940
 
941
941
  mPassenger = rb_define_module("PhusionPassenger");
942
-
942
+
943
943
  /*
944
944
  * Utility functions for accessing system functionality.
945
945
  */
946
946
  mNativeSupport = rb_define_module_under(mPassenger, "NativeSupport");
947
-
947
+
948
948
  S_ProcessTimes = rb_struct_define("ProcessTimes", "utime", "stime", NULL);
949
-
949
+
950
950
  rb_define_singleton_method(mNativeSupport, "disable_stdio_buffering", disable_stdio_buffering, 0);
951
951
  rb_define_singleton_method(mNativeSupport, "split_by_null_into_hash", split_by_null_into_hash, 1);
952
952
  rb_define_singleton_method(mNativeSupport, "writev", f_writev, 2);
@@ -955,7 +955,7 @@ Init_passenger_native_support() {
955
955
  rb_define_singleton_method(mNativeSupport, "process_times", process_times, 0);
956
956
  rb_define_singleton_method(mNativeSupport, "detach_process", detach_process, 1);
957
957
  rb_define_singleton_method(mNativeSupport, "freeze_process", freeze_process, 0);
958
-
958
+
959
959
  #ifdef HAVE_KQUEUE
960
960
  cFileSystemWatcher = rb_define_class_under(mNativeSupport,
961
961
  "FileSystemWatcher", rb_cObject);
@@ -966,7 +966,7 @@ Init_passenger_native_support() {
966
966
  rb_define_method(cFileSystemWatcher, "close",
967
967
  fs_watcher_close, 0);
968
968
  #endif
969
-
969
+
970
970
  /* The maximum length of a Unix socket path, including terminating null. */
971
971
  rb_define_const(mNativeSupport, "UNIX_PATH_MAX", INT2NUM(sizeof(addr.sun_path)));
972
972
  /* The maximum size of the data that may be passed to #writev. */