void handle_write(boost::system::error_code const& e, std::size_t bytes, boost::tuple<Handler, ParcelPostprocess> handler) { // just call initial handler boost::get<0>(handler)(e, bytes); // complete data point and push back onto gatherer send_data_.time_ = timer_.elapsed_nanoseconds() - send_data_.time_; parcels_sent_.add_data(send_data_); // now we can give this connection back to the cache out_buffer_.clear(); out_priority_ = 0; out_size_ = 0; send_data_.bytes_ = 0; send_data_.time_ = 0; send_data_.serialization_time_ = 0; send_data_.num_parcels_ = 0; // now handle the acknowledgement byte which is sent by the receiver #if defined(__linux) || defined(linux) || defined(__linux__) boost::asio::detail::socket_option::boolean< IPPROTO_TCP, TCP_QUICKACK> quickack(true); socket_.set_option(quickack); #endif void (parcelport_connection::*f)(boost::tuple<Handler, ParcelPostprocess>) = &parcelport_connection::handle_read_ack<Handler, ParcelPostprocess>; boost::asio::async_read(socket_, boost::asio::buffer(&ack_, sizeof(ack_)), boost::bind(f, shared_from_this(), handler)); }
// PD_TRACE_DECLARE_FUNCTION ( SDB__NETEVNHND__RDCALLBK, "_netEventHandler::_readCallback" ) void _netEventHandler::_readCallback( const boost::system::error_code & error ) { PD_TRACE_ENTRY ( SDB__NETEVNHND__RDCALLBK ) ; if ( error ) { if ( error.value() == boost::system::errc::operation_canceled || error.value() == boost::system::errc::no_such_file_or_directory ) { PD_LOG ( PDINFO, "connection aborted, node:%d, %d, %d", _id.columns.groupID, _id.columns.nodeID, _id.columns.serviceID ) ; } else { PD_LOG ( PDERROR, "Error received, node:%d, %d, %d, err=%d", _id.columns.groupID, _id.columns.nodeID, _id.columns.serviceID, error.value() ) ; } goto error_close ; } if ( NET_EVENT_HANDLER_STATE_HEADER == _state ) { if ( ( UINT32 )MSG_SYSTEM_INFO_LEN == (UINT32)_header.messageLength ) { if ( SDB_OK != _allocateBuf( sizeof(MsgSysInfoRequest) )) { goto error_close ; } _hasRecvMsg = TRUE ; ossMemcpy( _buf, &_header, sizeof( MsgSysInfoRequest ) ) ; _frame->handleMsg( shared_from_this() ) ; _state = NET_EVENT_HANDLER_STATE_HEADER ; asyncRead() ; goto done ; } else if ( sizeof(_MsgHeader) > (UINT32)_header.messageLength || SDB_MAX_MSG_LENGTH < (UINT32)_header.messageLength ) { PD_LOG( PDERROR, "Error header[len: %d, opCode: (%d)%d, TID:%d] " "received, node:%d, %d, %d", _header.messageLength, IS_REPLY_TYPE(_header.opCode) ? 1 : 0, GET_REQUEST_TYPE(_header.opCode), _header.TID, _id.columns.groupID, _id.columns.nodeID, _id.columns.serviceID ) ; goto error_close ; } else { if ( FALSE == _hasRecvMsg ) { _hasRecvMsg = TRUE ; _state = NET_EVENT_HANDLER_STATE_HEADER_LAST ; asyncRead() ; _state = NET_EVENT_HANDLER_STATE_HEADER ; goto done ; } PD_LOG( PDDEBUG, "msg header: [len:%d], [opCode: [%d]%d], " "[TID:%d], [groupID:%d], [nodeID:%d], " "[ADDR:%s], [PORT:%d]", _header.messageLength, IS_REPLY_TYPE(_header.opCode)?1:0, GET_REQUEST_TYPE(_header.opCode), _header.TID, _header.routeID.columns.groupID, _header.routeID.columns.nodeID, remoteAddr().c_str(), remotePort() ) ; if ( MSG_INVALID_ROUTEID == _id.value ) { if ( MSG_INVALID_ROUTEID != _header.routeID.value ) { _id = _header.routeID ; _frame->_addRoute( shared_from_this() ) ; } } } if ( (UINT32)sizeof(_MsgHeader) == (UINT32)_header.messageLength ) { if ( SDB_OK != _allocateBuf( sizeof(_MsgHeader) )) { goto error_close ; } ossMemcpy( _buf, &_header, sizeof( _MsgHeader ) ) ; _frame->handleMsg( shared_from_this() ) ; _state = NET_EVENT_HANDLER_STATE_HEADER ; asyncRead() ; goto done ; } #if defined (_LINUX) try { boost::asio::detail::socket_option::boolean<IPPROTO_TCP, TCP_QUICKACK> quickack( TRUE ) ; _sock.set_option( quickack ) ; } catch ( boost::system::system_error &e ) { PD_LOG ( PDERROR, "Failed to quick ack: %s", e.what() ) ; } #endif // _LINUX _state = NET_EVENT_HANDLER_STATE_BODY ; asyncRead() ; } else { _frame->handleMsg( shared_from_this() ) ; _state = NET_EVENT_HANDLER_STATE_HEADER ; asyncRead() ; } done: PD_TRACE_EXIT ( SDB__NETEVNHND__RDCALLBK ) ; return ; error_close: if ( _isConnected ) { close() ; } _frame->handleClose( shared_from_this(), _id ) ; _frame->_erase( handle() ) ; goto done ; }