Beispiel #1
0
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;
		}
	}
}
Beispiel #2
0
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;
		}
	}
}
Beispiel #3
0
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;
		}
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
    }
    }
}