{
//Lock buffer to send
if(!WriteBuffer()->get_data_size())
return;
LockWriting();
int n = send(GetSocket(), (const char*)WriteBuffer()->get_buffer(), WriteBuffer()->get_data_size(), SEND_FLAG);
if(n != SOCKET_ERROR)
{
//for DEBUG only!
// if(n == 0)
// sLog.outError("<Socket %u> DEBUG.Rognar: sent zero bytes!", GetSocket());
if(n > 0)//Remove sent data from output buffer
WriteBuffer()->remove(n);
if (WriteBuffer()->get_data_size())
{//We still have data. reschedule sending
if(event_add(&m_ev_write, NULL) == -1)
{
sLog.outError("<Socket %u> Couldn't reschedule sending.", GetSocket());
UnlockWriting();
Disconnect(true);
return;
}
if(!event_pending(&m_ev_write, EV_WRITE, NULL))
sLog.outError("<Socket %u> EV_WRITE Skipped!", GetSocket());
}
else//Output buffer is empty
m_SendAllowed = true;
}
UnlockWriting();
if (n == SOCKET_ERROR)
{
if (errno == EAGAIN || errno == EINTR)
{
//"Resource temporarily unavailable"
//This error is returned from operations on nonblocking sockets that cannot be completed immediately,
//for example recv when no data is queued to be read from the socket.
//It is a nonfatal error, and the operation should be retried later.
//It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect
//on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established.
if(event_add(&m_ev_write, NULL) == -1)
{
Disconnect(true);
return;
}
if(!event_pending(&m_ev_write, EV_WRITE, NULL))
sLog.outError("<Socket %u> EV_WRITE Skipped!", GetSocket());
}
else
{
Disconnect(true);
return;
}
}
}