Coverage Report

Created: 2025-10-27 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/appenderattachableimpl.cpp
Line
Count
Source
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
#include <log4cxx/helpers/appenderattachableimpl.h>
18
#include <algorithm>
19
#include <mutex>
20
21
using namespace LOG4CXX_NS;
22
using namespace LOG4CXX_NS::helpers;
23
24
IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachableImpl)
25
26
using AppenderListPtr = std::shared_ptr<const AppenderList>;
27
28
/** A vector of appender pointers. */
29
struct AppenderAttachableImpl::priv_data
30
{
31
private: // Attributes
32
#ifdef __cpp_lib_atomic_shared_ptr
33
  std::atomic<AppenderListPtr> pAppenderList;
34
#else // !defined(__cpp_lib_atomic_shared_ptr)
35
  AppenderListPtr    pAppenderList;
36
  mutable std::mutex m_mutex;
37
#endif // !defined(__cpp_lib_atomic_shared_ptr)
38
39
public: // ...structors
40
  priv_data(const AppenderList& newList = {})
41
1
    : pAppenderList{ std::make_shared<const AppenderList>(newList) }
42
1
  {}
43
44
public: // Accessors
45
  AppenderListPtr getAppenders() const
46
5.73k
  {
47
#ifdef __cpp_lib_atomic_shared_ptr
48
    return pAppenderList.load(std::memory_order_acquire);
49
#else // !defined(__cpp_lib_atomic_shared_ptr)
50
5.73k
    std::lock_guard<std::mutex> lock( m_mutex );
51
5.73k
    return pAppenderList;
52
5.73k
#endif // !defined(__cpp_lib_atomic_shared_ptr)
53
5.73k
  }
54
55
public: // Modifiers
56
  void setAppenders(const AppenderList& newList)
57
1.14k
  {
58
#ifdef __cpp_lib_atomic_shared_ptr
59
    pAppenderList.store(std::make_shared<AppenderList>(newList), std::memory_order_release);
60
#else // !defined(__cpp_lib_atomic_shared_ptr)
61
1.14k
    std::lock_guard<std::mutex> lock( m_mutex );
62
1.14k
    pAppenderList = std::make_shared<const AppenderList>(newList);
63
1.14k
#endif // !defined(__cpp_lib_atomic_shared_ptr)
64
1.14k
  }
65
};
66
67
AppenderAttachableImpl::AppenderAttachableImpl()
68
2
{
69
2
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl()
Line
Count
Source
68
2
{
69
2
}
70
71
#if LOG4CXX_ABI_VERSION <= 15
72
AppenderAttachableImpl::AppenderAttachableImpl(Pool& pool)
73
0
{
74
0
}
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
Unexecuted instantiation: log4cxx::helpers::AppenderAttachableImpl::AppenderAttachableImpl(log4cxx::helpers::Pool&)
75
#endif
76
AppenderAttachableImpl::~AppenderAttachableImpl()
77
2
{
78
2
}
79
80
81
void AppenderAttachableImpl::addAppender(const AppenderPtr newAppender)
82
382
{
83
382
  if (!newAppender)
84
0
    return;
85
382
  if (m_priv)
86
381
  {
87
381
    auto allAppenders = m_priv->getAppenders();
88
381
    if (allAppenders->end() == std::find(allAppenders->begin(), allAppenders->end(), newAppender))
89
381
    {
90
381
      auto newAppenders = *allAppenders;
91
381
      newAppenders.push_back(newAppender);
92
381
      m_priv->setAppenders(newAppenders);
93
381
    }
94
381
  }
95
1
  else
96
1
    m_priv = std::make_unique<priv_data>(AppenderList{newAppender});
97
382
}
98
99
int AppenderAttachableImpl::appendLoopOnAppenders(const spi::LoggingEventPtr& event, Pool& p)
100
7.64k
{
101
7.64k
  int result = 0;
102
7.64k
  if (m_priv)
103
3.82k
  {
104
3.82k
    auto allAppenders = m_priv->getAppenders();
105
3.82k
    for (auto& appender : *allAppenders)
106
3.82k
    {
107
3.82k
      appender->doAppend(event, p);
108
3.82k
      ++result;
109
3.82k
    }
110
3.82k
  }
111
7.64k
  return result;
112
7.64k
}
113
114
AppenderList AppenderAttachableImpl::getAllAppenders() const
115
1.53k
{
116
1.53k
  AppenderList result;
117
1.53k
  if (m_priv)
118
765
    result = *m_priv->getAppenders();
119
1.53k
  return result;
120
1.53k
}
121
122
AppenderPtr AppenderAttachableImpl::getAppender(const LogString& name) const
123
0
{
124
0
  AppenderPtr result;
125
0
  if (m_priv)
126
0
  {
127
0
    auto allAppenders = m_priv->getAppenders();
128
0
    for (auto& appender : *allAppenders)
129
0
    {
130
0
      if (name == appender->getName())
131
0
      {
132
0
        result = appender;
133
0
        break;
134
0
      }
135
0
    }
136
0
  }
137
0
  return result;
138
0
}
139
140
bool AppenderAttachableImpl::isAttached(const AppenderPtr appender) const
141
0
{
142
0
  bool result = false;
143
0
  if (m_priv && appender)
144
0
  {
145
0
    auto allAppenders = m_priv->getAppenders();
146
0
    result = allAppenders->end() != std::find(allAppenders->begin(), allAppenders->end(), appender);
147
0
  }
148
0
  return result;
149
0
}
150
151
void AppenderAttachableImpl::removeAllAppenders()
152
766
{
153
766
  if (m_priv)
154
383
  {
155
383
    auto allAppenders = m_priv->getAppenders();
156
383
    for (auto& appender : *allAppenders)
157
0
      appender->close();
158
383
    m_priv->setAppenders({});
159
383
  }
160
766
}
161
162
void AppenderAttachableImpl::removeAppender(const AppenderPtr appender)
163
382
{
164
382
  if (m_priv && appender)
165
382
  {
166
382
    auto newAppenders = *m_priv->getAppenders();
167
382
    auto pItem = std::find(newAppenders.begin(), newAppenders.end(), appender);
168
382
    if (newAppenders.end() != pItem)
169
382
    {
170
382
      newAppenders.erase(pItem);
171
382
      m_priv->setAppenders(newAppenders);
172
382
    }
173
382
  }
174
382
}
175
176
void AppenderAttachableImpl::removeAppender(const LogString& name)
177
0
{
178
0
  if (m_priv)
179
0
  {
180
0
    auto newAppenders = *m_priv->getAppenders();
181
0
    auto pItem = std::find_if(newAppenders.begin(), newAppenders.end()
182
0
      , [&name](const AppenderPtr& appender) -> bool
183
0
      {
184
0
        return name == appender->getName();
185
0
      });
186
0
    if (newAppenders.end() != pItem)
187
0
    {
188
0
      newAppenders.erase(pItem);
189
0
      m_priv->setAppenders(newAppenders);
190
0
    }
191
0
  }
192
0
}
193
194
bool AppenderAttachableImpl::replaceAppender(const AppenderPtr& oldAppender, const AppenderPtr& newAppender)
195
0
{
196
0
  bool found = false;
197
0
  if (m_priv && oldAppender && newAppender)
198
0
  {
199
0
    auto name = oldAppender->getName();
200
0
    auto newAppenders = *m_priv->getAppenders();
201
0
    auto pItem = std::find_if(newAppenders.begin(), newAppenders.end()
202
0
      , [&name](const AppenderPtr& appender) -> bool
203
0
      {
204
0
        return name == appender->getName();
205
0
      });
206
0
    if (newAppenders.end() != pItem)
207
0
    {
208
0
      *pItem = newAppender;
209
0
      m_priv->setAppenders(newAppenders);
210
0
      found = true;
211
0
    }
212
0
  }
213
0
  return found;
214
0
}
215
216
void AppenderAttachableImpl::replaceAppenders(const AppenderList& newList)
217
0
{
218
0
  if (m_priv)
219
0
  {
220
0
    auto allAppenders = m_priv->getAppenders();
221
0
    for (auto& a : *allAppenders)
222
0
      a->close();
223
0
    m_priv->setAppenders(newList);
224
0
  }
225
0
  else
226
0
    m_priv = std::make_unique<priv_data>(newList);
227
0
}
228
229