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
@@ -48,7 +48,7 @@ struct trace_point {
|
|
48
48
|
const char *data;
|
49
49
|
unsigned short line;
|
50
50
|
bool m_detached;
|
51
|
-
|
51
|
+
|
52
52
|
trace_point(const char *function, const char *source, unsigned short line,
|
53
53
|
const char *data = 0);
|
54
54
|
trace_point(const char *function, const char *source, unsigned short line,
|
data/ext/oxt/detail/context.hpp
CHANGED
@@ -42,12 +42,12 @@ public:
|
|
42
42
|
class scoped_lock: boost::noncopyable {
|
43
43
|
private:
|
44
44
|
spin_lock &l;
|
45
|
-
|
45
|
+
|
46
46
|
public:
|
47
47
|
scoped_lock(spin_lock &lock): l(lock) {
|
48
48
|
l.lock();
|
49
49
|
}
|
50
|
-
|
50
|
+
|
51
51
|
~scoped_lock() {
|
52
52
|
l.unlock();
|
53
53
|
}
|
@@ -56,11 +56,11 @@ public:
|
|
56
56
|
spin_lock() {
|
57
57
|
spin = 0;
|
58
58
|
}
|
59
|
-
|
59
|
+
|
60
60
|
void lock() {
|
61
61
|
OSSpinLockLock(&spin);
|
62
62
|
}
|
63
|
-
|
63
|
+
|
64
64
|
void unlock() {
|
65
65
|
OSSpinLockUnlock(&spin);
|
66
66
|
}
|
@@ -44,19 +44,19 @@ public:
|
|
44
44
|
class scoped_lock: boost::noncopyable {
|
45
45
|
private:
|
46
46
|
spin_lock &l;
|
47
|
-
|
47
|
+
|
48
48
|
public:
|
49
49
|
scoped_lock(spin_lock &lock): l(lock) {
|
50
50
|
l.lock();
|
51
51
|
}
|
52
|
-
|
52
|
+
|
53
53
|
~scoped_lock() {
|
54
54
|
l.unlock();
|
55
55
|
}
|
56
56
|
};
|
57
57
|
|
58
58
|
spin_lock(): exclusion(0) { }
|
59
|
-
|
59
|
+
|
60
60
|
/**
|
61
61
|
* Lock this spin lock.
|
62
62
|
* @throws boost::thread_resource_error Something went wrong.
|
@@ -44,12 +44,12 @@ public:
|
|
44
44
|
class scoped_lock: boost::noncopyable {
|
45
45
|
private:
|
46
46
|
spin_lock &l;
|
47
|
-
|
47
|
+
|
48
48
|
public:
|
49
49
|
scoped_lock(spin_lock &lock): l(lock) {
|
50
50
|
l.lock();
|
51
51
|
}
|
52
|
-
|
52
|
+
|
53
53
|
~scoped_lock() {
|
54
54
|
l.unlock();
|
55
55
|
}
|
@@ -64,14 +64,14 @@ public:
|
|
64
64
|
throw boost::thread_resource_error(ret, "Cannot initialize a spin lock");
|
65
65
|
}
|
66
66
|
}
|
67
|
-
|
67
|
+
|
68
68
|
~spin_lock() {
|
69
69
|
int ret;
|
70
70
|
do {
|
71
71
|
ret = pthread_spin_destroy(&spin);
|
72
72
|
} while (ret == EINTR);
|
73
73
|
}
|
74
|
-
|
74
|
+
|
75
75
|
void lock() {
|
76
76
|
int ret;
|
77
77
|
do {
|
@@ -56,7 +56,7 @@ class dynamic_thread_group {
|
|
56
56
|
private:
|
57
57
|
struct thread_handle;
|
58
58
|
typedef boost::shared_ptr<thread_handle> thread_handle_ptr;
|
59
|
-
|
59
|
+
|
60
60
|
/** A container which aggregates a thread object
|
61
61
|
* as well as the its own iterator in the 'thread_handles'
|
62
62
|
* member. The latter is used for removing itself from
|
@@ -66,33 +66,33 @@ private:
|
|
66
66
|
list<thread_handle_ptr>::iterator iterator;
|
67
67
|
thread *thr;
|
68
68
|
bool removed_from_list;
|
69
|
-
|
69
|
+
|
70
70
|
thread_handle() {
|
71
71
|
thr = NULL;
|
72
72
|
removed_from_list = false;
|
73
73
|
}
|
74
|
-
|
74
|
+
|
75
75
|
~thread_handle() {
|
76
76
|
delete thr;
|
77
77
|
}
|
78
78
|
};
|
79
|
-
|
79
|
+
|
80
80
|
/** A mutex which protects thread_handles and nthreads. */
|
81
81
|
mutable boost::mutex lock;
|
82
82
|
/** The internal list of threads. */
|
83
83
|
list<thread_handle_ptr> thread_handles;
|
84
84
|
/** The number of threads in this thread group. */
|
85
85
|
unsigned int nthreads;
|
86
|
-
|
86
|
+
|
87
87
|
struct thread_cleanup {
|
88
88
|
dynamic_thread_group *thread_group;
|
89
89
|
thread_handle *handle;
|
90
|
-
|
90
|
+
|
91
91
|
thread_cleanup(dynamic_thread_group *g, thread_handle *h) {
|
92
92
|
thread_group = g;
|
93
93
|
handle = h;
|
94
94
|
}
|
95
|
-
|
95
|
+
|
96
96
|
~thread_cleanup() {
|
97
97
|
this_thread::disable_interruption di;
|
98
98
|
this_thread::disable_syscall_interruption dsi;
|
@@ -103,21 +103,21 @@ private:
|
|
103
103
|
}
|
104
104
|
}
|
105
105
|
};
|
106
|
-
|
106
|
+
|
107
107
|
void thread_main(boost::function<void ()> &func, thread_handle *handle) {
|
108
108
|
thread_cleanup c(this, handle);
|
109
109
|
func();
|
110
110
|
}
|
111
|
-
|
111
|
+
|
112
112
|
public:
|
113
113
|
dynamic_thread_group() {
|
114
114
|
nthreads = 0;
|
115
115
|
}
|
116
|
-
|
116
|
+
|
117
117
|
~dynamic_thread_group() {
|
118
118
|
interrupt_and_join_all();
|
119
119
|
}
|
120
|
-
|
120
|
+
|
121
121
|
/**
|
122
122
|
* Create a new thread that belongs to this thread group.
|
123
123
|
*
|
@@ -155,7 +155,7 @@ public:
|
|
155
155
|
(*it)->thr->interrupt();
|
156
156
|
}
|
157
157
|
}
|
158
|
-
|
158
|
+
|
159
159
|
/**
|
160
160
|
* Interrupt and join all threads in this group.
|
161
161
|
*
|
@@ -175,7 +175,7 @@ public:
|
|
175
175
|
unsigned int nthreads_copy = nthreads;
|
176
176
|
vector<thread *> threads;
|
177
177
|
unsigned int i = 0;
|
178
|
-
|
178
|
+
|
179
179
|
// We make a copy so that the handles aren't destroyed prematurely.
|
180
180
|
threads.reserve(nthreads);
|
181
181
|
thread_handles_copy = thread_handles;
|
@@ -186,11 +186,11 @@ public:
|
|
186
186
|
}
|
187
187
|
thread_handles.clear();
|
188
188
|
nthreads = 0;
|
189
|
-
|
189
|
+
|
190
190
|
l.unlock();
|
191
191
|
thread::interrupt_and_join_multiple(&threads[0], nthreads_copy, interruptSyscalls);
|
192
192
|
}
|
193
|
-
|
193
|
+
|
194
194
|
void join_all() {
|
195
195
|
// See comments from interrupt_and_join_all().
|
196
196
|
boost::unique_lock<boost::mutex> l(lock);
|
@@ -200,7 +200,7 @@ public:
|
|
200
200
|
unsigned int nthreads_copy = nthreads;
|
201
201
|
vector<thread *> threads;
|
202
202
|
unsigned int i = 0;
|
203
|
-
|
203
|
+
|
204
204
|
// We make a copy so that the handles aren't destroyed prematurely.
|
205
205
|
threads.reserve(nthreads);
|
206
206
|
thread_handles_copy = thread_handles;
|
@@ -211,13 +211,13 @@ public:
|
|
211
211
|
}
|
212
212
|
thread_handles.clear();
|
213
213
|
nthreads = 0;
|
214
|
-
|
214
|
+
|
215
215
|
l.unlock();
|
216
216
|
for (i = 0; i < nthreads_copy; i++) {
|
217
217
|
threads[i]->join();
|
218
218
|
}
|
219
219
|
}
|
220
|
-
|
220
|
+
|
221
221
|
/**
|
222
222
|
* Returns the number of threads currently in this thread group.
|
223
223
|
*/
|
data/ext/oxt/implementation.cpp
CHANGED
@@ -58,12 +58,13 @@ static global_context_t *global_context = NULL;
|
|
58
58
|
*/
|
59
59
|
#ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
|
60
60
|
static __thread thread_local_context_ptr *local_context = NULL;
|
61
|
+
__thread void *thread_signature = NULL;
|
61
62
|
|
62
63
|
static void
|
63
64
|
init_thread_local_context_support() {
|
64
65
|
/* Do nothing. */
|
65
66
|
}
|
66
|
-
|
67
|
+
|
67
68
|
void
|
68
69
|
set_thread_local_context(const thread_local_context_ptr &ctx) {
|
69
70
|
local_context = new thread_local_context_ptr(ctx);
|
@@ -93,7 +94,7 @@ static global_context_t *global_context = NULL;
|
|
93
94
|
* this object alive until the OS cleans it up.
|
94
95
|
*/
|
95
96
|
static thread_specific_ptr<thread_local_context_ptr> *local_context = NULL;
|
96
|
-
|
97
|
+
|
97
98
|
static void
|
98
99
|
init_thread_local_context_support() {
|
99
100
|
local_context = new thread_specific_ptr<thread_local_context_ptr>();
|
@@ -180,7 +181,7 @@ tracable_exception::tracable_exception() {
|
|
180
181
|
if (OXT_LIKELY(ctx != NULL)) {
|
181
182
|
spin_lock::scoped_lock l(ctx->backtrace_lock);
|
182
183
|
vector<trace_point *>::const_iterator it, end = ctx->backtrace_list.end();
|
183
|
-
|
184
|
+
|
184
185
|
backtrace_copy.reserve(ctx->backtrace_list.size());
|
185
186
|
for (it = ctx->backtrace_list.begin(); it != end; it++) {
|
186
187
|
trace_point *p = new trace_point(
|
@@ -232,10 +233,10 @@ format_backtrace(const Collection &backtrace_list) {
|
|
232
233
|
backtrace_list.rbegin();
|
233
234
|
stringstream result;
|
234
235
|
typename Collection::const_reverse_iterator it;
|
235
|
-
|
236
|
+
|
236
237
|
for (it = backtrace_list.rbegin(); it != backtrace_list.rend(); it++) {
|
237
238
|
const trace_point *p = *it;
|
238
|
-
|
239
|
+
|
239
240
|
result << " in '" << p->function << "'";
|
240
241
|
if (p->source != NULL) {
|
241
242
|
const char *source = strrchr(p->source, '/');
|
@@ -387,7 +388,7 @@ thread::all_backtraces() throw() {
|
|
387
388
|
boost::lock_guard<boost::mutex> l(global_context->thread_registration_mutex);
|
388
389
|
list<thread_local_context_ptr>::const_iterator it;
|
389
390
|
std::stringstream result;
|
390
|
-
|
391
|
+
|
391
392
|
for (it = global_context->registered_threads.begin();
|
392
393
|
it != global_context->registered_threads.end();
|
393
394
|
it++)
|
@@ -399,7 +400,7 @@ thread::all_backtraces() throw() {
|
|
399
400
|
result << ", LWP " << ctx->tid;
|
400
401
|
#endif
|
401
402
|
result << "):" << endl;
|
402
|
-
|
403
|
+
|
403
404
|
spin_lock::scoped_lock l(ctx->backtrace_lock);
|
404
405
|
std::string bt = format_backtrace(ctx->backtrace_list);
|
405
406
|
result << bt;
|
@@ -420,7 +421,7 @@ thread::all_backtraces() throw() {
|
|
420
421
|
void
|
421
422
|
thread::interrupt(bool interruptSyscalls) {
|
422
423
|
int ret;
|
423
|
-
|
424
|
+
|
424
425
|
boost::thread::interrupt();
|
425
426
|
if (interruptSyscalls && context->syscall_interruption_lock.try_lock()) {
|
426
427
|
do {
|
data/ext/oxt/macros.hpp
CHANGED
@@ -42,7 +42,7 @@
|
|
42
42
|
* This allows the CPU to better perform branch prediction.
|
43
43
|
*/
|
44
44
|
#define OXT_LIKELY(expr) __builtin_expect((expr), 1)
|
45
|
-
|
45
|
+
|
46
46
|
/**
|
47
47
|
* Indicate that the given expression is likely to be false.
|
48
48
|
* This allows the CPU to better perform branch prediction.
|
@@ -92,7 +92,7 @@
|
|
92
92
|
* GCC on OpenBSD supports __thread, but any access to such a variable
|
93
93
|
* results in a segfault.
|
94
94
|
*
|
95
|
-
* Solaris does support __thread, but often it's not compiled into default GCC
|
95
|
+
* Solaris does support __thread, but often it's not compiled into default GCC
|
96
96
|
* packages (not to mention it's not available for Sparc). Playing it safe...
|
97
97
|
*
|
98
98
|
* On MacOS X, neither gcc nor llvm-gcc support the __thread keyword, but Clang
|
data/ext/oxt/system_calls.cpp
CHANGED
@@ -48,7 +48,7 @@ oxt::setup_syscall_interruption_support() {
|
|
48
48
|
struct sigaction action;
|
49
49
|
sigset_t signal_set;
|
50
50
|
int ret;
|
51
|
-
|
51
|
+
|
52
52
|
/* Very important! The signal mask is inherited across fork()
|
53
53
|
* and exec() and we don't know what the parent process did to
|
54
54
|
* us. At least on OS X, having a signal mask blocking important
|
@@ -58,7 +58,7 @@ oxt::setup_syscall_interruption_support() {
|
|
58
58
|
do {
|
59
59
|
ret = sigprocmask(SIG_SETMASK, &signal_set, NULL);
|
60
60
|
} while (ret == -1 && errno == EINTR);
|
61
|
-
|
61
|
+
|
62
62
|
action.sa_handler = interruption_signal_handler;
|
63
63
|
action.sa_flags = 0;
|
64
64
|
sigemptyset(&action.sa_mask);
|
@@ -86,7 +86,7 @@ oxt::setup_random_failure_simulation(const ErrorChance *_errorChances, unsigned
|
|
86
86
|
|
87
87
|
static bool
|
88
88
|
shouldSimulateFailure() {
|
89
|
-
if (nErrorChances > 0) {
|
89
|
+
if (OXT_UNLIKELY(nErrorChances > 0)) {
|
90
90
|
double number = random() / (double) RAND_MAX;
|
91
91
|
const ErrorChance *candidates[OXT_MAX_ERROR_CHANCES];
|
92
92
|
unsigned int i, n = 0;
|
@@ -117,12 +117,12 @@ shouldSimulateFailure() {
|
|
117
117
|
|
118
118
|
#define CHECK_INTERRUPTION(error_expression, allowSimulatingFailure, error_assignment, code) \
|
119
119
|
do { \
|
120
|
-
if (allowSimulatingFailure && shouldSimulateFailure()) { \
|
120
|
+
if (OXT_UNLIKELY(allowSimulatingFailure && shouldSimulateFailure())) { \
|
121
121
|
error_assignment; \
|
122
122
|
break; \
|
123
123
|
} \
|
124
124
|
thread_local_context *ctx = get_thread_local_context(); \
|
125
|
-
if (
|
125
|
+
if (OXT_LIKELY(ctx != NULL)) { \
|
126
126
|
ctx->syscall_interruption_lock.unlock(); \
|
127
127
|
} \
|
128
128
|
int _my_errno; \
|
@@ -135,7 +135,7 @@ shouldSimulateFailure() {
|
|
135
135
|
&& (!this_thread::syscalls_interruptable() \
|
136
136
|
|| !(_intr_requested = this_thread::interruption_requested())) \
|
137
137
|
); \
|
138
|
-
if (
|
138
|
+
if (OXT_LIKELY(ctx != NULL)) { \
|
139
139
|
ctx->syscall_interruption_lock.lock(); \
|
140
140
|
} \
|
141
141
|
if ((error_expression) \
|
@@ -239,7 +239,7 @@ syscalls::close(int fd) {
|
|
239
239
|
if (shouldSimulateFailure()) {
|
240
240
|
return -1;
|
241
241
|
}
|
242
|
-
|
242
|
+
|
243
243
|
thread_local_context *ctx = get_thread_local_context();
|
244
244
|
if (OXT_UNLIKELY(ctx != NULL)) {
|
245
245
|
ctx->syscall_interruption_lock.unlock();
|
@@ -579,7 +579,7 @@ syscalls::sleep(unsigned int seconds) {
|
|
579
579
|
// enough resolution so it won't trigger the problem.
|
580
580
|
struct timespec spec, rem;
|
581
581
|
int ret;
|
582
|
-
|
582
|
+
|
583
583
|
spec.tv_sec = seconds;
|
584
584
|
spec.tv_nsec = 0;
|
585
585
|
ret = syscalls::nanosleep(&spec, &rem);
|
@@ -619,7 +619,7 @@ syscalls::nanosleep(const struct timespec *req, struct timespec *rem) {
|
|
619
619
|
if (OXT_UNLIKELY(ctx != NULL)) {
|
620
620
|
ctx->syscall_interruption_lock.unlock();
|
621
621
|
}
|
622
|
-
|
622
|
+
|
623
623
|
do {
|
624
624
|
ret = ::nanosleep(&req2, &rem2);
|
625
625
|
e = errno;
|
@@ -641,11 +641,11 @@ syscalls::nanosleep(const struct timespec *req, struct timespec *rem) {
|
|
641
641
|
&& (!this_thread::syscalls_interruptable()
|
642
642
|
|| !(intr_requested = this_thread::interruption_requested()))
|
643
643
|
);
|
644
|
-
|
644
|
+
|
645
645
|
if (OXT_UNLIKELY(ctx != NULL)) {
|
646
646
|
ctx->syscall_interruption_lock.lock();
|
647
647
|
}
|
648
|
-
|
648
|
+
|
649
649
|
if (ret == -1
|
650
650
|
&& e == EINTR
|
651
651
|
&& this_thread::syscalls_interruptable()
|
data/ext/oxt/system_calls.hpp
CHANGED
@@ -115,7 +115,7 @@
|
|
115
115
|
namespace oxt {
|
116
116
|
static const int INTERRUPTION_SIGNAL = SIGUSR1; // SIGUSR2 is reserved by Valgrind...
|
117
117
|
#define OXT_MAX_ERROR_CHANCES 16
|
118
|
-
|
118
|
+
|
119
119
|
struct ErrorChance {
|
120
120
|
double chance;
|
121
121
|
int errorCode;
|
@@ -124,7 +124,7 @@ namespace oxt {
|
|
124
124
|
void setup_syscall_interruption_support();
|
125
125
|
|
126
126
|
void setup_random_failure_simulation(const ErrorChance *errorChances, unsigned int n);
|
127
|
-
|
127
|
+
|
128
128
|
/**
|
129
129
|
* System call and C library call wrappers with interruption support.
|
130
130
|
* These functions are interruption points, i.e. they throw
|
@@ -144,7 +144,7 @@ namespace oxt {
|
|
144
144
|
int dup2(int filedes, int filedes2);
|
145
145
|
int mkdir(const char *pathname, mode_t mode);
|
146
146
|
int chown(const char *path, uid_t owner, gid_t group);
|
147
|
-
|
147
|
+
|
148
148
|
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
149
149
|
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
150
150
|
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
|
@@ -156,23 +156,23 @@ namespace oxt {
|
|
156
156
|
int setsockopt(int s, int level, int optname, const void *optval,
|
157
157
|
socklen_t optlen);
|
158
158
|
int shutdown(int s, int how);
|
159
|
-
|
159
|
+
|
160
160
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
|
161
161
|
struct timeval *timeout);
|
162
162
|
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
|
163
|
-
|
163
|
+
|
164
164
|
FILE *fopen(const char *path, const char *mode);
|
165
165
|
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
|
166
166
|
int fclose(FILE *fp);
|
167
167
|
int unlink(const char *pathname);
|
168
168
|
int stat(const char *path, struct stat *buf);
|
169
169
|
int lstat(const char *path, struct stat *buf);
|
170
|
-
|
170
|
+
|
171
171
|
time_t time(time_t *t);
|
172
172
|
unsigned int sleep(unsigned int seconds);
|
173
173
|
int usleep(useconds_t usec);
|
174
174
|
int nanosleep(const struct timespec *req, struct timespec *rem);
|
175
|
-
|
175
|
+
|
176
176
|
pid_t fork();
|
177
177
|
int kill(pid_t pid, int sig);
|
178
178
|
int killpg(pid_t pgrp, int sig);
|
@@ -198,7 +198,7 @@ namespace this_thread {
|
|
198
198
|
* the calling thread.
|
199
199
|
*/
|
200
200
|
bool syscalls_interruptable();
|
201
|
-
|
201
|
+
|
202
202
|
class restore_syscall_interruption;
|
203
203
|
|
204
204
|
/**
|
@@ -223,7 +223,7 @@ namespace this_thread {
|
|
223
223
|
}
|
224
224
|
#endif
|
225
225
|
}
|
226
|
-
|
226
|
+
|
227
227
|
~enable_syscall_interruption() {
|
228
228
|
#ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
|
229
229
|
_syscalls_interruptable = last_value;
|
@@ -232,7 +232,7 @@ namespace this_thread {
|
|
232
232
|
#endif
|
233
233
|
}
|
234
234
|
};
|
235
|
-
|
235
|
+
|
236
236
|
/**
|
237
237
|
* Create this struct on the stack to temporarily disable system
|
238
238
|
* call interruption, until the object goes out of scope.
|
@@ -258,7 +258,7 @@ namespace this_thread {
|
|
258
258
|
}
|
259
259
|
#endif
|
260
260
|
}
|
261
|
-
|
261
|
+
|
262
262
|
~disable_syscall_interruption() {
|
263
263
|
#ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
|
264
264
|
_syscalls_interruptable = last_value;
|
@@ -267,7 +267,7 @@ namespace this_thread {
|
|
267
267
|
#endif
|
268
268
|
}
|
269
269
|
};
|
270
|
-
|
270
|
+
|
271
271
|
/**
|
272
272
|
* Creating an object of this class on the stack will restore the
|
273
273
|
* system call interruption state to what it was before.
|
@@ -286,7 +286,7 @@ namespace this_thread {
|
|
286
286
|
*_syscalls_interruptable = intr.last_value;
|
287
287
|
#endif
|
288
288
|
}
|
289
|
-
|
289
|
+
|
290
290
|
~restore_syscall_interruption() {
|
291
291
|
#ifdef OXT_THREAD_LOCAL_KEYWORD_SUPPORTED
|
292
292
|
_syscalls_interruptable = last_value;
|