[netperf-dev] netperf4 commit notice r85 - in
branches/glib_migration: . src
raj at netperf.org
raj at netperf.org
Fri Mar 17 16:48:24 PST 2006
Author: raj
Date: 2006-03-17 16:48:23 -0800 (Fri, 17 Mar 2006)
New Revision: 85
Modified:
branches/glib_migration/AUTHORS
branches/glib_migration/src/netlib.c
branches/glib_migration/src/netlib.h
branches/glib_migration/src/netperf.h
Log:
Another step down the glib conversion path, got some of the low-level
"read from the socket" callbacks and what they call written and compiled,
but not tested, now have to "invert" the instantiate_mumble routine and
get straight all that needs to be passed along via the "data" pointer
one can register to the call-back.
Modified: branches/glib_migration/AUTHORS
===================================================================
--- branches/glib_migration/AUTHORS 2006-03-17 17:46:09 UTC (rev 84)
+++ branches/glib_migration/AUTHORS 2006-03-18 00:48:23 UTC (rev 85)
@@ -13,3 +13,6 @@
Stephen Burger
Responsible for first working tests and multiple client
initiailization.
+
+Simon Leinen
+Initial Solaris (9) porting work
\ No newline at end of file
Modified: branches/glib_migration/src/netlib.c
===================================================================
--- branches/glib_migration/src/netlib.c 2006-03-17 17:46:09 UTC (rev 84)
+++ branches/glib_migration/src/netlib.c 2006-03-18 00:48:23 UTC (rev 85)
@@ -1632,6 +1632,183 @@
}
+/* loop and grab all the available bytes, but no more than N from the
+ source and return. add the number of bytes received to the
+ bytes_read parameter */
+GIOStatus
+read_n_available_bytes(GIOChannel *source, gchar *data, gsize n, gsize *bytes_read, GError **error) {
+ GIOStatus status;
+
+ gsize bytes_to_read;
+ gsize bytes_this_read;
+ gchar *buffer;
+
+ bytes_to_read = n;
+ *bytes_read = 0;
+ buffer = data + 1;
+
+ while (((status = g_io_channel_read_chars(source,
+ buffer,
+ bytes_to_read,
+ &bytes_this_read,
+ error)) ==
+ G_IO_STATUS_NORMAL) && (bytes_to_read > 0)) {
+ *bytes_read += bytes_this_read;
+ bytes_to_read -= bytes_this_read;
+ buffer = buffer + *bytes_read;
+ }
+ return(status);
+}
+
+/* given a buffer with a complete control message, XML parse it and
+ then send it on its way. */
+gboolean
+xml_parse_control_message(gchar *message, gsize length, gpointer data) {
+
+ xmlDocPtr xml_message;
+ gboolean ret;
+
+ NETPERF_DEBUG_ENTRY(debug,where);
+
+ if ((xml_message = xmlParseMemory(message, length)) != NULL) {
+ /* got the message, run with it */
+ if (debug) {
+ g_fprintf(where,
+ "%s:xmlParseMemory parsed a %d byte message at %p giving doc at %p\n",
+ __func__,
+ length,
+ message,
+ xml_message);
+ }
+ /* send it on its way*/
+ ret = TRUE;
+ }
+ else {
+ if (debug) {
+ g_fprintf(where,
+ "%s: xmlParseMemory gagged on a %d byte message at %p\n",
+ __func__,
+ length,
+ message);
+ }
+ ret = FALSE;
+ }
+ NETPERF_DEBUG_EXIT(debug,where);
+ return(ret);
+}
+
+gboolean
+read_from_control_connection(GIOChannel *source, GIOCondition condition, gpointer data) {
+ message_state_t *message_state;
+ gsize bytes_read;
+ GError *error = NULL;
+ gchar *ptr;
+ GIOStatus status;
+
+ NETPERF_DEBUG_ENTRY(debug,where);
+ message_state = data;
+ if (debug) {
+ g_fprintf(where,
+ "%s called with cource %p condition %x and data %p\n",
+ __func__,
+ source,
+ condition,
+ data);
+ if (message_state) {
+ g_fprintf(where,
+ "%s message_state have_header %d bytes_remaining %d buffer %p\n",
+ __func__,
+ message_state->have_header,
+ message_state->bytes_remaining,
+ message_state->buffer);
+ }
+ else {
+ g_error("%s called with null message_state\n",__func__);
+ }
+ }
+
+ /* ok, so here we go... */
+ if (!message_state->have_header) {
+ /* we still have to get the header */
+ if (NULL == message_state->buffer) {
+ /* the very first time round */
+ message_state->bytes_remaining = NETPERF_MESSAGE_HEADER_SIZE;
+ message_state->bytes_received = 0;
+ message_state->buffer = g_malloc(NETPERF_MESSAGE_HEADER_SIZE);
+ }
+ /* now try to grab the rest of the header */
+ ptr = message_state->buffer + message_state->bytes_received;
+ bytes_read = 0;
+ status = read_n_available_bytes(source,
+ ptr,
+ message_state->bytes_remaining,
+ &bytes_read,
+ &error);
+
+ /* we need some sort of error and status check here don't we? */
+
+ if (G_IO_STATUS_EOF == status) {
+ /* do something when the remote has told us they are going away */
+ }
+ else if ((G_IO_STATUS_ERROR == status) ||
+ (NULL != error)) {
+ /* do something to deal with an error condition */
+ }
+
+ message_state->bytes_received += bytes_read;
+ message_state->bytes_remaining -= bytes_read;
+
+ /* now, do we have the whole header? */
+ if (message_state->bytes_received == NETPERF_MESSAGE_HEADER_SIZE) {
+ /* setup for the message body */
+ message_state->have_header = TRUE;
+ message_state->bytes_remaining = ntohl(*(int *)message_state->buffer);
+ message_state->bytes_received = 0;
+ g_free(message_state->buffer);
+ message_state->buffer = g_malloc(message_state->bytes_remaining);
+ }
+ }
+
+ /* this is a separate if rather than an else clause because we want
+ to possibly execute this code in addition to the "get the rest of
+ the header" code. I suspect there is some way to do this with
+ less actual code but for now it seems sufficient. besides, we
+ want to make sure we drain the channel fully - otherwise there
+ may be some issues on Windows, maybe something to do with
+ possibly not getting notified of other bytes if we simply came
+ back out to let the event loop call us again. raj 2006-03-17 */
+ if (message_state->have_header) {
+ bytes_read = 0;
+ ptr = message_state->buffer + message_state->bytes_received;
+ status = read_n_available_bytes(source,
+ ptr,
+ message_state->bytes_remaining,
+ &bytes_read,
+ &error);
+
+ /* we need some sort of error and status check here don't we? */
+
+ if (G_IO_STATUS_EOF == status) {
+ /* do something when the remote has told us they are going away */
+ }
+ else if ((G_IO_STATUS_ERROR == status) ||
+ (NULL != error)) {
+ /* do something to deal with an error condition */
+ }
+
+ message_state->bytes_received += bytes_read;
+ message_state->bytes_remaining -= bytes_read;
+
+ if (0 == message_state->bytes_remaining) {
+ /* we have an entire message, time to process it */
+ }
+ }
+
+ NETPERF_DEBUG_EXIT(debug,where);
+
+ return(TRUE);
+}
+
int32_t
recv_control_message(int control_sock, xmlDocPtr *message)
{
Modified: branches/glib_migration/src/netlib.h
===================================================================
--- branches/glib_migration/src/netlib.h 2006-03-17 17:46:09 UTC (rev 84)
+++ branches/glib_migration/src/netlib.h 2006-03-18 00:48:23 UTC (rev 85)
@@ -40,6 +40,10 @@
#include "config.h"
#endif
+#ifdef WITH_GLIB
+#include <glib.h>
+#endif
+
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#ifdef TIME_WITH_SYS_TIME
@@ -128,6 +132,13 @@
unsigned int valid_states;
};
+typedef struct message_state {
+ gboolean have_header;
+ gint32 bytes_received;
+ gint32 bytes_remaining;
+ gpointer buffer;
+} message_state_t;
+
extern void netlib_init();
void display_test_hash();
Modified: branches/glib_migration/src/netperf.h
===================================================================
--- branches/glib_migration/src/netperf.h 2006-03-17 17:46:09 UTC (rev 84)
+++ branches/glib_migration/src/netperf.h 2006-03-18 00:48:23 UTC (rev 85)
@@ -135,6 +135,8 @@
#include "netconfidence.h"
+#define NETPERF_MESSAGE_HEADER_SIZE sizeof(guint32)
+
#define NETPERF_DEFAULT_SERVICE_NAME "netperf4"
#define NETPERF_DTD_FILE (const xmlChar *)"http://www.netperf.org/netperf_docs.dtd/1.0"
#define NETPERF_VERSION (const xmlChar *)"4"
More information about the netperf-dev
mailing list