| 1071 | } |
| 1072 | |
| 1073 | void startThreadFromGlobalPool( |
| 1074 | std::shared_ptr<ThreadFromGlobalPoolState> state, |
| 1075 | std::function<void()> func, |
| 1076 | UInt64 global_profiler_real_time_period_ns, |
| 1077 | UInt64 global_profiler_cpu_time_period_ns, |
| 1078 | bool global_trace_collector_allowed, |
| 1079 | bool propagate_opentelemetry_context) |
| 1080 | { |
| 1081 | /// NOTE: |
| 1082 | /// - If scheduleOrThrow throws, the ThreadFromGlobalPoolImpl destructor won't be called. |
| 1083 | /// - `this` cannot be passed in the lambda since after detach() it is no longer valid. |
| 1084 | GlobalThreadPool::instance().scheduleOrThrow( |
| 1085 | [my_state = std::move(state), |
| 1086 | my_func = std::move(func), |
| 1087 | global_profiler_real_time_period_ns, |
| 1088 | global_profiler_cpu_time_period_ns, |
| 1089 | global_trace_collector_allowed]() mutable |
| 1090 | { |
| 1091 | SCOPE_EXIT( |
| 1092 | my_state->thread_id = std::thread::id(); |
| 1093 | my_state->event.set(); |
| 1094 | ); |
| 1095 | |
| 1096 | my_state->thread_id = std::this_thread::get_id(); |
| 1097 | |
| 1098 | /// Move out so captured callable is destroyed before join() is signalled. |
| 1099 | auto function = std::move(my_func); |
| 1100 | |
| 1101 | /// ThreadStatus holds a raw pointer to the query context, so it must be |
| 1102 | /// destroyed before the signal that allows join() to return. |
| 1103 | DB::ThreadStatus thread_status; |
| 1104 | if (global_trace_collector_allowed |
| 1105 | && unlikely(global_profiler_real_time_period_ns != 0 || global_profiler_cpu_time_period_ns != 0)) |
| 1106 | thread_status.initGlobalProfiler(global_profiler_real_time_period_ns, global_profiler_cpu_time_period_ns); |
| 1107 | |
| 1108 | function(); |
| 1109 | }, |
| 1110 | {}, |
| 1111 | 0, |
| 1112 | propagate_opentelemetry_context); |
| 1113 | } |
| 1114 | |
| 1115 | CannotAllocateThreadFaultInjector & CannotAllocateThreadFaultInjector::instance() |
| 1116 | { |
no test coverage detected