in src/main/cpp/asyncappender.cpp [205:283]
void AsyncAppender::append(const spi::LoggingEventPtr& event, Pool& p)
{
if (priv->bufferSize <= 0)
{
priv->appenders->appendLoopOnAppenders(event, p);
}
if (!priv->dispatcher.joinable())
{
priv->dispatcher = ThreadUtility::instance()->createThread( LOG4CXX_STR("AsyncAppender"), &AsyncAppender::dispatch, this );
}
// Set the NDC and MDC for the calling thread as these
// LoggingEvent fields were not set at event creation time.
LogString ndcVal;
event->getNDC(ndcVal);
// Get a copy of this thread's MDC.
event->getMDCCopy();
{
std::unique_lock<std::mutex> lock(priv->bufferMutex);
while (true)
{
size_t previousSize = priv->buffer.size();
if (previousSize < (size_t)priv->bufferSize)
{
priv->buffer.push_back(event);
if (previousSize == 0)
{
priv->bufferNotEmpty.notify_all();
}
break;
}
//
// Following code is only reachable if buffer is full
//
//
// if blocking and thread is not already interrupted
// and not the dispatcher then
// wait for a buffer notification
bool discard = true;
if (priv->blocking
&& !priv->closed
&& (priv->dispatcher.get_id() != std::this_thread::get_id()) )
{
priv->bufferNotFull.wait(lock);
discard = false;
}
//
// if blocking is false or thread has been interrupted
// add event to discard map.
//
if (discard)
{
LogString loggerName = event->getLoggerName();
DiscardMap::iterator iter = priv->discardMap.find(loggerName);
if (iter == priv->discardMap.end())
{
DiscardSummary summary(event);
priv->discardMap.insert(DiscardMap::value_type(loggerName, summary));
}
else
{
(*iter).second.add(event);
}
break;
}
}
}
}