int32_t refill_read_buffers(scap_t* handle, bool wait) { uint32_t j; uint32_t ndevs = handle->m_ndevs; if(wait) { if(check_scap_next_wait(handle)) { usleep(BUFFER_EMPTY_WAIT_TIME_MS * 1000); handle->m_n_consecutive_waits++; } } // // Refill our data for each of the devices // for(j = 0; j < ndevs; j++) { scap_device* dev = &(handle->m_devs[j]); int32_t res = scap_readbuf(handle, j, false, &dev->m_sn_next_event, &dev->m_sn_len); if(res != SCAP_SUCCESS) { return res; } } // // Note: we might return a spurious timeout here in case the previous loop extracted valid data to parse. // It's ok, since this is rare and the caller will just call us again after receiving a // SCAP_TIMEOUT. // return SCAP_TIMEOUT; }
static int32_t scap_next_live(scap_t* handle, OUT scap_evt** pevent, OUT uint16_t* pcpuid) #endif { #if !defined(HAS_CAPTURE) // // this should be prevented at open time // ASSERT(false); return SCAP_FAILURE; #else uint32_t j; uint64_t max_ts = 0xffffffffffffffffLL; uint64_t max_buf_size = 0; scap_evt* pe = NULL; bool waited = false; *pcpuid = 65535; for(j = 0; j < handle->m_ndevs; j++) { if(handle->m_devs[j].m_sn_len == 0) { // // The buffer for this CPU is fully consumed. // This is a good time to check if we should wait // if(handle->m_emptybuf_timeout_ms != 0) { if(check_scap_next_wait(handle) && !waited) { usleep(BUFFER_EMPTY_WAIT_TIME_MS * 1000); waited = true; } } // // read another buffer // int32_t res = scap_readbuf(handle, j, false, &handle->m_devs[j].m_sn_next_event, &handle->m_devs[j].m_sn_len); if(res != SCAP_SUCCESS) { return res; } } // // Make sure that we have data // if(handle->m_devs[j].m_sn_len != 0) { if(handle->m_devs[j].m_sn_len > max_buf_size) { max_buf_size = handle->m_devs[j].m_sn_len; } // // We want to consume the event with the lowest timestamp // pe = (scap_evt*)handle->m_devs[j].m_sn_next_event; #ifdef _DEBUG ASSERT(pe->len == scap_event_compute_len(pe)); #endif if(pe->ts < max_ts) { if(pe->len > handle->m_devs[j].m_sn_len) { snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "scap_next buffer corruption"); // // if you get the following assertion, first recompile the driver and libscap // ASSERT(false); return SCAP_FAILURE; } *pevent = pe; *pcpuid = j; max_ts = pe->ts; } } } // // Check which buffer has been picked // if(*pcpuid != 65535) { // // Update the pointers. // ASSERT(handle->m_devs[*pcpuid].m_sn_len >= (*pevent)->len); handle->m_devs[*pcpuid].m_sn_len -= (*pevent)->len; handle->m_devs[*pcpuid].m_sn_next_event += (*pevent)->len; return SCAP_SUCCESS; } else { // // This happens only when all the buffers are empty, which should be very rare. // The caller want't receive an event, but shouldn't treat this as an error and should just retry. // return SCAP_TIMEOUT; } #endif }