in FixAntenna/NetCore/FixEngine/Session/IoThreads/SyncMessagePumper.cs [784:864]
private int Send(string msgType, FixMessage content, ChangesType? changesType, FixSessionSendingType optionMask)
{
try
{
lock (_queue)
{
var sync = (optionMask & FixSessionSendingType.SendSync) != 0;
var async = (optionMask & FixSessionSendingType.SendAsync) != 0;
// TBD! We can send messages only for connected session. Make check for session state lighter
if (optionMask != 0 && (!async || sync) && !HasAnyWorkQueued() && !_queue.OutOfTurnOnlyMode
&& SessionState.IsConnected(_fixSession.SessionState) && !_shutdownFlag)
{
_tmpMessageWithType.FixMessage = content;
_tmpMessageWithType.MessageType = msgType;
_tmpMessageWithType.ChangesType = changesType;
_tmpMsgBuf.Buffer = null;
//TODO: check how to buffer filling
var isUsingOriginalMsgBuffer = FillBuffer(_tmpMessageWithType, _tmpMsgBuf);
try
{
//TODO: and why we are passing byte[] instead of whole buffer
SendMessages(1, _tmpMsgBuf.Buffer);
}
catch (IOException ex)
{
if (Log.IsTraceEnabled)
{
Log.Debug("Sync send ERROR: " + ex.ToString(), ex);
}
else if (Log.IsDebugEnabled)
{
Log.Debug("Sync send ERROR: " + ex.ToString());
}
//there is problem with transport. Let's start pumper thread to do all "dirty" work
_queue.OutOfTurnOnlyMode = true;
Monitor.PulseAll(_queue);
_fixSession.ErrorHandler.OnError("", ex);
//throw ex;
}
if (isUsingOriginalMsgBuffer)
{
//can try to release the message after send is done
ReleaseMessageIfNeeded(content);
}
//message was sent directly only if queue is empty
return 0;
}
IsQueueTooBig();
//TODO - create pool for this
var fieldListWithType = changesType == null
? FixMessageWithTypePoolFactory.GetFixMessageWithTypeFromPool(content, msgType)
: FixMessageWithTypePoolFactory.GetFixMessageWithTypeFromPool(content, changesType);
var added = _queue.Add(fieldListWithType);
if (added)
{
_queue.NotifyAllApplication();
}
else
{
throw new MessageNotSentException("Message wasn't added to outgoing queue");
}
//message was queued
return _queue.TotalSize;
}
}
catch (IOException ex)
{
// solve deadlock:
// - TestRequestTask lock session first and then lock queue (during sending logon)
// - here we lock queue first and then we locked session during shutdown.
// For a moment here we will release queue lock here to avoid deadlock
ReportErrorAndShutdown(ex);
return _queue.TotalSize;
}
}