/src/logging-log4cxx/src/main/include/log4cxx/helpers/threadutility.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #ifndef _LOG4CXX_THREADUTILITY_H |
19 | | #define _LOG4CXX_THREADUTILITY_H |
20 | | |
21 | | #include <thread> |
22 | | #include <functional> |
23 | | #include <memory> |
24 | | #include <chrono> |
25 | | |
26 | | #include "log4cxx/logstring.h" |
27 | | #include "singletonholder.h" |
28 | | |
29 | | namespace LOG4CXX_NS |
30 | | { |
31 | | namespace helpers |
32 | | { |
33 | | |
34 | | /** |
35 | | * A function that will be called before a thread is started. This can |
36 | | * be used to (for example) block all of the signals in the thread, so |
37 | | * that when the thread is created it will have a correct signal mask. |
38 | | */ |
39 | | typedef std::function<void()> ThreadStartPre; |
40 | | |
41 | | /** |
42 | | * Called when a new thread has started. This can be used to set |
43 | | * parameters for the thread in a platform-specific manner. |
44 | | * |
45 | | * @param threadName The name of the thread |
46 | | * @param threadId The ID of the thread as reported by std::thread::get_id |
47 | | * @param nativeHandle The native handle of the thread, as reported by |
48 | | * std::thread::native_handle |
49 | | */ |
50 | | typedef std::function<void( LogString threadName, |
51 | | std::thread::id threadId, |
52 | | std::thread::native_handle_type nativeHandle )> ThreadStarted; |
53 | | |
54 | | /** |
55 | | * Called after a thread has started. This can be used to (for example) |
56 | | * unblock the signals in the thread. |
57 | | */ |
58 | | typedef std::function<void()> ThreadStartPost; |
59 | | |
60 | | enum class ThreadConfigurationType |
61 | | { |
62 | | NoConfiguration, |
63 | | BlockSignalsOnly, |
64 | | NameThreadOnly, |
65 | | BlockSignalsAndNameThread, |
66 | | }; |
67 | | |
68 | | class LOG4CXX_EXPORT ThreadUtility |
69 | | { |
70 | | private: |
71 | | friend class SingletonHolder<ThreadUtility>; |
72 | | ThreadUtility(); |
73 | | |
74 | | LOG4CXX_NS::helpers::ThreadStartPre preStartFunction(); |
75 | | LOG4CXX_NS::helpers::ThreadStarted threadStartedFunction(); |
76 | | LOG4CXX_NS::helpers::ThreadStartPost postStartFunction(); |
77 | | |
78 | | LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(priv_data, m_priv) |
79 | | public: |
80 | | ~ThreadUtility(); |
81 | | |
82 | | static ThreadUtility* instance(); |
83 | | |
84 | | /** |
85 | | * Utility method for configuring the ThreadUtility in a standard |
86 | | * configuration. |
87 | | */ |
88 | | static void configure( ThreadConfigurationType type ); |
89 | | |
90 | | /** |
91 | | * Configure the thread functions that log4cxx will use. |
92 | | * Note that setting any of these parameters to nullptr is valid, |
93 | | * and simply results in the callback not being called. |
94 | | */ |
95 | | void configureFuncs( ThreadStartPre pre_start, |
96 | | ThreadStarted started, |
97 | | ThreadStartPost post_start ); |
98 | | |
99 | | /** |
100 | | * A pre-start thread function that blocks signals to the new thread |
101 | | * (if the system has pthreads). If the system does not have pthreads, |
102 | | * does nothing. |
103 | | */ |
104 | | void preThreadBlockSignals(); |
105 | | |
106 | | /** |
107 | | * A thread_started function that names the thread using the appropriate |
108 | | * system call. |
109 | | */ |
110 | | void threadStartedNameThread(LogString threadName, |
111 | | std::thread::id thread_id, |
112 | | std::thread::native_handle_type native_handle); |
113 | | |
114 | | /** |
115 | | * A post-start thread function that unblocks signals that preThreadBlockSignals |
116 | | * blocked before starting the thread. If the system does not have pthreads, |
117 | | * does nothing. |
118 | | */ |
119 | | void postThreadUnblockSignals(); |
120 | | |
121 | | /** |
122 | | * Start a thread |
123 | | */ |
124 | | template<class Function, class... Args> |
125 | | std::thread createThread(LogString name, |
126 | | Function&& f, |
127 | | Args&& ... args) |
128 | 0 | { |
129 | 0 | LOG4CXX_NS::helpers::ThreadStartPre pre_start = preStartFunction(); |
130 | 0 | LOG4CXX_NS::helpers::ThreadStarted thread_start = threadStartedFunction(); |
131 | 0 | LOG4CXX_NS::helpers::ThreadStartPost post_start = postStartFunction(); |
132 | |
|
133 | 0 | if ( pre_start ) |
134 | 0 | { |
135 | 0 | pre_start(); |
136 | 0 | } |
137 | |
|
138 | 0 | std::thread t( f, args... ); |
139 | |
|
140 | 0 | if ( thread_start ) |
141 | 0 | { |
142 | 0 | thread_start( name, |
143 | 0 | t.get_id(), |
144 | 0 | t.native_handle() ); |
145 | 0 | } |
146 | |
|
147 | 0 | if ( post_start ) |
148 | 0 | { |
149 | 0 | post_start(); |
150 | 0 | } |
151 | |
|
152 | 0 | return t; |
153 | 0 | } Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<std::__1::__bind<void (log4cxx::helpers::ThreadUtility::priv_data::*)(), log4cxx::helpers::ThreadUtility::priv_data*>>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__bind<void (log4cxx::helpers::ThreadUtility::priv_data::*)(), log4cxx::helpers::ThreadUtility::priv_data*>&&) Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<void (log4cxx::net::TelnetAppender::*)(), log4cxx::net::TelnetAppender*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void (log4cxx::net::TelnetAppender::*&&)(), log4cxx::net::TelnetAppender*&&) Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<void (log4cxx::AsyncAppender::*)(), log4cxx::AsyncAppender*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void (log4cxx::AsyncAppender::*&&)(), log4cxx::AsyncAppender*&&) Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<std::__1::__bind<void (log4cxx::helpers::ThreadUtility::priv_data::*)(), log4cxx::helpers::ThreadUtility::priv_data*>>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::__bind<void (log4cxx::helpers::ThreadUtility::priv_data::*)(), log4cxx::helpers::ThreadUtility::priv_data*>&&) Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<void (log4cxx::net::TelnetAppender::*)(), log4cxx::net::TelnetAppender*>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, void (log4cxx::net::TelnetAppender::*&&)(), log4cxx::net::TelnetAppender*&&) Unexecuted instantiation: std::__1::thread log4cxx::helpers::ThreadUtility::createThread<void (log4cxx::AsyncAppender::*)(), log4cxx::AsyncAppender*>(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, void (log4cxx::AsyncAppender::*&&)(), log4cxx::AsyncAppender*&&) |
154 | | |
155 | | using Period = std::chrono::milliseconds; |
156 | | |
157 | | /** |
158 | | * Add the \c taskName periodic task |
159 | | */ |
160 | | void addPeriodicTask(const LogString& taskName, std::function<void()> f, const Period& delay); |
161 | | |
162 | | /** |
163 | | * Has a \c taskName periodic task already been added? |
164 | | */ |
165 | | bool hasPeriodicTask(const LogString& taskName); |
166 | | |
167 | | /** |
168 | | * Remove all periodic tasks and stop the processing thread |
169 | | */ |
170 | | void removeAllPeriodicTasks(); |
171 | | |
172 | | /** |
173 | | * Remove the \c taskName periodic task |
174 | | */ |
175 | | void removePeriodicTask(const LogString& taskName); |
176 | | |
177 | | /** |
178 | | * Remove any periodic task matching \c namePrefix |
179 | | */ |
180 | | void removePeriodicTasksMatching(const LogString& namePrefix); |
181 | | |
182 | | using Manager = SingletonHolder<ThreadUtility>; |
183 | | LOG4CXX_PTR_DEF(Manager); |
184 | | |
185 | | static ManagerPtr instancePtr(); |
186 | | }; |
187 | | |
188 | | } /* namespace helpers */ |
189 | | } /* namespace log4cxx */ |
190 | | |
191 | | #endif |