{ //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(" 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(" Couldn't reschedule sending.", GetSocket()); UnlockWriting(); Disconnect(true); return; } if(!event_pending(&m_ev_write, EV_WRITE, NULL)) sLog.outError(" 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(" EV_WRITE Skipped!", GetSocket()); } else { Disconnect(true); return; } } }