void async_serial::_read_end( const boost::system::error_code& error, size_t bytes_transferred) { if(error) { if(is_open()) { _do_close(); _set_error_status(true); } } else { if(_callback) _callback( _read_buffer, bytes_transferred); _do_read(); } }
void edthreaded_fd::_exec() { bool running = true; while (running) { m_wait_timer->update(); if (!m_wait_timer->running()) _do_write(); _do_read(); pthread_mutex_lock(&m_running_lock); running = m_running; pthread_mutex_unlock(&m_running_lock); } pthread_exit(nullptr); }
// -------------------------------------------------------------------------- // _do_read_wrap: Private function used to wrap the actual read operation and // analyse the return code from the read to translate it in a more general // return code. // // Parameters: // p_engine: p_config: Pointer to an ICMP_ECHO_ENGINE_PARMS structure. // tv_ref: Absolute time at which we should exit this function. // // Return values: // IEE_SUCCESS: Operation was successful. Continue. // IEE_GENERAL_ECHO_ERROR: Fatal error occurred. Abort. // IEE_CONNECTIVITY_ASSESSED: (ACD only) Stop processing. // iee_ret_t _do_read_wrap( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_ref ) { double time_left_ms; // Time left to spend in this function. double read_delay; // Number of milliseconds before the soonest echo event times out. struct timeval tv_delay; // The actual time delay. uint32_t echo_seq_read; // Echo sequence read. iee_priv_ret_t priv_retval; iee_ret_t retval = IEE_SUCCESS; // Check how much time we have left to spend here. time_left_ms = _compute_tv_diff_now( tv_ref ); if( time_left_ms <= 0.0 ) { // Return because it's already time to send a new ECHO REQUEST. // Should not happen in normal processing. Can happen if debugging. return IEE_SUCCESS; } // Main read loop. do { if( p_engine->event_list != NULL ) { // Check how much time before the soonest echo event times out. read_delay = _compute_tv_diff_now( &p_engine->event_list->tv_timeout ); } else { read_delay = p_engine->send_interval; } // Translate that in a timeval structure. _conv_ms_to_tv( MIN(time_left_ms, read_delay), &tv_delay ); // ------------------------------------------ // Wait for an incoming packet, and read it. // ------------------------------------------ priv_retval = _do_read( p_engine, &tv_delay, &echo_seq_read ); // Perform operations depending on what happened in the read. switch( priv_retval ) { case ANAL_PACKET_BAD: case ANAL_PACKET_IGNORED: // We don't care. break; case READ_SELECT_TIMEOUT: if( time_left_ms > read_delay && p_engine->event_list != NULL ) { // An echo event has timed out. // => Increment late counter and consecutive late counter. p_engine->count_late++; p_engine->count_consec_late++; DBG_PRINT("--> Echo timeout detected! count_consec_late:%d\n",p_engine->count_consec_late); // => Remove the echo event from the list. _remove_free_echo_event( p_engine, p_engine->event_list->echo_seq ); } // else, we have reached the time to quit processing incoming // packets. break; case ANAL_PACKET_PINGIN_ONTIME: // We received an ECHO REPLY on time. // => Reset the consecutive late counter. Increment the ontime counter. p_engine->count_consec_late = 0; p_engine->count_ontime++; // => Remove the associated echo event from the list. priv_retval = _remove_free_echo_event( p_engine, echo_seq_read ); if( priv_retval != ECHO_EVENT_REMOVED ) { // This event was already removed from the list (Probably because // a READ_SELECT_TIMEOUT occured while waiting for it). // Since it is a valid on time reply, we've reset the consecutive // late count. p_engine->count_late--; DBG_PRINT("--> Last echo timeout cancelled.\n"); } // If the icmp echo engine is in mode Automatic Connectivity // Detection (ACD), any received reply assesses a valid // connectivity. if( (iee_mode_t)p_engine->eng_mode == IEE_MODE_ACD ) { p_engine->eng_ongoing = 0; retval = IEE_CONNECTIVITY_ASSESSED; DBG_PRINT("Connectivity has been assessed (ACD).\n"); } // ** INTENTIONAL FALLTHROUGH ** // case ANAL_PACKET_PINGIN_LATE: // The associated echo event should have already beed removed from // the list of echo events. // Check if this received ECHO REPLY was the last. if( p_engine->echo_num != 0 && p_engine->count_send >= p_engine->echo_num ) { // This is our last echo reply. p_engine->eng_ongoing = 0; } break; case READ_SOCKET_CLOSED: p_engine->eng_ongoing = 0; // Should have already been set. retval = IEE_SUCCESS; DBG_PRINT("ICMP echo engine socket has been closed."); break; case READ_SELECT_ERROR: // Fatal error case READ_RECV_ERROR: // Fatal error default: // Unhandled cases (Should not occur). p_engine->eng_ongoing = 0; retval = IEE_GENERAL_ECHO_ERROR; break; } // Check if we've reached the maximal number of consecutive timeouts. if( p_engine->count_consec_late >= p_engine->echo_timeout_threshold ) { retval = IEE_GENERAL_ECHO_TIMEOUT; p_engine->eng_ongoing = 0; DBG_PRINT("General Echo Timeout detected.\n"); } // Check how much time we have left to spend here. time_left_ms = _compute_tv_diff_now( tv_ref ); } // Loop until we have to stop reading packets, or we've been notified // to stop processing. while( time_left_ms > 0.0 && p_engine->eng_ongoing == 1 ); return retval; }