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
@@ -49,19 +49,19 @@ struct EventedMessageClientContext {
49
49
  MS_READING_MESSAGE,
50
50
  MS_PROCESSING_MESSAGE
51
51
  };
52
-
52
+
53
53
  State state;
54
54
  AccountPtr account;
55
-
55
+
56
56
  ev::timer authenticationTimer;
57
57
  ScalarMessage scalarReader;
58
58
  ArrayMessage arrayReader;
59
59
  string username;
60
-
60
+
61
61
  EventedMessageClientContext() {
62
62
  state = MS_READING_USERNAME;
63
63
  }
64
-
64
+
65
65
  ~EventedMessageClientContext() {
66
66
  /* Its buffer might contain password data so make sure
67
67
  * it's properly zeroed out. */
@@ -87,34 +87,34 @@ struct EventedMessageClientContext {
87
87
  class EventedMessageClient: public EventedClient {
88
88
  public:
89
89
  EventedMessageClientContext messageServer;
90
-
90
+
91
91
  EventedMessageClient(struct ev_loop *loop, const FileDescriptor &fd)
92
92
  : EventedClient(loop, fd)
93
93
  {
94
94
  messageServer.authenticationTimer.set(loop);
95
95
  }
96
-
96
+
97
97
  void writeArrayMessage(const char *name, ...) {
98
98
  va_list ap;
99
99
  SmallVector<StaticString, 10> args;
100
100
  const char *arg;
101
-
101
+
102
102
  args.push_back(name);
103
103
  va_start(ap, name);
104
104
  while ((arg = va_arg(ap, const char *)) != NULL) {
105
105
  args.push_back(arg);
106
106
  }
107
107
  va_end(ap);
108
-
108
+
109
109
  writeArrayMessage(&args[0], args.size());
110
110
  }
111
-
111
+
112
112
  void writeArrayMessage(StaticString args[], unsigned int count) {
113
113
  char headerBuf[sizeof(uint16_t)];
114
114
  unsigned int outSize = ArrayMessage::outputSize(count);
115
115
  SmallVector<StaticString, 10> out;
116
116
  out.reserve(outSize);
117
-
117
+
118
118
  ArrayMessage::generate(args, count, headerBuf, &out[0], outSize);
119
119
  write(&out[0], outSize);
120
120
  }
@@ -128,40 +128,40 @@ public:
128
128
  class EventedMessageServer: public EventedServer {
129
129
  protected:
130
130
  AccountsDatabasePtr accountsDatabase;
131
-
132
-
131
+
132
+
133
133
  /******** Overrided hooks and methods ********/
134
-
134
+
135
135
  virtual EventedClient *createClient(const FileDescriptor &fd) {
136
136
  return new EventedMessageClient(getLoop(), fd);
137
137
  }
138
-
138
+
139
139
  virtual void onNewClient(EventedClient *_client) {
140
140
  EventedMessageClient *client = (EventedMessageClient *) _client;
141
141
  EventedMessageClientContext *context = &client->messageServer;
142
-
142
+
143
143
  context->authenticationTimer.set
144
144
  <&EventedMessageServer::onAuthenticationTimeout>(client);
145
145
  context->authenticationTimer.start(10);
146
-
146
+
147
147
  context->arrayReader.reserve(5);
148
148
  context->scalarReader.setMaxSize(MESSAGE_SERVER_MAX_USERNAME_SIZE);
149
-
149
+
150
150
  client->writeArrayMessage("version", protocolVersion(), NULL);
151
151
  }
152
-
152
+
153
153
  virtual void onClientReadable(EventedClient *_client) {
154
154
  EventedMessageClient *client = (EventedMessageClient *) _client;
155
155
  this_thread::disable_syscall_interruption dsi;
156
156
  int i = 0;
157
157
  bool done = false;
158
-
158
+
159
159
  // read() from the client at most 10 times on every read readiness event
160
160
  // in order to give other events the chance to be processed.
161
161
  while (i < 10 && !done) {
162
162
  char buf[1024 * 8];
163
163
  ssize_t ret;
164
-
164
+
165
165
  ret = syscalls::read(client->fd, buf, sizeof(buf));
166
166
  if (ret == -1) {
167
167
  if (errno != EAGAIN) {
@@ -182,53 +182,53 @@ protected:
182
182
  done = done || !client->ioAllowed();
183
183
  }
184
184
  }
185
-
186
-
185
+
186
+
187
187
  /******** New EventedMessageServer overridable hooks and API methods ********/
188
-
188
+
189
189
  virtual void onClientAuthenticated(EventedMessageClient *client) {
190
190
  // Do nothing.
191
191
  }
192
-
192
+
193
193
  virtual bool onMessageReceived(EventedMessageClient *client, const vector<StaticString> &args) {
194
194
  return true;
195
195
  }
196
-
196
+
197
197
  virtual void onEndOfStream(EventedMessageClient *client) {
198
198
  // Do nothing.
199
199
  }
200
-
200
+
201
201
  virtual pair<size_t, bool> onOtherDataReceived(EventedMessageClient *client,
202
202
  const char *data, size_t size)
203
203
  {
204
204
  abort();
205
205
  }
206
-
206
+
207
207
  virtual const char *protocolVersion() const {
208
208
  return "1";
209
209
  }
210
-
210
+
211
211
  void discardReadData() {
212
212
  readDataDiscarded = true;
213
213
  }
214
214
 
215
215
  private:
216
216
  bool readDataDiscarded;
217
-
217
+
218
218
  static void onAuthenticationTimeout(ev::timer &t, int revents) {
219
219
  EventedMessageClient *client = (EventedMessageClient *) t.data;
220
220
  client->disconnect();
221
221
  }
222
-
222
+
223
223
  void onDataReceived(EventedMessageClient *client, char *data, size_t size) {
224
224
  EventedMessageClientContext *context = &client->messageServer;
225
225
  size_t consumed = 0;
226
-
226
+
227
227
  readDataDiscarded = false;
228
228
  while (consumed < size && client->ioAllowed() && !readDataDiscarded) {
229
229
  char *current = data + consumed;
230
230
  size_t rest = size - consumed;
231
-
231
+
232
232
  switch (context->state) {
233
233
  case EventedMessageClientContext::MS_READING_USERNAME:
234
234
  consumed += context->scalarReader.feed(current, rest);
@@ -244,17 +244,17 @@ private:
244
244
  context->state = EventedMessageClientContext::MS_READING_PASSWORD;
245
245
  }
246
246
  break;
247
-
247
+
248
248
  case EventedMessageClientContext::MS_READING_PASSWORD: {
249
249
  size_t locallyConsumed;
250
-
250
+
251
251
  locallyConsumed = context->scalarReader.feed(current, rest);
252
252
  consumed += locallyConsumed;
253
-
253
+
254
254
  // The buffer contains password data so make sure we zero
255
255
  // it out when we're done.
256
256
  MemZeroGuard passwordGuard(current, locallyConsumed);
257
-
257
+
258
258
  if (context->scalarReader.hasError()) {
259
259
  context->scalarReader.reset(true);
260
260
  client->writeArrayMessage(
@@ -282,7 +282,7 @@ private:
282
282
  }
283
283
  break;
284
284
  }
285
-
285
+
286
286
  case EventedMessageClientContext::MS_READING_MESSAGE:
287
287
  consumed += context->arrayReader.feed(current, rest);
288
288
  if (context->arrayReader.hasError()) {
@@ -299,7 +299,7 @@ private:
299
299
  context->arrayReader.reset();
300
300
  }
301
301
  break;
302
-
302
+
303
303
  case EventedMessageClientContext::MS_PROCESSING_MESSAGE: {
304
304
  pair<size_t, bool> ret = onOtherDataReceived(client, current, rest);
305
305
  consumed += ret.first;
@@ -308,7 +308,7 @@ private:
308
308
  }
309
309
  break;
310
310
  }
311
-
311
+
312
312
  default:
313
313
  // Never reached.
314
314
  abort();
@@ -89,35 +89,35 @@ using namespace oxt;
89
89
  class EventedServer {
90
90
  protected:
91
91
  typedef set<EventedClient *> ClientSet;
92
-
92
+
93
93
  const ClientSet &getClients() const {
94
94
  return clients;
95
95
  }
96
-
96
+
97
97
  string getClientName(const EventedClient *client) const {
98
98
  return toString(client);
99
99
  }
100
-
100
+
101
101
  void logError(const EventedClient *client, const string &message) {
102
102
  P_ERROR("Error in client " << getClientName(client) << ": " << message);
103
103
  }
104
-
104
+
105
105
  void logSystemError(const EventedClient *client, const string &message, int errorCode) {
106
106
  P_ERROR("Error in client " << getClientName(client) << ": " <<
107
107
  message << ": " << strerror(errorCode) << " (" << errorCode << ")");
108
108
  }
109
-
109
+
110
110
  void logSystemError(const string &message, int errorCode) {
111
111
  P_ERROR(message << ": " << strerror(errorCode) << " (" << errorCode << ")");
112
112
  }
113
-
113
+
114
114
  virtual EventedClient *createClient(const FileDescriptor &fd) {
115
115
  return new EventedClient(loop, fd);
116
116
  }
117
-
117
+
118
118
  virtual void onNewClient(EventedClient *client) { }
119
119
  virtual void onClientReadable(EventedClient *client) { }
120
-
120
+
121
121
  /**
122
122
  * Called when a client has been disconnected. This may either be triggered
123
123
  * immediately by disconnect() or triggered after pending data has been sent
@@ -135,54 +135,54 @@ private:
135
135
  FileDescriptor fd;
136
136
  ev::io acceptWatcher;
137
137
  ClientSet clients;
138
-
138
+
139
139
  void removeClient(EventedClient *client) {
140
140
  clients.erase(client);
141
141
  }
142
-
142
+
143
143
  void freeAllClients() {
144
144
  ClientSet::iterator it;
145
145
  ClientSet::iterator end = clients.end();
146
-
146
+
147
147
  for (it = clients.begin(); it != end; it++) {
148
148
  (*it)->unref();
149
149
  }
150
150
  clients.clear();
151
151
  }
152
-
152
+
153
153
  static void _onReadable(EventedClient *client) {
154
154
  EventedServer *server = (EventedServer *) client->userData;
155
155
  client->ref();
156
156
  ScopeGuard guard(boost::bind(&EventedClient::unref, client));
157
157
  server->onClientReadable((EventedClient *) client);
158
158
  }
159
-
159
+
160
160
  static void _onDisconnect(EventedClient *client) {
161
161
  EventedServer *server = (EventedServer *) client->userData;
162
162
  ScopeGuard guard1(boost::bind(&EventedClient::unref, client));
163
-
163
+
164
164
  client->ref();
165
165
  ScopeGuard guard2(boost::bind(&EventedClient::unref, client));
166
-
166
+
167
167
  server->removeClient(client);
168
168
  server->onClientDisconnected((EventedClient *) client);
169
169
  }
170
-
170
+
171
171
  static void _onDetach(EventedClient *client) {
172
172
  EventedServer *server = (EventedServer *) client->userData;
173
173
  ScopeGuard guard1(boost::bind(&EventedClient::unref, client));
174
-
174
+
175
175
  client->ref();
176
176
  ScopeGuard guard2(boost::bind(&EventedClient::unref, client));
177
-
177
+
178
178
  server->removeClient(client);
179
179
  }
180
-
180
+
181
181
  static void _onSystemError(EventedClient *client, const string &message, int code) {
182
182
  EventedServer *server = (EventedServer *) client->userData;
183
183
  server->logSystemError(client, message, code);
184
184
  }
185
-
185
+
186
186
  void exceptionThrownWhileInitializingClient(EventedClient *client, ClientSet::iterator it) {
187
187
  if (!client->ioAllowed()) {
188
188
  // onNewClient() disconnected or detached the
@@ -196,12 +196,12 @@ private:
196
196
  }
197
197
  // Now client refcount == 0
198
198
  }
199
-
199
+
200
200
  void onAcceptable(ev::io &w, int revents) {
201
201
  this_thread::disable_syscall_interruption dsi;
202
202
  int i = 0;
203
203
  bool done = false;
204
-
204
+
205
205
  // Accept at most 10 connections on every accept readiness event
206
206
  // in order to give other events the chance to be processed.
207
207
  while (i < 10 && !done) {
@@ -212,7 +212,7 @@ private:
212
212
  struct sockaddr_in inet;
213
213
  } addr;
214
214
  socklen_t len = sizeof(addr);
215
-
215
+
216
216
  int clientfd = syscalls::accept(fd, (struct sockaddr *) &addr, &len);
217
217
  if (clientfd == -1) {
218
218
  if (errno != EAGAIN && errno != EWOULDBLOCK) {
@@ -223,11 +223,11 @@ private:
223
223
  } else {
224
224
  FileDescriptor clientfdGuard(clientfd);
225
225
  int optval = 1;
226
-
226
+
227
227
  setNonBlocking(clientfdGuard);
228
228
  syscalls::setsockopt(clientfd, SOL_SOCKET, SO_KEEPALIVE,
229
229
  &optval, sizeof(optval));
230
-
230
+
231
231
  EventedClient *client = createClient(clientfdGuard);
232
232
  client->onReadable = _onReadable;
233
233
  client->onDisconnect = _onDisconnect;
@@ -235,9 +235,9 @@ private:
235
235
  client->onSystemError = _onSystemError;
236
236
  client->userData = this;
237
237
  client->notifyReads(true);
238
-
238
+
239
239
  pair<ClientSet::iterator, bool> p = clients.insert(client);
240
-
240
+
241
241
  client->ref();
242
242
  // client refcount == 2
243
243
  {
@@ -250,7 +250,7 @@ private:
250
250
  g.clear();
251
251
  // If exception occurred: client refcount == 0
252
252
  }
253
-
253
+
254
254
  /* No exception occured.
255
255
  * If onNewClient() disconnected or detached the client:
256
256
  * client refcount == 1
@@ -264,7 +264,7 @@ private:
264
264
  i++;
265
265
  }
266
266
  }
267
-
267
+
268
268
  public:
269
269
  EventedServer(struct ev_loop *_loop, FileDescriptor serverFd)
270
270
  : loop(_loop),
@@ -275,15 +275,15 @@ public:
275
275
  acceptWatcher.set<EventedServer, &EventedServer::onAcceptable>(this);
276
276
  acceptWatcher.start(fd, ev::READ);
277
277
  }
278
-
278
+
279
279
  virtual ~EventedServer() {
280
280
  freeAllClients();
281
281
  }
282
-
282
+
283
283
  struct ev_loop *getLoop() const {
284
284
  return loop;
285
285
  }
286
-
286
+
287
287
  FileDescriptor getServerFd() const {
288
288
  return fd;
289
289
  }
@@ -116,32 +116,32 @@ public:
116
116
  */
117
117
  SystemException(const string &briefMessage, int errorCode) {
118
118
  stringstream str;
119
-
119
+
120
120
  str << strerror(errorCode) << " (errno=" << errorCode << ")";
121
121
  systemMessage = str.str();
122
-
122
+
123
123
  setBriefMessage(briefMessage);
124
124
  m_code = errorCode;
125
125
  }
126
-
126
+
127
127
  virtual ~SystemException() throw() {}
128
-
128
+
129
129
  virtual const char *what() const throw() {
130
130
  return fullMessage.c_str();
131
131
  }
132
-
132
+
133
133
  void setBriefMessage(const string &message) {
134
134
  briefMessage = message;
135
135
  fullMessage = briefMessage + ": " + systemMessage;
136
136
  }
137
-
137
+
138
138
  /**
139
139
  * The value of <tt>errno</tt> at the time the error occured.
140
140
  */
141
141
  int code() const throw() {
142
142
  return m_code;
143
143
  }
144
-
144
+
145
145
  /**
146
146
  * Returns a brief version of the exception message. This message does
147
147
  * not include the system error description, and is equivalent to the
@@ -150,7 +150,7 @@ public:
150
150
  string brief() const throw() {
151
151
  return briefMessage;
152
152
  }
153
-
153
+
154
154
  /**
155
155
  * Returns the system's error message. This message contains both the
156
156
  * content of <tt>strerror(errno)</tt> and the errno number itself.
@@ -174,9 +174,9 @@ public:
174
174
  const string &filename)
175
175
  : SystemException(message, errorCode),
176
176
  m_filename(filename) {}
177
-
177
+
178
178
  virtual ~FileSystemException() throw() {}
179
-
179
+
180
180
  /**
181
181
  * The filename that's associated to the error.
182
182
  */
@@ -277,7 +277,7 @@ public:
277
277
  * It DID explicitly supply an error message. */
278
278
  APP_STARTUP_EXPLAINABLE_ERROR
279
279
  };
280
-
280
+
281
281
  private:
282
282
  ErrorKind errorKind;
283
283
  string msg;
@@ -286,7 +286,7 @@ private:
286
286
  string m_errorPage;
287
287
  string preloaderCommand;
288
288
  map<string, string> annotations;
289
-
289
+
290
290
  public:
291
291
  SpawnException(const string &message, ErrorKind errorKind = UNDEFINED_ERROR)
292
292
  : msg(message)
@@ -295,7 +295,7 @@ public:
295
295
  m_hasErrorPage = false;
296
296
  m_isHTML = false;
297
297
  }
298
-
298
+
299
299
  SpawnException(const string &message, const string &errorPage,
300
300
  bool isHTML = true, ErrorKind errorKind = UNDEFINED_ERROR)
301
301
  : msg(message), m_errorPage(errorPage)
@@ -304,9 +304,9 @@ public:
304
304
  m_hasErrorPage = true;
305
305
  m_isHTML = isHTML;
306
306
  }
307
-
307
+
308
308
  virtual ~SpawnException() throw() {}
309
-
309
+
310
310
  virtual const char *what() const throw() {
311
311
  return msg.c_str();
312
312
  }
@@ -314,24 +314,24 @@ public:
314
314
  bool hasErrorPage() const {
315
315
  return m_hasErrorPage;
316
316
  }
317
-
317
+
318
318
  const string &getErrorPage() const {
319
319
  return m_errorPage;
320
320
  }
321
-
321
+
322
322
  bool isHTML() const {
323
323
  return m_isHTML;
324
324
  }
325
-
325
+
326
326
  ErrorKind getErrorKind() const {
327
327
  return errorKind;
328
328
  }
329
-
329
+
330
330
  SpawnException &setPreloaderCommand(const string &filename) {
331
331
  preloaderCommand = filename;
332
332
  return *this;
333
333
  }
334
-
334
+
335
335
  const string &getPreloaderCommand() const {
336
336
  return preloaderCommand;
337
337
  }
@@ -379,13 +379,13 @@ public:
379
379
  GetAbortedException(const string &message)
380
380
  : msg(message)
381
381
  { }
382
-
382
+
383
383
  GetAbortedException(const oxt::tracable_exception::no_backtrace &tag)
384
384
  : oxt::tracable_exception(tag)
385
385
  { }
386
386
 
387
387
  virtual ~GetAbortedException() throw() {}
388
-
388
+
389
389
  virtual const char *what() const throw() {
390
390
  return msg.c_str();
391
391
  }
@@ -400,7 +400,7 @@ public:
400
400
  RequestQueueFullException()
401
401
  : GetAbortedException(oxt::tracable_exception::no_backtrace())
402
402
  { }
403
-
403
+
404
404
  virtual const char *what() const throw() {
405
405
  return "Request queue is full";
406
406
  }