bool TCPCarrier::OnEvent(select_event &event) { int32_t readAmount = 0; int32_t writeAmount = 0; //3. Do the I/O switch (event.type) { case SET_READ: { IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer(); assert(pInputBuffer != NULL); if (!pInputBuffer->ReadFromTCPFd(_inboundFd, _recvBufferSize, readAmount)) { FATAL("Unable to read data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); return false; } _rx += readAmount; _pProtocol->OnRecvAmount(readAmount); return _pProtocol->SignalInputData(readAmount); } case SET_WRITE: { IOBuffer *pOutputBuffer = NULL; while ((pOutputBuffer = _pProtocol->GetOutputBuffer()) != NULL) { if (!pOutputBuffer->WriteToTCPFd(_outboundFd, _sendBufferSize, writeAmount)) { FATAL("Unable to send data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); IOHandlerManager::EnqueueForDelete(this); return false; } _tx += writeAmount; _pProtocol->OnSendAmount(writeAmount); if (GETAVAILABLEBYTESCOUNT(*pOutputBuffer) > 0) { ENABLE_WRITE_DATA; break; } } if (pOutputBuffer == NULL) { DISABLE_WRITE_DATA; } return true; } default: { ASSERT("Invalid state: %hhu", event.type); return false; } } }
bool TCPCarrier::OnEvent(struct kevent &event) { //3. Do the I/O switch (event.filter) { case EVFILT_READ: { IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer(); o_assert(pInputBuffer != NULL); if (!pInputBuffer->ReadFromTCPFd(event.ident, event.data, _ioAmount, _lastRecvError)) { FATAL("Unable to read data from connection: %s. Error was (%d): %s", (_pProtocol != NULL) ? STR(*_pProtocol) : "", _lastRecvError, strerror(_lastRecvError)); return false; } _rx += _ioAmount; ADD_IN_BYTES_MANAGED(_type, _ioAmount); if (!_pProtocol->SignalInputData(_ioAmount)) { FATAL("Unable to read data from connection: %s. Signaling upper protocols failed", (_pProtocol != NULL) ? STR(*_pProtocol) : ""); return false; } return true; } case EVFILT_WRITE: { IOBuffer *pOutputBuffer = NULL; if ((pOutputBuffer = _pProtocol->GetOutputBuffer()) != NULL) { if (!pOutputBuffer->WriteToTCPFd(event.ident, event.data, _ioAmount, _lastSendError)) { FATAL("Unable to write data on connection: %s. Error was (%d): %s", (_pProtocol != NULL) ? STR(*_pProtocol) : "", _lastSendError, strerror(_lastSendError)); IOHandlerManager::EnqueueForDelete(this); return false; } _tx += _ioAmount; ADD_OUT_BYTES_MANAGED(_type, _ioAmount); if (GETAVAILABLEBYTESCOUNT(*pOutputBuffer) == 0) { DISABLE_WRITE_DATA; } } else { DISABLE_WRITE_DATA; } return true; } default: { FATAL("Unable to read/write data from/to connection: %s. Invalid event type: %d", (_pProtocol != NULL) ? STR(*_pProtocol) : "", event.filter); return false; } } }
bool TCPCarrier::OnEvent(struct kevent &event) { //3. Do the I/O switch (event.filter) { case EVFILT_READ: { IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer(); o_assert(pInputBuffer != NULL); if (!pInputBuffer->ReadFromTCPFd(event.ident, event.data, _ioAmount)) { FATAL("Unable to read data. %s:%"PRIu16" -> %s:%"PRIu16" %s", STR(_farIp), _farPort, STR(_nearIp), _nearPort, (_pProtocol != NULL) ? STR(*_pProtocol) : "" ); return false; } _rx += _ioAmount; ADD_IN_BYTES_MANAGED(_type, _ioAmount); return _pProtocol->SignalInputData(_ioAmount); } case EVFILT_WRITE: { IOBuffer *pOutputBuffer = NULL; if ((pOutputBuffer = _pProtocol->GetOutputBuffer()) != NULL) { if (!pOutputBuffer->WriteToTCPFd(event.ident, event.data, _ioAmount)) { FATAL("Unable to send data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); IOHandlerManager::EnqueueForDelete(this); return false; } _tx += _ioAmount; ADD_OUT_BYTES_MANAGED(_type, _ioAmount); if (GETAVAILABLEBYTESCOUNT(*pOutputBuffer) == 0) { DISABLE_WRITE_DATA; } } else { DISABLE_WRITE_DATA; } return true; } default: { ASSERT("Invalid state: %hd", event.filter); return false; } } }
bool TCPCarrier::OnEvent(struct epoll_event &event) { //1. Read data if ((event.events & EPOLLIN) != 0) { IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer(); o_assert(pInputBuffer != NULL); if (!pInputBuffer->ReadFromTCPFd(_inboundFd, _recvBufferSize, _ioAmount)) { FATAL("Unable to read data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); return false; } _rx += _ioAmount; ADD_IN_BYTES_MANAGED(_type, _ioAmount); if (_ioAmount == 0) { FATAL("Connection closed"); return false; } if (!_pProtocol->SignalInputData(_ioAmount)) { FATAL("Unable to signal data available"); return false; } } //2. Write data if ((event.events & EPOLLOUT) != 0) { IOBuffer *pOutputBuffer = NULL; if ((pOutputBuffer = _pProtocol->GetOutputBuffer()) != NULL) { if (!pOutputBuffer->WriteToTCPFd(_inboundFd, _sendBufferSize, _ioAmount)) { FATAL("Unable to send data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); IOHandlerManager::EnqueueForDelete(this); return false; } _tx += _ioAmount; ADD_OUT_BYTES_MANAGED(_type, _ioAmount); if (GETAVAILABLEBYTESCOUNT(*pOutputBuffer) == 0) { DISABLE_WRITE_DATA; } } else { DISABLE_WRITE_DATA; } } return true; }
bool TCPCarrier::OnEvent(struct kevent &event) { int32_t readAmount = 0; int32_t writeAmount = 0; //3. Do the I/O switch (event.filter) { case EVFILT_READ: { IOBuffer *pInputBuffer = _pProtocol->GetInputBuffer(); assert(pInputBuffer != NULL); if (!pInputBuffer->ReadFromTCPFd(event.ident, event.data, readAmount)) { FATAL("Unable to read data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); return false; } _rx += readAmount; return _pProtocol->SignalInputData(readAmount); } case EVFILT_WRITE: { IOBuffer *pOutputBuffer = NULL; if ((pOutputBuffer = _pProtocol->GetOutputBuffer()) != NULL) { if (!pOutputBuffer->WriteToTCPFd(event.ident, event.data, writeAmount)) { FATAL("Unable to send data. %s:%hu -> %s:%hu", STR(_farIp), _farPort, STR(_nearIp), _nearPort); IOHandlerManager::EnqueueForDelete(this); return false; } _tx += writeAmount; if (GETAVAILABLEBYTESCOUNT(*pOutputBuffer) == 0) { DISABLE_WRITE_DATA; } } else { DISABLE_WRITE_DATA; } return true; } default: { ASSERT("Invalid state: %hd", event.filter); return false; } } }