[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