void AsyncAppender::append()

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;
			}
		}
	}
}