[netperf-dev] netperf4 commit notice r205 - branches/gobject_migration/src

raj at netperf.org raj at netperf.org
Thu Mar 8 16:44:51 PST 2007


Author: raj
Date: 2007-03-08 16:44:49 -0800 (Thu, 08 Mar 2007)
New Revision: 205

Modified:
   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/netperf-test.c
   branches/gobject_migration/src/netperf-test.h
   branches/gobject_migration/src/netperf.c
Log:
the journey of a thousand mods continues with a few more steps

Modified: branches/gobject_migration/src/netperf-control.c
===================================================================
--- branches/gobject_migration/src/netperf-control.c	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-control.c	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,3 +1,35 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif

Modified: branches/gobject_migration/src/netperf-control.h
===================================================================
--- branches/gobject_migration/src/netperf-control.h	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-control.h	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,3 +1,35 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
 #ifndef NETPERF_CONTROL_H
 #define NETPERF_CONTROL_H
 /* declarations to provide us with a Control object to be used by

Modified: branches/gobject_migration/src/netperf-netserver.c
===================================================================
--- branches/gobject_migration/src/netperf-netserver.c	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-netserver.c	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,11 +1,55 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <glib-object.h>
+
+#ifdef HAVE_STDIO_H
 #include <stdio.h>
+#endif
+
+#include "netperf.h"
+#include "netlib.h"
 #include "netperf-netserver.h"
+#include "netperf-test.h"
 
 /* perhaps one of these days, these should become properties of a
    NetperfNetserver? */
 extern int debug;
 extern FILE *where;
+extern GHashTable *test_hash;
 
 static int clear_stats_message(xmlNodePtr msg, xmlDocPtr doc, NetperfNetserver *server);
 static int clear_sys_stats_message(xmlNodePtr msg, xmlDocPtr doc, NetperfNetserver *server);
@@ -82,7 +126,8 @@
   NETSERVER_PROP_DUMMY_0,    /* GObject does not like a zero value for a property id */
   NETSERVER_PROP_ID,
   NETSERVER_PROP_STATE,
-  NETSERVER_PROP_REQ_STATE
+  NETSERVER_PROP_REQ_STATE,
+  NETSERVER_PROP_CONTROL_CONNECTION
 };
 
 /* some forward declarations to make the compiler happy regardless of
@@ -106,7 +151,10 @@
   CONTROL_CLOSED,     /* this would be the control connection object
 			 telling us the controll connection died. */
   LAST_SIGNAL         /* this should always be the last in the list so
-			 we can use it to size the array correctly. */
+			 we can use it to size the array correctly. of
+			 course, we may never actually use the array,
+			 but the tutorial code from which we are
+			 working happened to do so... */
 };
 
 static void netperf_netserver_new_message(NetperfNetserver *netserver, gpointer message);
@@ -150,6 +198,7 @@
   GParamSpec *state_param;
   GParamSpec *req_state_param;
   GParamSpec *id_param;
+  GParamSpec *control_connection_param;
 
   /* and on with the show */
   GObjectClass *g_object_class;
@@ -182,6 +231,15 @@
 			"unnamed",    /* default value */
 			G_PARAM_READWRITE);
 
+  control_connection_param =
+    g_param_spec_pointer("control_connection", /* used to setup a weak
+						  pointer to the
+						  control connection
+						  object */
+			 "control connection",
+			 "the control connection this netserver should use",
+			 G_PARAM_READWRITE);
+
   /* overwrite the base object methods with our own get and set
      property routines */
 
@@ -201,6 +259,10 @@
 				  NETSERVER_PROP_ID,
 				  id_param);
 
+  g_object_class_install_property(g_object_class,
+				  NETSERVER_PROP_CONTROL_CONNECTION,
+				  control_connection_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. */
@@ -246,7 +308,7 @@
   xmlChar *fromnid;
   xmlNodePtr msg;
   xmlNodePtr cur;
-  struct msgs *which_msg;
+  struct netperf_msgs *which_msg;
 
   NETPERF_DEBUG_ENTRY(debug,where);
 
@@ -270,7 +332,7 @@
     fflush(where);
   }
   for (cur = msg->xmlChildrenNode; cur != NULL; cur = cur->next) {
-    which_msg = np_msg_handler_base;
+    which_msg = server->message_state_table;
     while (which_msg->msg_name != NULL) {
       if (xmlStrcmp(cur->name,(xmlChar *)which_msg->msg_name)) {
         which_msg++;
@@ -283,11 +345,14 @@
                   rc, which_msg->msg_name);
           fflush(where);
           server->state = NSRV_ERROR;
-          if (server->sock != -1) {
-            CLOSE_SOCKET(server->sock);
+	  /* REVISIT this is where we would likely tell the control
+	     connection object that it should go away */
+	  /* some sort of object signal to the control connection, or
+	     perhaps a property set or a method invokation off of
+	     server->control_connection - after making sure it is
+	     non-NULL of course... */
             /* should we delete the server from the server_hash ? sgb */
-            break;
-          }
+	  break;
         }
       } else {
         if (debug || loc_debug) {
@@ -436,20 +501,33 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
+  /* since this is not really the test object file, it really
+     shouldn't be accessing some of these things directly? */
   if (test != NULL) {
     if (debug) {
+      gint state,state_req = -1;
+      g_object_get(test,
+		   "state", &state,
+		   "req-state", &state_req,
+		   NULL);
       fprintf(where,"%s: tid = %s  prev_state_req = %d ",
-              __func__, testid, test->state_req);
+              __func__, testid, state_req);
       fflush(where);
     }
     test->state_req = TEST_DEAD;
+    g_object_set(test,
+		 "req-state", TEST_DEAD,
+		 NULL);
     if (debug) {
-      fprintf(where," new_state_req = %d\n",test->state_req);
+      fprintf(where,
+	      "%s requested tid %s to enter TEST_DEAD\n",
+	      __func__,
+	      testid);
       fflush(where);
     }
   }
@@ -461,11 +539,11 @@
 dead_message(xmlNodePtr msg, xmlDocPtr doc, NetperfNetserver *server)
 {
   xmlChar    *testid;
-  test_t     *test;
+  NetperfTest    *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"%s: tid = %s  prev_state_req = %d ",
@@ -488,11 +566,11 @@
   int loc_debug = 0;
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug || loc_debug) {
       fprintf(where,"error_message: prev_state_req = %d ",test->state_req);
@@ -502,7 +580,12 @@
     test->err_fn  = (char *)xmlGetProp(msg,(const xmlChar *)"err_fn");
     test->err_str = (char *)xmlGetProp(msg,(const xmlChar *)"err_str");
     test->err_no  = atoi((char *)xmlGetProp(msg,(const xmlChar *)"err_no"));
-    test->state   = TEST_ERROR;
+    /* test->state   = TEST_ERROR; the stuff above should probably be
+       using a property set too...*/
+    g_object_set(test,
+		 "req-state", TEST_ERROR,
+		 NULL);
+
     if (debug || loc_debug) {
       fprintf(where," new_state_req = %d\n",test->state_req);
       fprintf(where,"\terr in test function %s  rc = %d\n",
@@ -521,11 +604,11 @@
 {
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,
@@ -552,11 +635,11 @@
 {
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,
@@ -584,12 +667,12 @@
 {
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
   xmlNodePtr  stats;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"get_stats_message: test_state = %d\n",test->state);
@@ -618,12 +701,12 @@
 {
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
   xmlNodePtr  sys_stats;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"%s: test_state = %d ",
@@ -653,45 +736,30 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
-  int        hash_value;
+  NetperfTest   *test;
 
-
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
 
-  hash_value = TEST_HASH_VALUE(testid);
+  test = g_hash_table_lookup(test_hash,(gchar *) testid);
 
-  /* don't forget to add error checking one day */
-  if (debug) {
-    fprintf(where,"np_idle_message: waiting for mutex\n");
-    fflush(where);
-  }
-  NETPERF_MUTEX_LOCK(test_hash[hash_value].hash_lock);
-
-  test = test_hash[hash_value].test;
-  while (test != NULL) {
-    if (!xmlStrcmp(test->id,testid)) {
-      /* we have a match */
-      break;
-    }
-    test = test->next;
-  }
-
+  /* REVISIT - this should use netperftest object property calls */
   if (test != NULL) {
+    gint prev_state = -1;
+    g_object_get(test,
+		 "state", &prev_state,
+		 NULL);
     if (debug) {
-      fprintf(where,"np_idle_message: prev_state = %d ",test->state);
+      fprintf(where,"%s: prev_state = %d ",__func__,test->state);
       fflush(where);
     }
-    test->state = TEST_IDLE;
-    /* I'd have liked to have abstracted this with the NETPERF_mumble
-       macros, but the return values differ. raj 2006-03-02 */
-    g_cond_broadcast(test_hash[hash_value].condition);
+    /* when we set the state to TEST_IDLE, we expect that the property
+       setting code will walk a list of dependent tests to inform them
+       of the state change of this test. */
+    g_object_set(test,
+		 "state", TEST_IDLE,
+		 NULL);
   }
-  if (debug) {
-    fprintf(where,"np_idle_message: unlocking mutex\n");
-    fflush(where);
-  }
-  NETPERF_MUTEX_UNLOCK(test_hash[hash_value].hash_lock);
+
   return(rc);
 }
 
@@ -700,20 +768,26 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"idle_message: tid = %s  prev_state_req = %d ",
               testid, test->state_req);
       fflush(where);
     }
-    test->state_req = TEST_IDLE;
+    g_object_set(test,
+		 "req-state", TEST_IDLE,
+		 NULL);
+
     if (debug) {
-      fprintf(where," new_state_req = %d\n",test->state_req);
+      fprintf(where,
+	      "%s has set the state of test %p to TEST_IDLE\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -725,20 +799,33 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
-      fprintf(where,"idled_message: tid = %s  prev_state_req = %d ",
-              testid, test->state_req);
+      gint state_req = -1;
+      g_object_get(test,
+		   "req-state", &state_req,
+		   NULL);
+      fprintf(where,
+	      "%s: tid = %s  prev_state_req = %d ",
+	      __func__,
+              testid,
+	      state_req);
       fflush(where);
     }
+    g_object_set(test,
+		 "state", TEST_IDLE,
+		 NULL);
     test->state = TEST_IDLE;
     if (debug) {
-      fprintf(where," new_state_req = %d\n",test->state_req);
+      fprintf(where,
+	      "%s requested test %p enter TEST_IDLE\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -796,7 +883,7 @@
   int        rc = NPE_SUCCESS;
   xmlNodePtr dependency_data;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
   int        hash_value;
 
 
@@ -809,20 +896,8 @@
     }
   }
   
-  hash_value = TEST_HASH_VALUE(testid);
+  test = g_hash_table_lookup(test_hash, (gchar *)testid);
 
-  /* don't forget to add error checking one day */
-  NETPERF_MUTEX_LOCK(test_hash[hash_value].hash_lock);
-
-  test = test_hash[hash_value].test;
-  while (test != NULL) {
-    if (!xmlStrcmp(test->id,testid)) {
-      /* we have a match */
-      break;
-    }
-    test = test->next;
-  }
-
   if (test != NULL) {
     if (debug) {
       fprintf(where,"initialized_message: prev_state = %d ",test->state);
@@ -831,28 +906,40 @@
     if (dependency_data != NULL) {
       test->dependent_data = xmlCopyNode(dependency_data,1);
       if (test->dependent_data != NULL) {
-        test->state = TEST_INIT;
+	g_object_set(test,
+		     "state", TEST_INIT,
+		     NULL);
       } else {
-        test->state = TEST_ERROR;
+	g_object_set(test,
+		     "state", TEST_ERROR,
+		     NULL);
         /* add additional error information later */
       }
     } else {
-      test->state = TEST_INIT;
+      g_object_set(test,
+		   "state", TEST_INIT,
+		   NULL);
     }
 
-    /* since the different cond broadcast calls return different
-       things, we cannot use the nice NETPERF_mumble abstractions. */
+    /* this is where there would be a netperftest property setting
+       call - above to set the state, and so no more condition
+       variable stuff */
 
-    g_cond_broadcast(test_hash[hash_value].condition);
-
-
     if (debug) {
-      fprintf(where," new_state = %d rc = %d\n",test->state,rc);
+      gint state = -1;
+      g_object_get(test,
+		   "state",&state,
+		   NULL);
+      fprintf(where,"%s test %p new_state = %d rc = %d\n",
+	      __func__,
+	      test,
+	      state,
+	      rc);
       fflush(where);
     }
 
   }
-  NETPERF_MUTEX_UNLOCK(test_hash[hash_value].hash_lock);
+
   return(rc);
 }
 
@@ -862,20 +949,24 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"load_message: tid = %s  prev_state_req = %d ",
               testid, test->state_req);
       fflush(where);
     }
-    test->state_req = TEST_LOADED;
+    g_object_set(test,
+		 "req-state",TEST_LOADED,
+		 NULL);
     if (debug) {
-      fprintf(where," new_state_req = %d\n",test->state_req);
+      fprintf(where,"%s requested test %p enter state TEST_LOADED\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -887,19 +978,23 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"loaded_message: prev_state = %d ",test->state);
       fflush(where);
     }
-    test->state = TEST_LOADED;
+    g_object_set(test,
+		 "state", TEST_LOADED,
+		 NULL);
     if (debug) {
-      fprintf(where," new_state = %d\n",test->state);
+      fprintf(where,"%s requested test %p enter TEST_LOADED\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -912,19 +1007,23 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"measure_message: prev_state_req = %d ",test->state_req);
       fflush(where);
     }
-    test->state_req = TEST_MEASURE;
+    g_object_set(test,
+		 "req-state", TEST_MEASURE,
+		 NULL);
     if (debug) {
-      fprintf(where," new_state_req = %d\n",test->state_req);
+      fprintf(where,"%s requested test %p enter TEST_MEASURE\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -936,18 +1035,22 @@
 {
   int        rc = NPE_SUCCESS;
   xmlChar   *testid;
-  test_t    *test;
+  NetperfTest   *test;
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
     if (debug) {
       fprintf(where,"measuring_message: prev_state = %d ",test->state);
       fflush(where);
     }
-    test->state = TEST_MEASURE;
+    g_object_set(test,
+		 "state", TEST_MEASURE,
+		 NULL);
     if (debug) {
-      fprintf(where," new_state = %d\n",test->state);
+      fprintf(where,"%s test %p entered TEST_MEASURE state\n",
+	      __func__,
+	      test);
       fflush(where);
     }
   }
@@ -960,7 +1063,7 @@
 {
   int        rc = NPE_SUCCESS;
   int        rc2;
-  test_t    *new_test;
+  NetperfTest   *new_test;
   xmlNodePtr test_node;
   xmlChar   *testid;
   xmlChar   *loc_type = NULL;
@@ -985,18 +1088,18 @@
       continue;
     }
     testid = xmlGetProp(test_node,(const xmlChar *)"tid");
-    new_test = (test_t *)malloc(sizeof(test_t));
-    if (new_test != NULL) { /* we have a new test_t structure */
-      memset(new_test,0,sizeof(test_t));
-      new_test->node      = test_node;
-      new_test->id        = testid;
-      new_test->server_id = server->id;
-      new_test->state     = TEST_PREINIT;
-      new_test->new_state = TEST_PREINIT;
-      new_test->state_req = TEST_IDLE;
-      new_test->debug     = debug;
-      new_test->where     = where;
-      rc = get_test_function(new_test,(const xmlChar *)"test_name");
+    new_test = g_object_new(TYPE_NETPERF_TEST,
+			    "node", test_node,
+			    "id", testid,
+			    "server_id", server->id,
+			    "state", NP_TST_PREINIT,
+			    "new_state", NP_TST_PREINIT,
+			    "req-state", NP_TST_IDLE,
+			    "debug", debug,
+			    "where", where,
+			    NULL);
+    if (new_test != NULL) { /* we have a new test_t object */
+      /* REVISIT we need to set the function pointers too */
       if (rc == NPE_SUCCESS) {
         rc = get_test_function(new_test,(const xmlChar *)"test_clear");
       }
@@ -1011,12 +1114,15 @@
       rc = NPE_MALLOC_FAILED2;
     }
     if (rc == NPE_SUCCESS) {
-      rc = add_test_to_hash(new_test);
+      g_hash_table_replace(test_hash,
+			   testid,
+			   new_test);
     }
     if (rc == NPE_SUCCESS) {
       if (debug) {
         fprintf(where,
-                "test_message: launching test thread using func %p\n",
+                "%s: launching test thread using func %p\n",
+		__func__,
                 new_test->test_func);
         fflush(where);
       }
@@ -1043,10 +1149,14 @@
 				 where);
 	}
 
-	rc = launch_thread(&new_test->thread_id,launch_pad,launch_state);
+	/* signal the test object it is time to launch the test thread */
+	g_signal_emit_by_name(new_test,
+			      "launch_thread");
 	if (debug) {
 	  fprintf(where,
-		  "test_message: launched test thread\n");
+		  "%s: requested launch of the  test thread for test %p\n",
+		  __func__,
+		  new_test);
 	  fflush(where);
 	}
 	/* having launched the test thread, we really aught to unbind
@@ -1058,19 +1168,24 @@
     }
 
     /* wait for test to initialize, then we will know that it's native
-       thread id has been set in the test_t */
+       thread id has been set in the NetperfTest. the sleep is
+       something of a kludge we should probably revisit the
+       notification mechanism at some point. perhaps we will use a
+       signal from the test object back to the netserver object. */
     if (rc == NPE_SUCCESS) {
       while (new_test->new_state == TEST_PREINIT) {
         if (debug) {
           fprintf(where,
-                  "test_message: waiting on thread\n");
+                  "%s: waiting on thread\n",
+		  __func__);
           fflush(where);
         }
         g_usleep(1000000);
       }  /* end wait */
       if (debug) {
         fprintf(where,
-                "test_message: test initialization finished on thread\n");
+                "%s: test initialization finished on thread\n",
+		__func__);
         fflush(where);
       }
     }
@@ -1085,7 +1200,25 @@
 	/* we use rc2 because we aren't going to fail the run if the
 	   affinity didn't work, but eventually we should emit some
 	   sort of warning */
-        rc2 = set_test_locality(new_test, (char *)loc_type, (char *)loc_value);
+	/* what sort of mechanism should we use here?  we want to have
+	   the test thread bound to a specific CPU, and the
+	   netlib_mumble.c set_thread_locality routine will want to
+	   know about the test's debug and where settings. should we
+	   set loc_type and loc_value as properties, should we pass
+	   them as a signal, or should we invoke a method? too many
+	   choices. for now we will use g_object_set to set the
+	   loc_type and loc_value, and once both those are set the
+	   test object code will make the call to
+	   set_thread_locality. however, the logic might actually be
+	   cleaner if we were to use a signal - we could pass both of
+	   them at the same time rather than the one at a time setting
+	   of a property. */
+	g_object_set(new_test,
+		     "loc_type", loc_type,
+		     "loc_value", loc_value,
+		     NULL);
+	/* and now we as the launching thread, want to go back to
+	   where we were before. */
 	rc2 = clear_own_locality((char *)loc_type,debug,where);
       }
       /* however, at this point we need to be sure to free loc_type
@@ -1103,9 +1236,12 @@
     }
 
     if (rc != NPE_SUCCESS) {
-      new_test->state  = TEST_ERROR;
-      new_test->err_rc = rc;
-      new_test->err_fn = (char *)__func__;
+      /* REVISIT - what culls this test later? */
+      g_object_set(new_test,
+		   "state", NP_TST_ERROR,
+		   "err_rc", rc,
+		   "err_fn", (char *)__func__,
+		   NULL);
       rc = NPE_TEST_INIT_FAILED;
       break;
     }
@@ -1124,11 +1260,11 @@
   int          loc_debug = 0;
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
   xmlNodePtr  stats = NULL;
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (debug || loc_debug) {
     fprintf(where,"sys_stats_message: test = %p\n",test);
     fflush(where);
@@ -1146,12 +1282,14 @@
       stats = xmlCopyNode(msg,1);
       xmlAddChild(test->received_stats, stats);
       if (debug || loc_debug) {
-        fprintf(where,"sys_stats_message: stats to list %p\n",
+        fprintf(where,"%s: stats to list %p\n",
+		__func__,
                 test->received_stats->xmlChildrenNode);
         fflush(where);
       }
     }
     if (stats == NULL) {
+      /* REVISIT - this needs some g_object_set() magic */
       test->state  = TEST_ERROR;
       test->err_rc = NPE_SYS_STATS_DROPPED;
       test->err_fn = (char *)__func__;
@@ -1165,13 +1303,14 @@
 {
   int          rc = NPE_SUCCESS;
   xmlChar     *testid;
-  test_t      *test;
+  NetperfTest     *test;
   xmlNodePtr  stats = NULL;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
-  test   = find_test_in_hash(testid);
+  test   = g_hash_table_lookup(test_hash,(gchar *)testid);
   if (test != NULL) {
+    /* REVISIT this needs some g_object_get() magic */
     if (debug) {
       fprintf(where,"test_stats_message: test_state = %d\n",test->state);
       fflush(where);
@@ -1184,6 +1323,7 @@
       xmlAddChild(test->received_stats, stats);
     }
     if (stats == NULL) {
+      /* REVISIT - this needs some g_object_set() magic */
       test->state  = TEST_ERROR;
       test->err_rc = NPE_TEST_STATS_DROPPED;
       test->err_fn = (char *)__func__;
@@ -1234,6 +1374,7 @@
 					   GParamSpec *pspec) {
   NetperfNetserver *netserver;
   guint req_state;
+  void *temp_ptr;
 
   netserver = NETPERF_NETSERVER(object);
 
@@ -1252,6 +1393,11 @@
     netserver->id = g_value_dup_string(value);
     break;
 
+  case NETSERVER_PROP_CONTROL_CONNECTION:
+    temp_ptr = g_value_get_pointer(value);
+    g_object_add_weak_pointer(temp_ptr,&(netserver->control_connection));
+    break;
+
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     break;
@@ -1281,6 +1427,10 @@
     g_value_set_string(value, netserver->id);
     break;
 
+  case NETSERVER_PROP_CONTROL_CONNECTION:
+    g_value_set_pointer(value, netserver->control_connection);
+    break;
+
   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-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-netserver.h	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,3 +1,35 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
 #ifndef NETPERF_NETSERVER_H
 #define NETPERF_NETSERVER_H
 
@@ -80,6 +112,10 @@
 
   /* do we need to have references to the test instances associated
      with this netserver instance? */
+
+  /* we do want a weak pointer for the control object */
+  void *control_connection;
+
 };
 
 /* second, the class structure, which is where we will put any method

Modified: branches/gobject_migration/src/netperf-test.c
===================================================================
--- branches/gobject_migration/src/netperf-test.c	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-test.c	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,3 +1,47 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
 #include <glib-object.h>
 #include <stdio.h>
 #include "netperf-test.h"
@@ -37,6 +81,8 @@
 			 telling us the controll connection died. */
   DEPENDENCY_MET,     /* we receive this when the test on which we are
 			 dependant has finished initializing */
+  LAUNCH_THREAD,      /* ask the object to launch a thread to run the
+			 actual test code */
   LAST_SIGNAL         /* this should always be the last in the list so
 			 we can use it to size the array correctly. */
 };
@@ -44,11 +90,12 @@
 static void netperf_test_new_message(NetperfTest *test, gpointer message);
 static void netperf_test_control_closed(NetperfTest *test);
 static void netperf_test_dependency_met(NetperfTest *test);
+static void netperf_test_launch_thread(NetperfTest *test);
 
 /* a place to stash the id's returned by g_signal_new should we ever
    need to refer to them by their ID. */ 
 
-static guint netperf_test_signals[LAST_SIGNAL] = {0,0};
+static guint netperf_test_signals[LAST_SIGNAL] = {0,0,0,0};
 
 GType netperf_test_get_type(void) {
   static GType netperf_test_type = 0;
@@ -213,6 +260,7 @@
   klass->new_message = netperf_test_new_message;
   klass->control_closed = netperf_test_control_closed;
   klass->dependency_met = netperf_test_dependency_met;
+  klass->launch_thread = netperf_test_launch_thread;
 
   netperf_test_signals[NEW_MESSAGE] = 
     g_signal_new("new_message",            /* signal name */
@@ -252,6 +300,16 @@
 		 G_TYPE_NONE,
 		 0);
 
+  netperf_test_signals[LAUNCH_THREAD] =
+    g_signal_new("launch_thread",
+		 TYPE_NETPERF_TEST,
+		 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+		 G_STRUCT_OFFSET(NetperfTestClass, launch_thread),
+		 NULL,
+		 NULL,
+		 g_cclosure_marshal_VOID__VOID,
+		 G_TYPE_NONE,
+		 0);
 }
 
 /* signal handler for new message */
@@ -288,6 +346,105 @@
   return;
 }
 
+
+/* this routine exists because there is no architected way to get a
+   "native" thread id out of a GThread.  we need a native thread ID to
+   allow the main netserver thread to bind a test thread to a
+   specified CPU/processor set/locality domain. so, we use the
+   launch_pad routine to allow the newly created thread to store a
+   "pthread_self" into the test structure. the netserver thread, when
+   it see's the test thread is in the idle state can then assign the
+   affinity to the thread. raj 2006-03-30 */
+
+void *
+netperf_test_launch_pad(NetperfTest *test) {
+
+  NETPERF_DEBUG_ENTRY(test->debug,test->where);
+
+#ifdef G_THREADS_IMPL_POSIX
+  /* hmm, I wonder if I have to worry about alignment */
+#ifdef _AIX
+  /* bless its heart, AIX wants its CPU binding routine to be given a
+     kernel thread ID and not a pthread id.  isn't that special. */
+  test->native_thread_id_ptr = malloc(sizeof(tid_t));
+  if (test->native_thread_id_ptr) {
+    *(tid_t *)(test->native_thread_id_ptr) = thread_self();
+  }
+  if (debug) {
+    fprintf(where,"%s my thread id is %d\n",__func__,thread_self());
+    fflush(where);
+  }
+#elif defined(__sun)
+#include <sys/lwp.h>
+  /* well, bless _its_ heart, Solaris wants something other than a
+     pthread_id for its binding calls too.  isn't that special... raj
+     2006-06-28 */
+  test->native_thread_id_ptr = malloc(sizeof(lwpid_t));
+  if (test->native_thread_id_ptr) {
+    *(lwpid_t *)(test->native_thread_id_ptr) = _lwp_self();
+  }
+  if (test->debug) {
+    fprintf(where,"%s my thread id is %d\n",__func__,_lwp_self());
+    fflush(where);
+  }
+#else
+#include <pthread.h>
+  test->native_thread_id_ptr = malloc(sizeof(pthread_t));
+  if (test->native_thread_id_ptr) {
+    *(pthread_t *)(test->native_thread_id_ptr) = pthread_self();
+  }
+  if (test->debug) {
+    fprintf(test->where,"%s my thread id is %ld\n",__func__,pthread_self());
+    fflush(test->where);
+  }
+#endif
+#else
+#ifdef __sun
+#include <sys/lwp.h>
+  /* well, bless _its_ heart, Solaris wants something other than a
+     pthread_id for its binding calls too.  isn't that special...  No,
+     your eyes are not deceiving you - this code is appearing in two
+     places because it would seem that glib-2.0 on Solaris may be
+     compiled using Sun's old threads stuff rather than pthreads. raj
+     2006-06-28 */
+  test->native_thread_id_ptr = malloc(sizeof(lwpid_t));
+  if (test->native_thread_id_ptr) {
+    *(lwpid_t *)(test->native_thread_id_ptr) = _lwp_self();
+  }
+  if (test->debug) {
+    fprintf(test->where,"%s my thread id is %d\n",__func__,_lwp_self());
+    fflush(test->where);
+  }
+#else
+  test->native_thread_id_ptr = NULL;
+#endif
+#endif
+  /* and now, call the routine we really want to run. at some point we
+     should bring those values onto the stack so we can free the
+     thread_launch_state_t I suppose. */
+  return (test->test_func)(test);
+}
+
+/* I would have used the NETPERF_THREAD_T abstraction, but that would
+   make netlib.h dependent on netperf.h and I'm not sure I want to do
+   that. raj 2006-03-02 */
+static void netperf_test_launch_thread(NetperfTest *test)
+{
+
+  g_thread_create_full(netperf_test_launch_pad,   /* what to run */
+		       test, /* what it should use */
+		       0,    /* default stack size */
+		       FALSE, /* not joinable */
+		       TRUE,  /* bound - make it system scope */
+		       G_THREAD_PRIORITY_NORMAL,
+		       NULL);
+
+  /* REVISIT we really should be checking return values here and
+     possibly setting corresponding values in the test structure on
+     failure etc. */
+}
+
+
 /* get and set property routines */
 static void netperf_test_set_property(GObject *object,
 					   guint prop_id,

Modified: branches/gobject_migration/src/netperf-test.h
===================================================================
--- branches/gobject_migration/src/netperf-test.h	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf-test.h	2007-03-09 00:44:49 UTC (rev 205)
@@ -1,3 +1,35 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+This file is part of netperf4.
+
+Netperf4 is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+Netperf4 is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
 #ifndef NETPERF_TEST_H
 #define NETPERF_TEST_H
 
@@ -162,6 +194,7 @@
   void (*new_message)(NetperfTest *test, gpointer message);
   void (*control_closed)(NetperfTest *test);
   void (*dependency_met)(NetperfTest *test);
+  void (*launch_thread)(NetperfTest *test);
 
   /* methods */
 

Modified: branches/gobject_migration/src/netperf.c
===================================================================
--- branches/gobject_migration/src/netperf.c	2007-03-07 02:13:04 UTC (rev 204)
+++ branches/gobject_migration/src/netperf.c	2007-03-09 00:44:49 UTC (rev 205)
@@ -30,9 +30,6 @@
 but you are not obligated to do so.  If you do not wish to do so,
 delete this exception statement from your version.
 
-#include <termios.h>
-#include <grp.h>
-#include <pwd.h>
 */
 
 #ifdef HAVE_CONFIG_H



More information about the netperf-dev mailing list