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.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- 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) {
|
@@ -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;
|
data/ext/common/Constants.h
CHANGED
@@ -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();
|
data/ext/common/EventedClient.h
CHANGED
@@ -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
|