[netperf-dev] netperf4 commit notice r219 -
branches/gobject_migration/src
raj at netperf.org
raj at netperf.org
Fri Mar 16 13:10:48 PST 2007
Author: raj
Date: 2007-03-16 13:10:47 -0800 (Fri, 16 Mar 2007)
New Revision: 219
Modified:
branches/gobject_migration/src/netlib4.c
branches/gobject_migration/src/netperf-control.c
branches/gobject_migration/src/netperf-control.h
branches/gobject_migration/src/netperf-netserver.c
branches/gobject_migration/src/netperf-netserver.h
branches/gobject_migration/src/netperf4.c
Log:
bring netservers to the INIT state
Modified: branches/gobject_migration/src/netlib4.c
===================================================================
--- branches/gobject_migration/src/netlib4.c 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netlib4.c 2007-03-16 21:10:47 UTC (rev 219)
@@ -2095,7 +2095,8 @@
gboolean
xml_parse_control_message(gchar *message, gsize length) {
- xmlDocPtr xml_message;
+ xmlDocPtr xml_doc;
+ xmlNodePtr xml_message;
gchar *key;
gboolean ret;
NetperfNetserver *netserver;
@@ -2110,7 +2111,8 @@
length,
message);
}
- if ((xml_message = xmlParseMemory(message, length)) != NULL) {
+
+ if ((xml_doc = xmlParseMemory(message, length)) != NULL) {
/* got the message, run with it */
if (debug) {
g_fprintf(where,
@@ -2118,7 +2120,7 @@
__func__,
length,
message,
- xml_message);
+ xml_doc);
}
#ifdef notdef
/* we used to see if this was the first message on the control
@@ -2131,16 +2133,33 @@
global_state->first_message = FALSE;
}
#endif
- /* extract the netserver id from the to portion of the message */
+
+ xml_message = xmlDocGetRootElement(xml_doc);
+
+ /* extract the id from the to portion of the message. if the
+ destination is "netperf" then it implies we are the netperf
+ side (should have a sanity check there at some point) which
+ means to find the netserver we really want to be looking
+ based on the fromnid, not the tonid */
+
+
key = xmlGetProp(xml_message, (const xmlChar *)"tonid");
if (NULL != key) {
/* lookup its destination and send it on its way. we need to be
certain that netserver.c has added a suitable entry to a
netperf_netserver_hash like netperf.c does. */
-
+
netserver = g_hash_table_lookup(server_hash,key);
+ if (debug) {
+ g_fprintf(where,
+ "%s found netserver at %p in the hash using %s as the key\n",
+ __func__,
+ netserver,
+ key);
+ fflush(where);
+ }
/* should this be a signal sent to the netserver object, a
method we invoke, or a property we attempt to set? I suspect
just about any of those would actually work, question is
@@ -2149,12 +2168,13 @@
here which I suppose is a good thing. REVISIT we used to call
a routine called process_message with a pointer to the server
structure and a pointer to the message */
- g_signal_emit_by_name(netserver,"new-message",xml_message);
+ g_signal_emit_by_name(netserver,"new-message",xml_doc);
/* REVISIT this - should we have a return value from the signal?
*/
ret = TRUE;
}
else {
+ g_print("YoHo! the key was null!\n");
ret = FALSE;
}
}
Modified: branches/gobject_migration/src/netperf-control.c
===================================================================
--- branches/gobject_migration/src/netperf-control.c 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netperf-control.c 2007-03-16 21:10:47 UTC (rev 219)
@@ -43,10 +43,12 @@
#include <glib-object.h>
#include <stdio.h>
#include "netperf-control.h"
+#include "netperf-netserver.h"
#include "netperf.h"
extern int debug;
extern FILE * where;
+extern GHashTable *server_hash;
enum {
CONTROL_PROP_DUMMY_0, /* GObject does not like a zero value for a property id */
@@ -59,11 +61,16 @@
CONTROL_PROP_LOCALHOST,
CONTROL_PROP_LOCALPORT,
CONTROL_PROP_LOCALFAMILY,
- CONTROL_PROP_NETSERVER
+ CONTROL_PROP_NETSERVER,
+ CONTROL_PROP_IS_NETPERF
};
/* some forward declarations to make the compiler happy regardless of
the order in which things appear in the file */
+static gboolean read_from_control_connection(GIOChannel *source,
+ GIOCondition condition,
+ gpointer data);
+
static void netperf_control_set_property(GObject *object,
guint prop_id,
const GValue *value,
@@ -139,6 +146,7 @@
GParamSpec *localport_param;
GParamSpec *localfamily_param;
GParamSpec *netserver_param;
+ GParamSpec *is_netperf_param;
/* and on with the show */
GObjectClass *g_object_class;
@@ -220,6 +228,13 @@
"pointer to the owning netserver object",
G_PARAM_READWRITE);
+ is_netperf_param =
+ g_param_spec_boolean("is_netperf",
+ "is netperf side?",
+ "is this a netperf-side control object or netserver?",
+ TRUE,
+ G_PARAM_READWRITE);
+
/* overwrite the base object methods with our own get and set
property routines */
@@ -267,6 +282,10 @@
CONTROL_PROP_NETSERVER,
netserver_param);
+ g_object_class_install_property(g_object_class,
+ CONTROL_PROP_IS_NETPERF,
+ is_netperf_param);
+
/* we would set the signal handlers for the class here. we might
have a signal say for the arrival of a complete message or
perhaps the cotnrol connection going down or somesuch. */
@@ -515,7 +534,14 @@
control->state = CONTROL_CONNECTED;
control->state_req = CONTROL_CONNECTED;
-
+ /* we need to add a watch to the main event loop so we can start
+ pulling messages from the socket */
+ control->watch_id = g_io_add_watch(control->source,
+ G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
+ read_from_control_connection,
+ control);
+ g_print("ho! adding a watch_id returned %u\n",control->watch_id);
+
/* REVISIT this should be conditional on all the control connection stuff
being successful */
g_signal_emit_by_name(control->netserver,"control_connected");
@@ -571,6 +597,10 @@
control->netserver = g_value_get_pointer(value);
break;
+ case CONTROL_PROP_IS_NETPERF:
+ control->is_netperf = g_value_get_boolean(value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -623,6 +653,10 @@
g_value_set_pointer(value, control->netserver);
break;
+ case CONTROL_PROP_IS_NETPERF:
+ g_value_set_boolean(value, control->is_netperf);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -700,7 +734,111 @@
return(FALSE);
}
-gboolean
+/* given a buffer with a complete control message, XML parse it and
+ then send it on its way. */
+static gboolean
+netperf_control_parse_message(NetperfControl *control) {
+
+ xmlDocPtr xml_doc;
+ xmlNodePtr xml_message;
+ gchar *key;
+ gboolean ret;
+ NetperfNetserver *netserver;
+
+ NETPERF_DEBUG_ENTRY(debug,where);
+
+ if (debug) {
+ g_fprintf(where,
+ "%s asked to parse %d byte message '%*s'\n",
+ __func__,
+ control->bytes_received,
+ control->bytes_received,
+ control->buffer);
+ }
+
+ if ((xml_doc = xmlParseMemory(control->buffer, control->bytes_received)) != 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__,
+ control->bytes_received,
+ control->buffer,
+ xml_doc);
+ }
+#ifdef notdef
+ /* we used to see if this was the first message on the control
+ connection, which was related to this routine being used only
+ by netserver.c and not netperf.c et al. we will have to
+ figure-out something else to do in that case. */
+ /* was this the first message on the control connection? */
+ if (global_state->first_message) {
+ allocate_netperf(source,xml_message,data);
+ global_state->first_message = FALSE;
+ }
+#endif
+
+ xml_message = xmlDocGetRootElement(xml_doc);
+
+ /* extract the id from the to portion of the message. if the
+ destination is "netperf" then it implies we are the netperf
+ side (should have a sanity check there at some point) which
+ means to find the netserver we really want to be looking
+ based on the fromnid, not the tonid */
+
+ if (control->is_netperf)
+ key = xmlGetProp(xml_message, (const xmlChar *)"fromnid");
+ else
+ key = xmlGetProp(xml_message, (const xmlChar *)"tonid");
+
+ if (NULL != key) {
+ /* lookup its destination and send it on its way. we need to be
+ certain that netserver.c has added a suitable entry to a
+ netperf_netserver_hash like netperf.c does. */
+
+ netserver = g_hash_table_lookup(server_hash,key);
+
+ if (debug) {
+ g_fprintf(where,
+ "%s found netserver at %p in the hash using %s as the key\n",
+ __func__,
+ netserver,
+ key);
+ fflush(where);
+ }
+ /* should this be a signal sent to the netserver object, a
+ method we invoke, or a property we attempt to set? I suspect
+ just about any of those would actually work, question is
+ which to use? if we start with either a signal or a property
+ we won't be dereferencing anything from the object pointer
+ here which I suppose is a good thing. REVISIT we used to call
+ a routine called process_message with a pointer to the server
+ structure and a pointer to the message */
+ g_signal_emit_by_name(netserver,"new-message",xml_doc);
+ /* REVISIT this - should we have a return value from the signal?
+ */
+ ret = TRUE;
+ }
+ else {
+ g_print("YoHo! the key was null!\n");
+ ret = FALSE;
+ }
+ }
+ else {
+ if (debug) {
+ g_fprintf(where,
+ "%s: xmlParseMemory gagged on a %d byte message at %p\n",
+ __func__,
+ control->bytes_received,
+ control->buffer);
+ }
+ ret = FALSE;
+ }
+ NETPERF_DEBUG_EXIT(debug,where);
+ return(ret);
+}
+
+static gboolean
read_from_control_connection(GIOChannel *source, GIOCondition condition, gpointer data) {
gsize bytes_read;
@@ -712,6 +850,9 @@
NETPERF_DEBUG_ENTRY(debug,where);
+ g_print("Yo! reading from control connection debug is %d where is %p\n",
+ debug,where);
+
if (debug) {
g_fprintf(where,
"%s called with source %p condition %x and data %p\n",
@@ -851,15 +992,13 @@
/* make sure we are NULL terminated just in case someone tries
to print it as a string or something. */
control_object->buffer[control_object->bytes_received] = '\0';
- /* xml_parse_control_message, from netlib, will attempt to
- convert the buffer into an XML document and will then parse
- it to find the correct destination. we have it in netlib
- because we don't want no stinkin XML here in the control
- object code :) */
- ret = xml_parse_control_message(control_object->buffer,
- control_object->bytes_received,
- data,
- source);
+
+ /* should we be "signaling" here or just go ahead and pretend
+ that this routing is control object code anyway - might as
+ well for the time being */
+
+ ret = netperf_control_parse_message(control_object);
+
/* let us not forget to reset our control_object shall we? we
don't really want to re-parse the same message over and over
again... raj 2006-03-22 */
Modified: branches/gobject_migration/src/netperf-control.h
===================================================================
--- branches/gobject_migration/src/netperf-control.h 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netperf-control.h 2007-03-16 21:10:47 UTC (rev 219)
@@ -72,6 +72,8 @@
control_state_t state; /* the present state of the control */
control_state_t state_req; /* the state in which we want the control
to be*/
+ gboolean is_netperf; /* are we a netperf-side control object or
+ netserver-side control object? */
gchar *remotehost;
gchar *remoteport;
gchar *localhost;
@@ -85,6 +87,8 @@
GIOChannel *source; /* the io channel over which we communicate
with the remote control. */
+ guint watch_id; /* the id of the channel watch we ahve
+ installed to pull things from the control channel */
int sockfd; /* REVISIT the file descriptor associated with the
socket. THIS NEEDS TO CHANGE TO "SOCKET" ASAP */
Modified: branches/gobject_migration/src/netperf-netserver.c
===================================================================
--- branches/gobject_migration/src/netperf-netserver.c 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netperf-netserver.c 2007-03-16 21:10:47 UTC (rev 219)
@@ -137,7 +137,8 @@
NETSERVER_PROP_STATE,
NETSERVER_PROP_REQ_STATE,
NETSERVER_PROP_NODE,
- NETSERVER_PROP_CONTROL_CONNECTION
+ NETSERVER_PROP_CONTROL_CONNECTION,
+ NETSERVER_PROP_IS_NETPERF
};
/* some forward declarations to make the compiler happy regardless of
@@ -214,6 +215,7 @@
GParamSpec *id_param;
GParamSpec *control_connection_param;
GParamSpec *node_param;
+ GParamSpec *is_netperf_param;
/* and on with the show */
GObjectClass *g_object_class;
@@ -261,6 +263,13 @@
"XML configuration node",
G_PARAM_READWRITE);
+ is_netperf_param =
+ g_param_spec_boolean("is_netperf",
+ "is on netperf",
+ "is this netserver on a netperf or a netserver?",
+ TRUE,
+ G_PARAM_READWRITE);
+
/* overwrite the base object methods with our own get and set
property routines */
@@ -288,6 +297,10 @@
NETSERVER_PROP_NODE,
node_param);
+ g_object_class_install_property(g_object_class,
+ NETSERVER_PROP_IS_NETPERF,
+ is_netperf_param);
+
/* we would set the signal handlers for the class here. we might
have a signal say for the arrival of a complete message or
perhaps the cotnrol connection going down or somesuch. */
@@ -413,13 +426,15 @@
if (server != NULL) cur_state = 1 << server->state;
if (debug) {
- fprintf(where,"process_message: received '%s' message from server %s\n",
+ fprintf(where,"%s: received '%s' message from server %s\n",
+ __func__,
msg->xmlChildrenNode->name, fromnid);
- fprintf(where,"process_message: servers current state is %d\n", cur_state);
+ fprintf(where,"%s: servers current state is %d\n", __func__, cur_state);
fflush(where);
}
for (cur = msg->xmlChildrenNode; cur != NULL; cur = cur->next) {
which_msg = server->message_state_table;
+ g_print("message_state_table %p\n",server->message_state_table);
while (which_msg->msg_name != NULL) {
if (xmlStrcmp(cur->name,(xmlChar *)which_msg->msg_name)) {
which_msg++;
@@ -428,7 +443,8 @@
if (which_msg->valid_states & cur_state) {
rc = (which_msg->msg_func)(cur,doc,server);
if (rc != NPE_SUCCESS) {
- fprintf(where,"process_message: received %d from %s\n",
+ fprintf(where,"%s: received %d from %s\n",
+ __func__,
rc, which_msg->msg_name);
fflush(where);
server->state = NSRV_ERROR;
@@ -444,7 +460,8 @@
} else {
if (debug || loc_debug) {
fprintf(where,
- "process_message:state is %d got unexpected '%s' message.\n",
+ "%s :state is %d got unexpected '%s' message.\n",
+ __func__,
cur_state,
cur->name);
fflush(where);
@@ -481,6 +498,8 @@
fflush(where);
}
rc = NPE_SUCCESS;
+ server->state = NETSERVER_INIT;
+ server->state_req = NETSERVER_WORK; /* is this correct? */
} else {
/* versions don't match */
if (debug) {
@@ -504,6 +523,7 @@
int rc = NPE_SUCCESS;
xmlNodePtr message;
+ netperf_control_msg_desc_t *desc;
if ((message = xmlNewNode(NULL,(xmlChar *)"version")) != NULL) {
/* set the properties of the version message -
@@ -512,19 +532,31 @@
(xmlSetProp(message,(xmlChar *)"updt",NETPERF_UPDATE) != NULL) &&
(xmlSetProp(message,(xmlChar *)"fix", NETPERF_FIX) != NULL)) {
/* still smiling */
- /* almost there... */
- rc = write_to_control_connection(server->source,
- message,
- server->id,
- fromnid);
- if (rc != NPE_SUCCESS) {
- if (debug) {
- fprintf(where,
- "send_version_message: write_to_control_connection failed\n");
- fflush(where);
- }
- }
- } else {
+ /* almost there... build a descriptor to avoid having a three
+ argmuent marshaller for a signal and just leverage the
+ existing one for a pointer :) the control object will be
+ responsible for freeing the fields of the desc as well as the
+ desc itself - while the "signal" since it has a return code
+ implies a procedure call, later the control object may
+ decided to queue something so we best not mess with things
+ behind its back */
+
+ desc = g_malloc(sizeof(netperf_control_msg_desc_t));
+ desc->body = message;
+ /* should this be a copy using glib, or libxml2 routines? */
+ desc->nid = g_strdup(server->id);
+ desc->fromnid = g_strdup(fromnid);
+
+ server->state = NETSERVER_VERS;
+ server->state_req = NETSERVER_VERS;
+
+ /* now tell the control object to send the thing. perhaps one of
+ these days we'll have a return value :) */
+ g_signal_emit_by_name(server->control_object,
+ "message", desc);
+
+ }
+ else {
if (debug) {
fprintf(where,
"send_version_message: an xmlSetProp failed\n");
@@ -532,8 +564,11 @@
}
rc = NPE_SEND_VERSION_XMLSETPROP_FAILED;
}
- /* now that we are done with it, best to free the message node */
- xmlFreeNode(message);
+ /* now that we are done with it, best to free the message
+ node. however, that needs to be done by the control object now
+ because that will be the thing that "knows" when it is finished
+ with it */
+ /* xmlFreeNode(message); */
}
else {
if (debug) {
@@ -1506,6 +1541,7 @@
"localhost", localhost,
"localport", localport,
"netserver", server,
+ "is_netperf", TRUE,
NULL);
/* set our desired state correctly so when we receive the signal
we are connected the right things can happen */
@@ -1539,6 +1575,9 @@
netserver->state = NETSERVER_CONNECTED;
/* REVISIT - do we need to make sure that netserver->state_req is
suitably set? */
+ /* probably need to get rid of the constant string one of these
+ days */
+ send_version_message(netserver,"netperf");
}
else {
g_print("%s received unexpected control_connected signal for server %p id %s\n",
@@ -1660,6 +1699,15 @@
netserver->node = g_value_get_pointer(value);
break;
+ case NETSERVER_PROP_IS_NETPERF:
+ netserver->is_netperf = g_value_get_boolean(value);
+ if (netserver->is_netperf)
+ netserver->message_state_table = NP_Msgs;
+ else
+ netserver->message_state_table = NS_Msgs;
+ g_print("setting netservers is_netperf property to %p\n",netserver->message_state_table);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -1696,6 +1744,9 @@
g_value_set_pointer(value, netserver->node);
break;
+ case NETSERVER_PROP_IS_NETPERF:
+ g_value_set_boolean(value, netserver->is_netperf);
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
Modified: branches/gobject_migration/src/netperf-netserver.h
===================================================================
--- branches/gobject_migration/src/netperf-netserver.h 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netperf-netserver.h 2007-03-16 21:10:47 UTC (rev 219)
@@ -83,18 +83,21 @@
gchar *my_nid; /* an identifier used by netserver? */
+
GIOChannel *source; /* the io channel over which we communicate
with the remote netserver. should this
instead be a weak reference to a control
connection object? */
+
xmlNodePtr node; /* the XML document node containing the
servers configuration data */
netserver_state_t state; /* the present state of the netserver */
netserver_state_t state_req; /* the state in which we want the netserver
to be*/
-
+ gboolean is_netperf; /* is this netserver on a netperf or a
+ netserver */
gint err_rc; /* error code received which caused this
server to enter the NETSERVER_ERROR state */
char *err_fn; /* name of the routine which placed this
Modified: branches/gobject_migration/src/netperf4.c
===================================================================
--- branches/gobject_migration/src/netperf4.c 2007-03-16 00:46:18 UTC (rev 218)
+++ branches/gobject_migration/src/netperf4.c 2007-03-16 21:10:47 UTC (rev 219)
@@ -912,6 +912,7 @@
new_server = g_object_new(TYPE_NETPERF_NETSERVER,
"id", netserverid,
"node", this_netserver,
+ "is_netperf", TRUE,
NULL);
if (new_server != NULL) { /* we have a new netserver object,
lets add it to the server_hash */
More information about the netperf-dev
mailing list