stream->id, component->id);
}
+/* Will attempt to queue all @n_messages into the pseudo-TCP transmission
+ * buffer. This is always used in reliable mode, so essentially treats @messages
+ * as a massive flat array of buffers.
+ *
+ * Returns the number of messages successfully sent on success (which may be
+ * zero if sending the first buffer of the message would have blocked), or
+ * a negative number on error. */
+static gint
+pseudo_tcp_socket_send_messages (PseudoTcpSocket *self,
+ const NiceOutputMessage *messages, guint n_messages, GError **error)
+{
+ guint i;
+
+ for (i = 0; i < n_messages; i++) {
+ const NiceOutputMessage *message = &messages[i];
+ guint j;
+
+ /* If there’s not enough space for the entire message, bail now before
+ * queuing anything. This doesn’t gel with the fact this function is only
+ * used in reliable mode, and there is no concept of a ‘message’, but is
+ * necessary because the calling API has no way of returning to the client
+ * and indicating that a message was partially sent. */
+ if (message->length > pseudo_tcp_socket_get_available_send_space (self)) {
+ return i;
+ }
+
+ for (j = 0;
+ (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
+ (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
+ j++) {
+ const GOutputVector *buffer = &message->buffers[j];
+ gssize ret;
+
+ /* Send on the pseudo-TCP socket. */
+ ret = pseudo_tcp_socket_send (self, buffer->buffer, buffer->size);
+
+ /* In case of -1, the error is either EWOULDBLOCK or ENOTCONN, which both
+ * need the user to wait for the reliable-transport-writable signal */
+ if (ret < 0 && pseudo_tcp_socket_get_error (self) == EWOULDBLOCK) {
+ ret = 0;
+ return i;
+ } else if (ret < 0 && pseudo_tcp_socket_get_error (self) == ENOTCONN) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
+ "TCP connection is not yet established.");
+ return ret;
+ } else if (ret < 0) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error writing data to pseudo-TCP socket.");
+ return ret;
+ }
+ }
+ }
+
+ return i;
+}
+
/* Will fill up @messages from the first free byte onwards (as determined using
* @iter). This is always used in reliable mode, so it essentially treats
* @messages as a massive flat array of buffers.
if (component->selected_pair.local != NULL) {
NiceSocket *sock;
NiceAddress *addr;
+ GOutputVector local_buf;
+ NiceOutputMessage local_message;
sock = component->selected_pair.local->sockptr;
#endif
addr = &component->selected_pair.remote->addr;
- if (nice_socket_send (sock, addr, len, buffer)) {
+
+ local_buf.buffer = buffer;
+ local_buf.size = len;
+ local_message.buffers = &local_buf;
+ local_message.n_buffers = 1;
+ local_message.to = addr;
+ local_message.length = len;
+
+ if (nice_socket_send_messages (sock, &local_message, 1)) {
return WR_SUCCESS;
}
} else {
return local_messages.length;
}
-/**
- * nice_agent_send_full:
- * @agent: a #NiceAgent
- * @stream_id: the ID of the stream to send to
- * @component_id: the ID of the component to send to
- * @buf: (array length=buf_len): data to transmit, of at least @buf_len bytes in
- * size
- * @buf_len: length of valid data in @buf, in bytes
- * @cancellable: (allow-none): a #GCancellable to cancel the operation from
- * another thread, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Sends the data in @buf on the socket identified by the given stream/component
- * pair. Transmission is non-blocking, so a %G_IO_ERROR_WOULD_BLOCK error may be
- * returned if the send buffer is full.
- *
- * As with nice_agent_send(), the given component must be in
- * %NICE_COMPONENT_STATE_READY or, as a special case, in any state if it was
- * previously ready and was then restarted.
- *
- * On success, the number of bytes written to the socket will be returned (which
- * will always be @buf_len when in non-reliable mode, and may be less than
- * @buf_len when in reliable mode).
- *
- * On failure, -1 will be returned and @error will be set. If the #NiceAgent is
- * reliable and the socket is not yet connected, %G_IO_ERROR_BROKEN_PIPE will be
- * returned; if the write buffer is full, %G_IO_ERROR_WOULD_BLOCK will be
- * returned. In both cases, wait for the #NiceAgent::reliable-transport-writable
- * signal before trying again. If the given @stream_id or @component_id are
- * invalid or not yet connected, %G_IO_ERROR_BROKEN_PIPE will be returned.
- * %G_IO_ERROR_FAILED will be returned for other errors.
- *
- * Returns: the number of bytes sent (guaranteed to be greater than 0), or -1 on
- * error
- *
- * Since: 0.1.5
- */
-NICEAPI_EXPORT gssize
-nice_agent_send_full (
+NICEAPI_EXPORT gint
+nice_agent_send_messages_nonblocking (
NiceAgent *agent,
guint stream_id,
guint component_id,
- const guint8 *buf,
- gsize buf_len,
+ const NiceOutputMessage *messages,
+ guint n_messages,
GCancellable *cancellable,
GError **error)
{
Stream *stream;
Component *component;
- gssize ret = -1;
+ gint n_sent_messages = -1;
GError *child_error = NULL;
g_return_val_if_fail (NICE_IS_AGENT (agent), -1);
g_return_val_if_fail (stream_id >= 1, -1);
g_return_val_if_fail (component_id >= 1, -1);
- g_return_val_if_fail (buf != NULL, -1);
+ g_return_val_if_fail (n_messages == 0 || messages != NULL, -1);
g_return_val_if_fail (
cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
g_return_val_if_fail (error == NULL || *error == NULL, -1);
if (component->tcp != NULL) {
/* Send on the pseudo-TCP socket. */
- ret = pseudo_tcp_socket_send (component->tcp, (const gchar *) buf, buf_len);
+ n_sent_messages = pseudo_tcp_socket_send_messages (component->tcp, messages,
+ n_messages, &child_error);
adjust_tcp_clock (agent, stream, component);
if (!pseudo_tcp_socket_can_send (component->tcp))
g_cancellable_reset (component->tcp_writable_cancellable);
- /* In case of -1, the error is either EWOULDBLOCK or ENOTCONN, which both
- need the user to wait for the reliable-transport-writable signal */
- if (ret < 0 &&
- pseudo_tcp_socket_get_error (component->tcp) == EWOULDBLOCK) {
- g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
- "Write would block.");
- goto done;
- } else if (ret < 0 &&
- pseudo_tcp_socket_get_error (component->tcp) == ENOTCONN) {
- g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
- "TCP connection is not yet established.");
- goto done;
- } else if (ret < 0) {
+ if (n_sent_messages < 0) {
/* Signal error */
priv_pseudo_tcp_error (agent, stream, component);
-
- g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Error writing data to pseudo-TCP socket.");
- goto done;
}
} else if (agent->reliable) {
g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Error writing data to failed pseudo-TCP socket.");
- goto done;
} else if (component->selected_pair.local != NULL) {
NiceSocket *sock;
NiceAddress *addr;
+ guint i;
#ifndef NDEBUG
gchar tmpbuf[INET6_ADDRSTRLEN];
nice_address_to_string (&component->selected_pair.remote->addr, tmpbuf);
- nice_debug ("Agent %p : s%d:%d: sending %" G_GSIZE_FORMAT " bytes to "
- "[%s]:%d", agent, stream_id, component_id, buf_len, tmpbuf,
+ nice_debug ("Agent %p : s%d:%d: sending %u messages to "
+ "[%s]:%d", agent, stream_id, component_id, n_messages, tmpbuf,
nice_address_get_port (&component->selected_pair.remote->addr));
#endif
sock = component->selected_pair.local->sockptr;
addr = &component->selected_pair.remote->addr;
- if (nice_socket_send (sock, addr, buf_len, (const gchar *) buf)) {
- /* Success: sent all the bytes. */
- ret = buf_len;
- } else {
- /* Some error. Since nice_socket_send() provides absolutely no useful
- * feedback, assume it’s EWOULDBLOCK. */
- g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
- "Error writing data to socket: probably would block.");
- goto done;
+ /* Set the destination address. FIXME: This is ugly. */
+ for (i = 0; i < n_messages; i++) {
+ NiceOutputMessage *message = (NiceOutputMessage *) &messages[i];
+ message->to = addr;
+ }
+
+ n_sent_messages = nice_socket_send_messages (sock, messages, n_messages);
+
+ if (n_sent_messages < 0) {
+ g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Error writing data to socket.");
}
} else {
/* Socket isn’t properly open yet. */
- g_set_error (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
- "Can’t send: No selected pair yet.");
- goto done;
+ n_sent_messages = 0; /* EWOULDBLOCK */
+ }
+
+ /* Handle errors and cancellations. */
+ if (n_sent_messages == 0) {
+ g_set_error_literal (&child_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
+ g_strerror (EAGAIN));
+ n_sent_messages = -1;
}
+ nice_debug ("%s: n_sent_messages: %d, n_messages: %u", G_STRFUNC,
+ n_sent_messages, n_messages);
+
done:
- g_assert ((child_error != NULL) == (ret == -1));
- g_assert (ret != 0);
+ g_assert ((child_error != NULL) == (n_sent_messages == -1));
+ g_assert (n_sent_messages != 0);
+ g_assert (n_sent_messages < 0 || (guint) n_sent_messages <= n_messages);
if (child_error != NULL)
g_propagate_error (error, child_error);
agent_unlock ();
- return ret;
+ return n_sent_messages;
}
NICEAPI_EXPORT gint
guint len,
const gchar *buf)
{
- return nice_agent_send_full (agent, stream_id, component_id,
- (const guint8 *) buf, len, NULL, NULL);
+ GOutputVector local_buf = { buf, len };
+ NiceOutputMessage local_message = { &local_buf, 1, NULL, len };
+ gint n_sent_messages;
+
+ n_sent_messages = nice_agent_send_messages_nonblocking (agent, stream_id,
+ component_id, &local_message, 1, NULL, NULL);
+
+ if (n_sent_messages == 1)
+ return len;
+ return n_sent_messages;
}
NICEAPI_EXPORT GSList *
#include <unistd.h>
#endif
+/* Maximum IP payload ((1 << 16) - 1), minus IP header, minus UDP header. */
+#define MAX_MESSAGE_SIZE (65535 - 20 - 8) /* bytes */
+
typedef enum {
STREAM_AGENT, /* nice_agent_[send|recv]() */
STREAM_AGENT_NONBLOCKING, /* nice_agent_[send|recv]_nonblocking() */
typedef enum {
BUFFER_SIZE_CONSTANT_LARGE, /* always 65535 bytes */
- BUFFER_SIZE_CONSTANT_SMALL, /* always 1024 bytes */
+ BUFFER_SIZE_CONSTANT_SMALL, /* always 4096 bytes */
BUFFER_SIZE_CONSTANT_TINY, /* always 1 byte */
BUFFER_SIZE_ASCENDING, /* ascending powers of 2 */
BUFFER_SIZE_RANDOM, /* random every time */
} receive;
BufferDataStrategy buffer_data_strategy;
gsize n_bytes;
+ guint n_messages;
/* Test state. */
GRand *transmit_size_rand;
gsize transmitted_bytes;
gsize received_bytes;
gsize *other_received_bytes;
+ guint transmitted_messages;
+ guint received_messages;
+ guint *other_received_messages;
} TestData;
/* Whether @stream_api is blocking (vs. non-blocking). */
*
* @max_buffer_size may be used to limit the total size of all the buffers in
* all the messages, for example to avoid blocking on receiving data which will
- * never be sent.
+ * never be sent. This only applies for blocking, reliable stream APIs.
+ *
+ * @max_n_messages may be used to limit the number of messages generated, to
+ * avoid blocking on receiving messages which will never be sent. This only
+ * applies for blocking, non-reliable stream APIs.
*
* @messages must be freed with g_free(), as must all of the buffer arrays and
* the buffers themselves. */
static void
generate_messages_to_receive (TestIOStreamThreadData *data, gsize buffer_offset,
- NiceInputMessage **messages, guint *n_messages, gsize max_buffer_size)
+ NiceInputMessage **messages, guint *n_messages, gsize max_buffer_size,
+ guint max_n_messages)
{
TestData *test_data = data->user_data;
guint i;
*n_messages =
generate_message_count (test_data->receive.message_count_strategy,
test_data->receive_size_rand, buffer_offset);
+
+ if (!data->reliable)
+ *n_messages = MIN (*n_messages, max_n_messages);
+
*messages = g_malloc_n (*n_messages, sizeof (NiceInputMessage));
for (i = 0; i < *n_messages; i++) {
test_data->receive_size_rand, buffer_offset);
/* Trim the buffer length if it would otherwise cause the API to block. */
- if (data->reliable)
+ if (data->reliable) {
buf_len = MIN (buf_len, max_buffer_size);
+ max_buffer_size -= buf_len;
+ }
- max_buffer_size -= buf_len;
buffer->size = buf_len;
-
buffer->buffer = g_malloc (buffer->size);
/* Fill it with poison to try and detect incorrect writes. */
/* If we’ve hit the max_buffer_size, adjust the buffer and message counts
* and run away. */
- if (max_buffer_size == 0) {
+ if (data->reliable && max_buffer_size == 0) {
message->n_buffers = j + 1;
*n_messages = i + 1;
return;
if (stream_api_is_blocking (test_data->stream_api) && data->reliable)
g_assert_cmpint (len, ==, buf_len);
- /* Validate the buffer contents. */
+ /* Validate the buffer contents.
+ *
+ * Note: Buffers can only be validated up to valid_len. The buffer may
+ * have been re-used internally (e.g. by receiving a STUN message, then
+ * overwriting it with a data packet), so we can’t guarantee that the
+ * bytes beyond valid_len have been untouched. */
expected_buf = g_malloc (buf_len);
memset (expected_buf, 0xaa, buf_len);
generate_buffer_data (test_data->buffer_data_strategy, buffer_offset,
expected_buf, len);
- g_assert (memcmp (*buf, expected_buf, buf_len) == 0);
+ g_assert (memcmp (*buf, expected_buf, len) == 0);
g_free (expected_buf);
test_data->received_bytes += len;
if (stream_api_is_blocking (test_data->stream_api))
g_assert_cmpint (n_valid_messages, ==, n_messages);
+ test_data->received_messages += n_valid_messages;
+
/* Validate the message contents. */
for (i = 0; i < (guint) n_valid_messages; i++) {
NiceInputMessage *message = &((*messages)[i]);
guint8 *expected_buf;
gsize valid_len;
+ /* See note above about valid_len. */
total_buf_len += buffer->size;
valid_len = MIN (message_len_remaining, buffer->size);
memset (expected_buf, 0xaa, buffer->size);
generate_buffer_data (test_data->buffer_data_strategy, buffer_offset,
expected_buf, valid_len);
- g_assert (memcmp (buffer->buffer, expected_buf, buffer->size) == 0);
+ g_assert (memcmp (buffer->buffer, expected_buf, valid_len) == 0);
g_free (expected_buf);
test_data->received_bytes += valid_len;
prev_message_len = message->length;
/* If the API was blocking, it should have completely filled the message. */
- if (stream_api_is_blocking (test_data->stream_api))
+ if (stream_api_is_blocking (test_data->stream_api) && data->reliable)
g_assert_cmpuint (message->length, ==, total_buf_len);
g_assert (message->from == NULL);
*buf, *buf_len);
}
+/* Similar to generate_buffer_to_transmit(), except that it generates an array
+ * of NiceOutputMessages rather than a single buffer. */
+static void
+generate_messages_to_transmit (TestIOStreamThreadData *data,
+ gsize buffer_offset, NiceOutputMessage **messages, guint *n_messages)
+{
+ TestData *test_data = data->user_data;
+ guint i;
+ gsize total_buf_len = 0;
+
+ /* Determine the number of messages to send. */
+ *n_messages =
+ generate_message_count (test_data->transmit.message_count_strategy,
+ test_data->transmit_size_rand, buffer_offset);
+ *n_messages =
+ MIN (*n_messages,
+ test_data->n_messages - test_data->transmitted_messages);
+
+ *messages = g_malloc_n (*n_messages, sizeof (NiceOutputMessage));
+
+ for (i = 0; i < *n_messages; i++) {
+ NiceOutputMessage *message = &((*messages)[i]);
+ guint j;
+ gsize max_message_size;
+
+ message->n_buffers =
+ generate_buffer_count (test_data->transmit.buffer_count_strategy,
+ test_data->transmit_size_rand, buffer_offset);
+ message->buffers = g_malloc_n (message->n_buffers, sizeof (GOutputVector));
+ message->to = NULL;
+ message->length = 0;
+
+ /* Limit the overall message size to the smaller of (n_bytes / n_messages)
+ * and MAX_MESSAGE_SIZE, to ensure each message is non-empty. */
+ max_message_size =
+ MIN ((test_data->n_bytes / test_data->n_messages), MAX_MESSAGE_SIZE);
+
+ for (j = 0; j < (guint) message->n_buffers; j++) {
+ GOutputVector *buffer = &message->buffers[j];
+ gsize buf_len;
+ guint8 *buf;
+
+ buf_len =
+ generate_buffer_size (test_data->transmit.buffer_size_strategy,
+ test_data->transmit_size_rand, buffer_offset);
+ buf_len =
+ MIN (buf_len,
+ test_data->n_bytes - test_data->transmitted_bytes - total_buf_len);
+ buf_len = MIN (buf_len, max_message_size - message->length);
+
+ buffer->size = buf_len;
+ buf = g_malloc (buffer->size);
+ buffer->buffer = buf;
+ message->length += buf_len;
+ total_buf_len += buf_len;
+
+ /* Fill it with data. */
+ generate_buffer_data (test_data->buffer_data_strategy, buffer_offset,
+ buf, buf_len);
+
+ buffer_offset += buf_len;
+
+ /* Reached the maximum UDP payload size? */
+ if (message->length >= max_message_size) {
+ message->n_buffers = j + 1;
+ break;
+ }
+ }
+
+ g_assert_cmpuint (message->length, <=, max_message_size);
+ }
+}
+
/* Validate the number of bytes transmitted, and update the test’s internal
* state machine. Consumes @buf. */
static void
g_free (*buf);
}
+/* Similar to notify_transmitted_buffer(), except it operates on an array of
+ * messages from generate_messages_to_transmit(). */
+static void
+notify_transmitted_messages (TestIOStreamThreadData *data, gsize buffer_offset,
+ NiceOutputMessage **messages, guint n_messages, gint n_sent_messages)
+{
+ TestData *test_data = data->user_data;
+ guint i;
+
+ g_assert_cmpint (n_sent_messages, <=, n_messages);
+ g_assert_cmpint (n_sent_messages, >=, 0);
+
+ test_data->transmitted_messages += n_sent_messages;
+
+ for (i = 0; i < n_messages; i++) {
+ NiceOutputMessage *message = &((*messages)[i]);
+ guint j;
+
+ if (i < (guint) n_sent_messages)
+ test_data->transmitted_bytes += message->length;
+
+ for (j = 0; j < (guint) message->n_buffers; j++) {
+ GOutputVector *buffer = &message->buffers[j];
+
+ g_free ((guint8 *) buffer->buffer);
+ }
+
+ g_free (message->buffers);
+ }
+
+ g_free (*messages);
+}
+
/*
* Implementation using nice_agent_recv_messages() and nice_agent_send().
*/
/* Initialise an array of messages to receive into. */
generate_messages_to_receive (data, test_data->received_bytes, &messages,
- &n_messages, test_data->n_bytes - test_data->received_bytes);
+ &n_messages, test_data->n_bytes - test_data->received_bytes,
+ test_data->n_messages - test_data->received_messages);
/* Block on receiving some data. */
n_valid_messages = nice_agent_recv_messages (data->agent, stream_id,
while (test_data->transmitted_bytes < test_data->n_bytes) {
GError *error = NULL;
- guint8 *buf = NULL;
- gsize buf_len = 0;
- gssize _len;
- gssize len = 0;
+ NiceOutputMessage *messages;
+ guint n_messages;
+ gint n_sent_messages;
/* Generate a buffer to transmit. */
- generate_buffer_to_transmit (data, test_data->transmitted_bytes, &buf,
- &buf_len);
+ generate_messages_to_transmit (data, test_data->transmitted_bytes,
+ &messages, &n_messages);
- /* Transmit it. */
+ /* Busy loop on receiving some data. */
do {
- _len = nice_agent_send_full (data->agent, stream_id, component_id,
- buf + len, buf_len - len, NULL, &error);
-
- /* Busy loop on EWOULDBLOCK. */
- if (_len == -1 &&
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
- g_clear_error (&error);
- continue;
- } else if (_len > 0) {
- len += _len;
- } else {
- len = _len;
- }
-
- g_assert_no_error (error);
- } while (len != -1 && (gsize) len < buf_len);
+ g_clear_error (&error);
+ n_sent_messages = nice_agent_send_messages_nonblocking (data->agent,
+ stream_id, component_id, messages, n_messages, NULL, &error);
+ } while (n_sent_messages == -1 &&
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK));
+ g_assert_no_error (error);
/* Update the test’s buffer generation state machine. */
- notify_transmitted_buffer (data, test_data->transmitted_bytes, &buf,
- buf_len, len);
+ notify_transmitted_messages (data, test_data->transmitted_bytes, &messages,
+ n_messages, n_sent_messages);
}
}
/* Initialise an array of messages to receive into. */
generate_messages_to_receive (data, test_data->received_bytes, &messages,
- &n_messages, test_data->n_bytes - test_data->received_bytes);
+ &n_messages, test_data->n_bytes - test_data->received_bytes,
+ test_data->n_messages - test_data->received_messages);
+
+ /* Trim n_messages to avoid consuming the ‘done’ message. */
+ n_messages =
+ MIN (n_messages, test_data->n_messages - test_data->received_messages);
/* Busy loop on receiving some data. */
do {
static void
test_data_init (TestData *data, gboolean reliable, StreamApi stream_api,
- gsize n_bytes, BufferSizeStrategy transmit_buffer_size_strategy,
+ gsize n_bytes, guint n_messages,
+ BufferSizeStrategy transmit_buffer_size_strategy,
BufferCountStrategy transmit_buffer_count_strategy,
MessageCountStrategy transmit_message_count_strategy,
BufferSizeStrategy receive_buffer_size_strategy,
BufferCountStrategy receive_buffer_count_strategy,
MessageCountStrategy receive_message_count_strategy,
BufferDataStrategy buffer_data_strategy, guint32 transmit_seed,
- guint32 receive_seed, gsize *other_received_bytes)
+ guint32 receive_seed, gsize *other_received_bytes,
+ guint *other_received_messages)
{
data->reliable = reliable;
data->stream_api = stream_api;
data->n_bytes = n_bytes;
+ data->n_messages = n_messages;
data->transmit.buffer_size_strategy = transmit_buffer_size_strategy;
data->transmit.buffer_count_strategy = transmit_buffer_count_strategy;
data->transmit.message_count_strategy = transmit_message_count_strategy;
data->transmitted_bytes = 0;
data->received_bytes = 0;
data->other_received_bytes = other_received_bytes;
+ data->transmitted_messages = 0;
+ data->received_messages = 0;
+ data->other_received_messages = other_received_messages;
}
/*
}
static void
-test (gboolean reliable, StreamApi stream_api, gsize n_bytes,
+test (gboolean reliable, StreamApi stream_api, gsize n_bytes, guint n_messages,
BufferSizeStrategy transmit_buffer_size_strategy,
BufferCountStrategy transmit_buffer_count_strategy,
MessageCountStrategy transmit_message_count_strategy,
NULL, NULL }, /* STREAM_GSOURCE */
};
- test_data_init (&l_data, reliable, stream_api, n_bytes,
+ test_data_init (&l_data, reliable, stream_api, n_bytes, n_messages,
transmit_buffer_size_strategy, transmit_buffer_count_strategy,
transmit_message_count_strategy, receive_buffer_size_strategy,
receive_buffer_count_strategy, receive_message_count_strategy,
buffer_data_strategy, transmit_seed, receive_seed,
- &r_data.received_bytes);
- test_data_init (&r_data, reliable, stream_api, n_bytes,
+ &r_data.received_bytes, &r_data.received_messages);
+ test_data_init (&r_data, reliable, stream_api, n_bytes, n_messages,
transmit_buffer_size_strategy, transmit_buffer_count_strategy,
transmit_message_count_strategy, receive_buffer_size_strategy,
receive_buffer_count_strategy, receive_message_count_strategy,
buffer_data_strategy, transmit_seed, receive_seed,
- &l_data.received_bytes);
+ &l_data.received_bytes, &l_data.received_messages);
run_io_stream_test (deadlock_timeout, reliable, &callbacks[stream_api],
&l_data, NULL, &r_data, NULL);
/* Options with default values. */
guint32 option_transmit_seed = 0;
guint32 option_receive_seed = 0;
-gsize option_n_bytes = 100000;
+gsize option_n_bytes = 10000;
+guint option_n_messages = 50;
guint option_timeout = 1200; /* seconds */
gboolean option_long_mode = FALSE;
{ "receive-seed", 0, 0, G_OPTION_ARG_INT, &option_receive_seed,
"Seed for reception RNG", "S" },
{ "n-bytes", 'n', 0, G_OPTION_ARG_INT64, &option_n_bytes,
- "Number of bytes to send in each test (default 100000)", "N" },
+ "Number of bytes to send in each test (default 10000)", "N" },
+ { "n-messages", 'm', 0, G_OPTION_ARG_INT64, &option_n_messages,
+ "Number of messages to send in each test (default 50)", "M" },
{ "timeout", 't', 0, G_OPTION_ARG_INT, &option_timeout,
"Deadlock detection timeout length, in seconds (default: 1200)", "S" },
{ "long-mode", 'l', 0, G_OPTION_ARG_NONE, &option_long_mode,
guint32 transmit_seed;
guint32 receive_seed;
gsize n_bytes;
+ guint n_messages;
guint deadlock_timeout;
gboolean long_mode;
GOptionContext *context;
transmit_seed = option_transmit_seed;
receive_seed = option_receive_seed;
n_bytes = option_n_bytes;
+ n_messages = option_n_messages;
deadlock_timeout = option_timeout;
long_mode = option_long_mode;
receive_message_count_strategy = MESSAGE_COUNT_CONSTANT_ONE;
}
- g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, "
+ g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, %u, "
"%u, %u, %u, %u)…",
- reliable, stream_api, n_bytes, transmit_buffer_size_strategy,
+ reliable, stream_api, n_bytes, n_messages,
+ transmit_buffer_size_strategy,
receive_buffer_size_strategy, buffer_data_strategy,
transmit_seed, receive_seed);
- test (reliable, stream_api, n_bytes, transmit_buffer_size_strategy,
+ test (reliable, stream_api, n_bytes, n_messages,
+ transmit_buffer_size_strategy,
transmit_buffer_count_strategy, transmit_message_count_strategy,
receive_buffer_size_strategy, receive_buffer_count_strategy,
receive_message_count_strategy, buffer_data_strategy,
receive_message_count_strategy != MESSAGE_COUNT_CONSTANT_ONE))
continue;
- g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, "
+ g_debug ("Running test (%u, %u, %" G_GSIZE_FORMAT ", %u, %u, "
"%u, %u, %u, %u, %u, %u, %u, %u)…",
- reliable, stream_api, n_bytes, transmit_buffer_size_strategy,
+ reliable, stream_api, n_bytes, n_messages,
+ transmit_buffer_size_strategy,
transmit_buffer_count_strategy, transmit_message_count_strategy,
receive_buffer_size_strategy, receive_buffer_count_strategy,
receive_message_count_strategy, buffer_data_strategy,
transmit_seed, receive_seed);
- test (reliable, stream_api, n_bytes, transmit_buffer_size_strategy,
+ test (reliable, stream_api, n_bytes, n_messages,
+ transmit_buffer_size_strategy,
transmit_buffer_count_strategy, transmit_message_count_strategy,
receive_buffer_size_strategy, receive_buffer_count_strategy,
receive_message_count_strategy, buffer_data_strategy,