コード例 #1
0
ファイル: scap.c プロジェクト: Erethon/sysdig
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;
}
コード例 #2
0
ファイル: scap.c プロジェクト: 17twenty/sysdig
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
}