Example #1
0
/**
 * Read data from the pmsg list into supplied buffer.  Copied data is
 * removed from the list.
 *
 * @param slist		the pmsg list
 * @param buf		start of buffer where data must be copied
 * @param len		length of buffer
 *
 * @return amount of copied bytes.
 */
size_t
pmsg_slist_read(slist_t *slist, void *buf, size_t len)
{
	slist_iter_t *iter;
	size_t remain = len;
	void *p;

	g_assert(slist != NULL);
	g_assert_log(size_is_non_negative(len), "%s(): len=%zd", G_STRFUNC, len);

	iter = slist_iter_removable_on_head(slist);
	p = buf;

	while (remain != 0 && slist_iter_has_item(iter)) {
		pmsg_t *mb = slist_iter_current(iter);
		int n;

		n = pmsg_read(mb, p, remain);
		remain -= n;
		p = ptr_add_offset(p, n);
		if (0 == pmsg_size(mb)) {			/* Fully copied message */
			pmsg_free(mb);
			slist_iter_remove(iter);		/* Warning: moves to next */
		} else {
			break;		/* No need to continue on partial copy */
		}
	}
	slist_iter_free(&iter);

	return len - remain;
}
Example #2
0
/**
 * Appends `n_bytes' to the pmsg_t buffer. If the last pmsg_t is writable
 * it is filled with as much data as space is still available. Otherwise
 * or if this space is not sufficient another pmsg_t is created and
 * appendded to the list.
 */
void
pmsg_slist_append(slist_t *slist, const void *data, size_t n_bytes)
{
	pmsg_t *mb;

	g_assert(slist);
	g_assert_log(size_is_non_negative(n_bytes),
		"%s(): n_bytes=%zd", G_STRFUNC, n_bytes);

	if (0 == n_bytes)
		return;
	g_assert(NULL != data);

	mb = slist_tail(slist);
	if (mb && pmsg_is_writable(mb)) {
		size_t n;

		n = pmsg_write(mb, data, n_bytes);
		data = (const char *) data + n;
		n_bytes -= n;
	}
	if (n_bytes > 0) {
		mb = pmsg_new(PMSG_P_DATA, NULL, MAX(n_bytes, PMSG_SLIST_GROW_MIN));
		pmsg_write(mb, data, n_bytes);
		slist_append(slist, mb);
	}
}
Example #3
0
/*
 * Release lock on aging table.
 *
 * The table must have been marked thread-safe already and locked by the
 * calling thread.
 */
void
aging_unlock(aging_table_t *ag)
{
	aging_check(ag);
	g_assert_log(ag->lock != NULL,
		"%s(): aging table %p not marked thread-safe", G_STRFUNC, ag);

	mutex_unlock(ag->lock);
}
Example #4
0
/**
 * Write NUL-terminated string, up to `n' characters or the first seen NUL
 * in the buffer, whichever comes first.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_fixed_string(pmsg_t *mb, const char *str, size_t n)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert(UNSIGNED(pmsg_available(mb)) >= n + 10);	/* Need ule64 length */
	g_assert_log(size_is_non_negative(n), "%s(): n=%zd", G_STRFUNC, n);

	len = strlen(str);
	len = MIN(n, len);
	pmsg_write_ule64(mb, (uint64) len);

	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #5
0
/**
 * Read data from the message, returning the amount of bytes transferred.
 */
int
pmsg_read(pmsg_t *mb, void *data, int len)
{
	int available, readable;

	pmsg_check_consistency(mb);
	g_assert_log(len >= 0, "%s(): len=%d", G_STRFUNC, len);

	available = mb->m_wptr - mb->m_rptr;
	g_assert(available >= 0);		/* Data cannot go beyond end of arena */

	readable = len >= available ? available : len;
	if (readable != 0) {
		memcpy(data, mb->m_rptr, readable);
		mb->m_rptr += readable;
	}
	return readable;
}
Example #6
0
/**
 * Write NUL-terminated string.
 *
 * If (size_t) -1 is given as length, then it is computed via strlen(), in
 * which case the string buffer must be NUL-terminated.  Otherwise, the value
 * is taken to be the pre-computed string length.
 *
 * The string is written as: <ule64(length)><bytes>, no trailing NUL.
 */
void
pmsg_write_string(pmsg_t *mb, const char *str, size_t length)
{
	size_t len;

	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */
	g_assert_log(size_is_non_negative(length) || (size_t) -1 == length,
		"%s(): length=%zd", G_STRFUNC, length);

	len = (size_t) -1 == length ? strlen(str) : length;

	g_assert(UNSIGNED(pmsg_available(mb)) >= len + 10);	/* Need ule64 length */

	pmsg_write_ule64(mb, (uint64) len);
	if (len != 0) {
		pmsg_write(mb, str, len);
	}
}
Example #7
0
/**
 * Discard trailing data from the message, returning the amount of
 * bytes discarded.
 */
int
pmsg_discard_trailing(pmsg_t *mb, int len)
{
	int available, n;

	pmsg_check_consistency(mb);
	g_assert_log(len >= 0, "%s(): len=%d", G_STRFUNC, len);

	available = mb->m_wptr - mb->m_rptr;
	g_assert(available >= 0);		/* Data cannot go beyond end of arena */

	/*
 	 * The write pointer moves backward to point before the discarded bytes.
	 */

	n = len >= available ? available : len;
	mb->m_wptr -= n;
	return n;
}
Example #8
0
/**
 * Discard data from the message, returning the amount of bytes discarded.
 */
int
pmsg_discard(pmsg_t *mb, int len)
{
	int available, n;

	pmsg_check(mb);
	g_assert_log(len >= 0, "%s(): len=%d", G_STRFUNC, len);

	available = mb->m_wptr - mb->m_rptr;
	g_assert(available >= 0);		/* Data cannot go beyond end of arena */

	/*
	 * The read pointer moves forward to point after the discarded bytes.
	 */

	n = len >= available ? available : len;
	mb->m_rptr += n;
	return n;
}
Example #9
0
/**
 * Write data at the end of the message.
 * The message must be the only reference to the underlying data.
 *
 * @returns amount of written data.
 */
int
pmsg_write(pmsg_t *mb, const void *data, int len)
{
	pdata_t *arena;
	int available, written;

	pmsg_check_consistency(mb);
	g_assert_log(len >= 0, "%s(): len=%d", G_STRFUNC, len);
	g_assert(pmsg_is_writable(mb));	/* Not shared, or would corrupt data */

	arena = mb->m_data;
	available = arena->d_end - mb->m_wptr;
	g_assert(available >= 0);		/* Data cannot go beyond end of arena */

	written = len >= available ? available : len;
	if (written != 0)
		mb->m_wptr = mempcpy(mb->m_wptr, data, written);

	return written;
}
Example #10
0
/**
 * Copy ``len'' bytes from the source message block to the destination by
 * reading the source bytes and writing them to the recipient.
 *
 * @returns amount of bytes written, which may be lower than the requested
 * amount if the source buffer was shorter or there is not enough room in
 * the destination.
 */
int
pmsg_copy(pmsg_t *dest, pmsg_t *src, int len)
{
	int copied, available;

	pmsg_check_consistency(dest);
	pmsg_check_consistency(src);
	g_assert_log(len >= 0, "%s(): len=%d", G_STRFUNC, len);
	g_assert(pmsg_is_writable(dest));	/* Not shared, or would corrupt data */

	copied = src->m_wptr - src->m_rptr;	/* Available data in source */
	copied = MIN(copied, len);
	available = pmsg_available(dest);	/* Room in destination buffer */
	copied = MIN(copied, available);

	if (copied > 0) {
		dest->m_wptr = mempcpy(dest->m_wptr, src->m_rptr, copied);
		src->m_rptr += copied;
	}

	return copied;
}