10
10
11
11
using namespace Datadog ;
12
12
13
-
14
13
// Helper class for spawning a std::thread with control over its default stack size
15
14
#ifdef __linux__
16
- #include < unistd.h>
17
15
#include < sys/resource.h>
18
- template <typename Function, typename ... Args>
19
- pthread_t create_thread_with_stack (size_t stack_size, Function&& f, Args&&... args) {
16
+ #include < unistd.h>
17
+
18
+ struct ThreadArgs
19
+ {
20
+ Sampler* sampler;
21
+ uint64_t seq_num;
22
+ };
23
+
24
+ void *
25
+ call_sampling_thread (void * args)
26
+ {
27
+ ThreadArgs* thread_args = static_cast <ThreadArgs*>(args);
28
+ Sampler* sampler = thread_args->sampler ;
29
+ sampler->sampling_thread (thread_args->seq_num );
30
+ return nullptr ;
31
+ }
32
+
33
+ pthread_t
34
+ create_thread_with_stack (size_t stack_size, Sampler* sampler, uint64_t seq_num)
35
+ {
20
36
pthread_attr_t attr;
21
- pthread_attr_init (&attr);
37
+ if (pthread_attr_init (&attr) != 0 ) {
38
+ return 0 ;
39
+ }
22
40
if (stack_size > 0 ) {
23
41
pthread_attr_setstacksize (&attr, stack_size);
24
42
}
25
43
26
- // DAS: I think std::bind here is necessary?
27
- pthread_t thread;
28
- auto * thread_func = new auto (
29
- std::bind (std::forward<Function>(f), std::forward<Args>(args)...)
30
- );
31
-
32
- int ret = pthread_create (
33
- &thread,
34
- &attr,
35
- [](void * arg) -> void * {
36
- auto * func = static_cast <decltype (thread_func)>(arg);
37
- (*func)();
38
- delete func;
39
- return nullptr ;
40
- },
41
- thread_func
42
- );
44
+ pthread_t thread_id;
45
+ ThreadArgs thread_args = { sampler, seq_num };
46
+ int ret = pthread_create (&thread_id, &attr, call_sampling_thread, &thread_args);
43
47
44
48
pthread_attr_destroy (&attr);
45
49
46
50
if (ret != 0 ) {
47
- delete thread_func;
48
- throw std::runtime_error (" Failed to create thread" );
51
+ return 0 ;
49
52
}
50
- return thread ;
53
+ return thread_id ;
51
54
}
52
55
#endif
53
56
@@ -175,7 +178,7 @@ Sampler::unregister_thread(uint64_t id)
175
178
thread_info_map.erase (id);
176
179
}
177
180
178
- void
181
+ bool
179
182
Sampler::start ()
180
183
{
181
184
static std::once_flag once;
@@ -188,11 +191,18 @@ Sampler::start()
188
191
// We might as well get the default stack size and use that
189
192
rlimit stack_sz = {};
190
193
getrlimit (RLIMIT_STACK, &stack_sz);
191
- create_thread_with_stack (stack_sz.rlim_cur , &Sampler::sampling_thread, this , ++thread_seq_num); // leak the thread
194
+ if (create_thread_with_stack (stack_sz.rlim_cur , this , ++thread_seq_num) == 0 ) {
195
+ return false ;
196
+ }
192
197
#else
193
- std::thread t (&Sampler::sampling_thread, this , ++thread_seq_num);
194
- t.detach ();
198
+ try {
199
+ std::thread t (&Sampler::sampling_thread, this , ++thread_seq_num);
200
+ t.detach ();
201
+ } catch (const std::exception& e) {
202
+ return false ;
203
+ }
195
204
#endif
205
+ return true ;
196
206
}
197
207
198
208
void
0 commit comments