[netperf-dev] netperf4 commit notice r218 -
branches/gobject_migration/src
raj at netperf.org
raj at netperf.org
Thu Mar 15 16:46:20 PST 2007
Author: raj
Date: 2007-03-15 16:46:18 -0800 (Thu, 15 Mar 2007)
New Revision: 218
Modified:
branches/gobject_migration/src/netperf-control.c
branches/gobject_migration/src/netperf-control.h
branches/gobject_migration/src/netperf-netserver.c
Log:
prepare to send a version message
Modified: branches/gobject_migration/src/netperf-control.c
===================================================================
--- branches/gobject_migration/src/netperf-control.c 2007-03-15 22:27:08 UTC (rev 217)
+++ branches/gobject_migration/src/netperf-control.c 2007-03-16 00:46:18 UTC (rev 218)
@@ -78,7 +78,7 @@
/* our control signals */
enum {
- NEW_MESSAGE, /* this would be the control connection object
+ MESSAGE, /* this would be the control connection object
telling us a complete message has arrived. */
CONTROL_CLOSED, /* this would be the control connection object
telling us the control connection died. */
@@ -89,7 +89,7 @@
we can use it to size the array correctly. */
};
-static void netperf_control_new_message(NetperfControl *control, gpointer message);
+static void netperf_control_message(NetperfControl *control, gpointer message);
static void netperf_control_control_closed(NetperfControl *control);
static void netperf_control_connect(NetperfControl *control);
@@ -271,19 +271,19 @@
have a signal say for the arrival of a complete message or
perhaps the cotnrol connection going down or somesuch. */
- klass->new_message = netperf_control_new_message;
+ klass->message = netperf_control_message;
klass->control_closed = netperf_control_control_closed;
klass->connect_control = netperf_control_connect;
- netperf_control_signals[NEW_MESSAGE] =
- g_signal_new("new_message", /* signal name */
+ netperf_control_signals[MESSAGE] =
+ g_signal_new("message", /* signal name */
TYPE_NETPERF_CONTROL, /* class type id */
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, /* options,
not sure if
G_SIGNAL_DETAILED
is
indicated */
- G_STRUCT_OFFSET(NetperfControlClass, new_message),
+ G_STRUCT_OFFSET(NetperfControlClass, message),
NULL, /* no accumulator */
NULL, /* so no accumulator data */
g_cclosure_marshal_VOID__POINTER, /* return void,
@@ -314,12 +314,150 @@
}
/* signal handler for new message */
-static void netperf_control_new_message(NetperfControl *control, gpointer message)
+static void netperf_control_message(NetperfControl *control, gpointer message)
{
- g_print("A new message %p arrived for control object %p\n",
- message,
- control);
+ netperf_control_msg_desc_t *descriptor = message;
+ g_print("Control object %p was requested to send a message from descriptor %p\n",
+ control,
+ message);
+
+ int rc;
+ int32_t length;
+
+ gchar *chars_to_send;
+
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+ xmlNodePtr message_header;
+ xmlNodePtr new_node;
+ char *control_message;
+ int control_message_len;
+ gsize bytes_written;
+ GError *error = NULL;
+ GIOStatus status;
+
+ if ((doc = xmlNewDoc((xmlChar *)"1.0")) != NULL) {
+ /* zippity do dah */
+ doc->standalone = 0;
+ dtd = xmlCreateIntSubset(doc,(xmlChar *)"message",NULL,NETPERF_DTD_FILE);
+ if (dtd != NULL) {
+ if (((message_header = xmlNewNode(NULL,(xmlChar *)"message")) != NULL) &&
+ (xmlSetProp(message_header,(xmlChar *)"tonid",descriptor->nid) != NULL) &&
+ (xmlSetProp(message_header,(xmlChar *)"fromnid",descriptor->fromnid) != NULL)) {
+ /* zippity ay */
+ xmlDocSetRootElement(doc,message_header);
+ /* it certainly would be nice to not have to do this with two
+ calls... raj 2003-02-28 */
+ if (((new_node = xmlDocCopyNode(descriptor->body,doc,1)) != NULL) &&
+ (xmlAddChild(message_header, new_node) != NULL)) {
+ /* IF there were a call where I could specify the buffer,
+ then we wouldn't have to copy this again to get things
+ contiguous with the "header" - then again, if the glib IO
+ channel stuff offered a gathering write call it wouldn't
+ matter... raj 2006-03-24 */
+ xmlDocDumpMemory(doc,
+ (xmlChar **)&control_message,
+ &control_message_len);
+ if (control_message_len > 0) {
+ /* what a wonderful day */
+
+ length = control_message_len;
+
+ if (debug) {
+ g_fprintf(where,
+ "%s allocating %d bytes\n",
+ __func__,
+ length+NETPERF_MESSAGE_HEADER_SIZE);
+ }
+
+ chars_to_send = g_malloc(length+NETPERF_MESSAGE_HEADER_SIZE);
+
+ /* if glib IO channels offered a gathering write, this
+ silliness wouldn't be necessary. yes, they offer
+ buffered I/O and I could do two writes and then a
+ flush, but dagnabit, if I could just call sendmsg()
+ before, so no extra copies, no flushes, it certainly
+ would be nice to be able to do the same with an IO
+ channel. raj 2006-03-24 */
+
+ /* the message length send via the network does not include
+ the length itself... raj 2003-02-27 */
+ length = htonl(strlen(control_message));
+
+ /* first copy the "header" ... */
+ memcpy(chars_to_send,
+ &length,
+ NETPERF_MESSAGE_HEADER_SIZE);
+ if (debug) {
+ g_fprintf(where,
+ "%s copied %d bytes to %p\n",
+ __func__,
+ NETPERF_MESSAGE_HEADER_SIZE,
+ chars_to_send);
+ }
+ /* ... now copy the "data" */
+ memcpy(chars_to_send+NETPERF_MESSAGE_HEADER_SIZE,
+ control_message,
+ control_message_len);
+
+ if (debug) {
+ g_fprintf(where,
+ "%s copied %d bytes to %p\n",
+ __func__,
+ control_message_len,
+ chars_to_send+NETPERF_MESSAGE_HEADER_SIZE);
+ }
+
+ /* and finally, send the data */
+ status = g_io_channel_write_chars(control->source,
+ chars_to_send,
+ control_message_len +
+ NETPERF_MESSAGE_HEADER_SIZE,
+ &bytes_written,
+ &error);
+
+ if (debug) {
+ /* first display the header */
+ fprintf(where, "Sending %d byte message\n",
+ control_message_len);
+ fprintf(where, "|%*s| ",control_message_len,control_message);
+ fflush(where);
+ }
+ if (bytes_written ==
+ (control_message_len+NETPERF_MESSAGE_HEADER_SIZE)) {
+ if (debug) {
+ fprintf(where,"was successful\n");
+ }
+ rc = NPE_SUCCESS;
+ } else {
+ rc = NPE_SEND_CTL_MSG_FAILURE;
+ if (debug) {
+ fprintf(where,"failed\n");
+ }
+ }
+ g_free(chars_to_send);
+ /* this may not be the 100% correct place for this */
+ xmlFreeDoc(doc);
+ free(control_message);
+ } else {
+ rc = NPE_SEND_CTL_MSG_XMLDOCDUMPMEMORY_FAILED;
+ }
+ } else {
+ rc = NPE_SEND_CTL_MSG_XMLCOPYNODE_FAILED;
+ }
+ } else {
+ rc = NPE_SEND_CTL_MSG_XMLNEWNODE_FAILED;
+ }
+ } else {
+ rc = NPE_SEND_CTL_MSG_XMLNEWDTD_FAILED;
+ }
+ } else {
+ rc = NPE_SEND_CTL_MSG_XMLNEWDOC_FAILED;
+ }
+ /* the signaller allocated, we free the descriptor - do we also free
+ any of the contents? */
+ g_free(descriptor);
return;
}
@@ -334,6 +472,9 @@
static void netperf_control_connect(NetperfControl *control)
{
+ GIOStatus status;
+ GError *error = NULL;
+
g_print("asked to connect control at %p\n",control);
control->sockfd = establish_control(control->remotehost,
@@ -344,7 +485,37 @@
control->localfamily);
/* REVISIT - do the g_io_channel stuff here */
-
+#ifdef G_OS_WIN32
+ control->source = g_io_channel_win32_new_socket(control->sockfd);
+#else
+ control->source = g_io_channel_unix_new(control->sockfd);
+#endif
+ status = g_io_channel_set_flags(control->source,
+ G_IO_FLAG_NONBLOCK,
+ &error);
+ if (error) {
+ g_warning("g_io_channel_set_flags %s %d %s\n",
+ g_quark_to_string(error->domain),
+ error->code,
+ error->message);
+ g_clear_error(&error);
+ }
+
+ status = g_io_channel_set_encoding(control->source,NULL,&error);
+ if (error) {
+ g_warning("g_io_channel_set_encoding %s %d %s\n",
+ g_quark_to_string(error->domain),
+ error->code,
+ error->message);
+ g_clear_error(&error);
+ }
+
+ g_io_channel_set_buffered(control->source,FALSE);
+
+ control->state = CONTROL_CONNECTED;
+ control->state_req = CONTROL_CONNECTED;
+
+
/* REVISIT this should be conditional on all the control connection stuff
being successful */
g_signal_emit_by_name(control->netserver,"control_connected");
Modified: branches/gobject_migration/src/netperf-control.h
===================================================================
--- branches/gobject_migration/src/netperf-control.h 2007-03-15 22:27:08 UTC (rev 217)
+++ branches/gobject_migration/src/netperf-control.h 2007-03-16 00:46:18 UTC (rev 218)
@@ -35,6 +35,19 @@
/* declarations to provide us with a Control object to be used by
netperf4's GObject conversion */
+/* initially I wanted to keep netperf-control free of XML, but that is
+ not terribly practical */
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+typedef struct netperf_control_msg_desc {
+ xmlNodePtr body; /* message body */
+ xmlChar *nid; /* the destination id */
+ xmlChar *fromnid; /* the source id */
+} netperf_control_msg_desc_t;
+
typedef enum netperf_control_state {
CONTROL_PREINIT,
CONTROL_CONNECTED,
@@ -94,7 +107,7 @@
GObjectClass parent_class;
/* signals */
- void (*new_message)(NetperfControl *control, gpointer message);
+ void (*message)(NetperfControl *control, gpointer message);
void (*control_closed)(NetperfControl *control);
void (*connect_control)(NetperfControl *control);
Modified: branches/gobject_migration/src/netperf-netserver.c
===================================================================
--- branches/gobject_migration/src/netperf-netserver.c 2007-03-15 22:27:08 UTC (rev 217)
+++ branches/gobject_migration/src/netperf-netserver.c 2007-03-16 00:46:18 UTC (rev 218)
@@ -1517,7 +1517,7 @@
else {
/* just what should we do if we are signaled to connect and we are
not in NETSERVER_PREINIT? */
- g_print("%s Yo! netserver at %p id %s was asked to connect when it was in state %s rather than NETSERVER_PREINIT!\n",
+ g_print("%s Yo! netserver at %p id %s was asked to connect when it was in state %d rather than NETSERVER_PREINIT!\n",
__func__,
server,
server->id,
More information about the netperf-dev
mailing list