示例#1
0
ssize_t
qb_rb_chunk_peek(struct qb_ringbuffer_s * rb, void **data_out, int32_t timeout)
{
	uint32_t read_pt;
	uint32_t chunk_size;
	uint32_t chunk_magic;
	int32_t res = 0;

	if (rb == NULL) {
		return -EINVAL;
	}
	if (rb->notifier.timedwait_fn) {
		res = rb->notifier.timedwait_fn(rb->notifier.instance, timeout);
	}
	if (res < 0 && res != -EIDRM) {
		if (res == -ETIMEDOUT) {
			return 0;
		} else {
			errno = -res;
			qb_util_perror(LOG_ERR, "sem_timedwait");
		}
		return res;
	}
	read_pt = rb->shared_hdr->read_pt;
	chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);
	if (chunk_magic != QB_RB_CHUNK_MAGIC) {
		if (rb->notifier.post_fn) {
			(void)rb->notifier.post_fn(rb->notifier.instance, res);
		}
		return 0;
	}
	chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
	*data_out = QB_RB_CHUNK_DATA_GET(rb, read_pt);
	return chunk_size;
}
示例#2
0
ssize_t
qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t len,
		 int32_t timeout)
{
	uint32_t read_pt;
	uint32_t chunk_size;
	uint32_t chunk_magic;
	int32_t res = 0;

	if (rb == NULL) {
		return -EINVAL;
	}
	if (rb->notifier.timedwait_fn) {
		res = rb->notifier.timedwait_fn(rb->notifier.instance, timeout);
	}
	if (res < 0 && res != -EIDRM) {
		if (res != -ETIMEDOUT) {
			errno = -res;
			qb_util_perror(LOG_ERR, "sem_timedwait");
		}
		return res;
	}

	read_pt = rb->shared_hdr->read_pt;
	chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);

	if (chunk_magic != QB_RB_CHUNK_MAGIC) {
		if (rb->notifier.timedwait_fn == NULL) {
			return -ETIMEDOUT;
		} else {
			(void)rb->notifier.post_fn(rb->notifier.instance, res);
#ifdef EBADMSG
			return -EBADMSG;
#else
			return -EINVAL;
#endif
		}
	}

	chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
	if (len < chunk_size) {
		qb_util_log(LOG_ERR,
			    "trying to recv chunk of size %d but %d available",
			    len, chunk_size);
		if (rb->notifier.post_fn) {
			(void)rb->notifier.post_fn(rb->notifier.instance, chunk_size);
		}
		return -ENOBUFS;
	}

	memcpy(data_out,
	       QB_RB_CHUNK_DATA_GET(rb, read_pt),
	       chunk_size);

	_rb_chunk_reclaim(rb);

	return chunk_size;
}
示例#3
0
void *
qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len)
{
	uint32_t write_pt;

	if (rb == NULL) {
		errno = EINVAL;
		return NULL;
	}
	/*
	 * Reclaim data if we are over writing and we need space
	 */
	if (rb->flags & QB_RB_FLAG_OVERWRITE) {
		while (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) {
			int rc = _rb_chunk_reclaim(rb);
			if (rc != 0) {
				errno = rc;
				return NULL;
			}
		}
	} else {
		if (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) {
			errno = EAGAIN;
			return NULL;
		}
	}

	write_pt = rb->shared_hdr->write_pt;
	/*
	 * insert the chunk header
	 */
	rb->shared_data[write_pt] = 0;
	QB_RB_CHUNK_MAGIC_SET(rb, write_pt, QB_RB_CHUNK_MAGIC_ALLOC);

	/*
	 * return a pointer to the beginning of the chunk data
	 */
	return (void *)QB_RB_CHUNK_DATA_GET(rb, write_pt);

}