@@ -23,29 +23,15 @@ using namespace LOG4CXX_NS::helpers;
2323
2424IMPLEMENT_LOG4CXX_OBJECT (AppenderAttachableImpl)
2525
26+ #ifndef __cpp_lib_atomic_shared_ptr
27+
2628struct AppenderAttachableImpl ::priv_data
2729{
2830 /* * Array of appenders. */
2931 AppenderList appenderList;
3032 mutable std::mutex m_mutex;
3133};
3234
33- AppenderAttachableImpl::AppenderAttachableImpl ()
34- {
35- }
36-
37- #if LOG4CXX_ABI_VERSION <= 15
38- AppenderAttachableImpl::AppenderAttachableImpl (Pool& pool)
39- : m_priv()
40- {
41- }
42- #endif
43-
44- AppenderAttachableImpl::~AppenderAttachableImpl ()
45- {
46-
47- }
48-
4935void AppenderAttachableImpl::addAppender (const AppenderPtr newAppender)
5036{
5137 // Null values for newAppender parameter are strictly forbidden.
@@ -199,4 +185,192 @@ void AppenderAttachableImpl::replaceAppenders(const AppenderList& newList)
199185 m_priv->appenderList = newList;
200186}
201187
188+ #else // __cpp_lib_atomic_shared_ptr
189+
190+ using AppenderListPtr = std::shared_ptr<const AppenderList>;
191+
192+ /* * A vector of appender pointers. */
193+ struct AppenderAttachableImpl ::priv_data
194+ {
195+ std::atomic<AppenderListPtr> pAppenderList;
196+
197+ priv_data (const AppenderList& newList = {})
198+ : pAppenderList{ std::make_shared<AppenderList>(newList) }
199+ {}
200+
201+ AppenderListPtr getAppenders () const
202+ {
203+ return pAppenderList.load (std::memory_order_acquire);
204+ }
205+
206+ void setAppenders (const AppenderListPtr& newList)
207+ {
208+ pAppenderList.store (newList, std::memory_order_release);
209+ }
210+ };
211+
212+ void AppenderAttachableImpl::addAppender (const AppenderPtr newAppender)
213+ {
214+ if (!newAppender)
215+ return ;
216+ if (m_priv)
217+ {
218+ auto allAppenders = m_priv->getAppenders ();
219+ if (allAppenders->end () == std::find (allAppenders->begin (), allAppenders->end (), newAppender))
220+ {
221+ auto newAppenders = std::make_shared<AppenderList>(*allAppenders);
222+ newAppenders->push_back (newAppender);
223+ m_priv->setAppenders (newAppenders);
224+ }
225+ }
226+ else
227+ m_priv = std::make_unique<AppenderAttachableImpl::priv_data>(AppenderList{newAppender});
228+ }
229+
230+ int AppenderAttachableImpl::appendLoopOnAppenders (const spi::LoggingEventPtr& event, Pool& p)
231+ {
232+ int result = 0 ;
233+ if (m_priv)
234+ {
235+ auto allAppenders = m_priv->getAppenders ();
236+ for (auto & appender : *allAppenders)
237+ {
238+ appender->doAppend (event, p);
239+ ++result;
240+ }
241+ }
242+ return result;
243+ }
244+
245+ AppenderList AppenderAttachableImpl::getAllAppenders () const
246+ {
247+ AppenderList result;
248+ if (m_priv)
249+ result = *m_priv->getAppenders ();
250+ return result;
251+ }
252+
253+ AppenderPtr AppenderAttachableImpl::getAppender (const LogString& name) const
254+ {
255+ AppenderPtr result;
256+ if (m_priv)
257+ {
258+ auto allAppenders = m_priv->getAppenders ();
259+ for (auto & appender : *allAppenders)
260+ {
261+ if (name == appender->getName ())
262+ {
263+ result = appender;
264+ break ;
265+ }
266+ }
267+ }
268+ return result;
269+ }
270+
271+ bool AppenderAttachableImpl::isAttached (const AppenderPtr appender) const
272+ {
273+ bool result = false ;
274+ if (m_priv && appender)
275+ {
276+ auto allAppenders = m_priv->getAppenders ();
277+ result = allAppenders->end () != std::find (allAppenders->begin (), allAppenders->end (), appender);
278+ }
279+ return result;
280+ }
281+
282+ void AppenderAttachableImpl::removeAllAppenders ()
283+ {
284+ if (m_priv)
285+ {
286+ auto allAppenders = m_priv->getAppenders ();
287+ for (auto & appender : *allAppenders)
288+ appender->close ();
289+ m_priv->setAppenders (std::make_shared<AppenderList>());
290+ }
291+ }
292+
293+ void AppenderAttachableImpl::removeAppender (const AppenderPtr appender)
294+ {
295+ if (m_priv && appender)
296+ {
297+ auto newAppenders = *m_priv->getAppenders ();
298+ auto pItem = std::find (newAppenders.begin (), newAppenders.end (), appender);
299+ if (newAppenders.end () != pItem)
300+ {
301+ newAppenders.erase (pItem);
302+ m_priv->setAppenders (std::make_shared<AppenderList>(newAppenders));
303+ }
304+ }
305+ }
306+
307+ void AppenderAttachableImpl::removeAppender (const LogString& name)
308+ {
309+ if (m_priv)
310+ {
311+ auto newAppenders = *m_priv->getAppenders ();
312+ auto pItem = std::find_if (newAppenders.begin (), newAppenders.end ()
313+ , [&name](const AppenderPtr& appender) -> bool
314+ {
315+ return name == appender->getName ();
316+ });
317+ if (newAppenders.end () != pItem)
318+ {
319+ newAppenders.erase (pItem);
320+ m_priv->setAppenders (std::make_shared<AppenderList>(newAppenders));
321+ }
322+ }
323+ }
324+
325+ bool AppenderAttachableImpl::replaceAppender (const AppenderPtr& oldAppender, const AppenderPtr& newAppender)
326+ {
327+ bool found = false ;
328+ if (m_priv && oldAppender && newAppender)
329+ {
330+ auto name = oldAppender->getName ();
331+ auto newAppenders = *m_priv->getAppenders ();
332+ auto pItem = std::find_if (newAppenders.begin (), newAppenders.end ()
333+ , [&name](const AppenderPtr& appender) -> bool
334+ {
335+ return name == appender->getName ();
336+ });
337+ if (newAppenders.end () != pItem)
338+ {
339+ *pItem = newAppender;
340+ m_priv->setAppenders (std::make_shared<AppenderList>(newAppenders));
341+ found = true ;
342+ }
343+ }
344+ return found;
345+ }
346+
347+ void AppenderAttachableImpl::replaceAppenders (const AppenderList& newList)
348+ {
349+ if (m_priv)
350+ {
351+ auto allAppenders = m_priv->getAppenders ();
352+ for (auto & a : *allAppenders)
353+ a->close ();
354+ m_priv->setAppenders (std::make_shared<AppenderList>(newList));
355+ }
356+ else
357+ m_priv = std::make_unique<AppenderAttachableImpl::priv_data>(newList);
358+ }
359+
360+ #endif // __cpp_lib_atomic_shared_ptr
361+
362+ AppenderAttachableImpl::AppenderAttachableImpl ()
363+ {
364+ }
365+
366+ AppenderAttachableImpl::~AppenderAttachableImpl ()
367+ {
368+ }
369+
370+ #if LOG4CXX_ABI_VERSION <= 15
371+ AppenderAttachableImpl::AppenderAttachableImpl (Pool& pool)
372+ {
373+ }
374+ #endif
375+
202376
0 commit comments