[netperf-dev] netperf4 commit notice r222 -
branches/gobject_migration/src
raj at netperf.org
raj at netperf.org
Wed Mar 21 13:42:47 PST 2007
Author: raj
Date: 2007-03-21 13:42:45 -0800 (Wed, 21 Mar 2007)
New Revision: 222
Modified:
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/netperf4.c
Log:
eghads we can ask a test to init
Modified: branches/gobject_migration/src/netperf-netserver.c
===================================================================
--- branches/gobject_migration/src/netperf-netserver.c 2007-03-16 21:51:00 UTC (rev 221)
+++ branches/gobject_migration/src/netperf-netserver.c 2007-03-21 21:42:45 UTC (rev 222)
@@ -163,6 +163,8 @@
connection */
CONTROL_CLOSED, /* this would be the control connection object
telling us the controll connection died. */
+ SEND_MESSAGE, /* this would be someone asking us to send a
+ message */
LAST_SIGNAL /* this should always be the last in the list so
we can use it to size the array correctly. of
course, we may never actually use the array,
@@ -174,11 +176,12 @@
static void netperf_netserver_control_closed(NetperfNetserver *netserver);
static void netperf_netserver_connect_control(NetperfNetserver *netserver);
static void netperf_netserver_control_connected(NetperfNetserver *netserver);
+static void netperf_netserver_send_message(NetperfNetserver *netserver, gpointer*desc);
/* 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_netserver_signals[LAST_SIGNAL] = {0,0,0};
+static guint netperf_netserver_signals[LAST_SIGNAL] = {0,0,0,0};
GType netperf_netserver_get_type(void) {
static GType netperf_netserver_type = 0;
@@ -309,6 +312,7 @@
klass->control_closed = netperf_netserver_control_closed;
klass->connect_control = netperf_netserver_connect_control;
klass->control_connected = netperf_netserver_control_connected;
+ klass->send_message = netperf_netserver_send_message;
netperf_netserver_signals[NEW_MESSAGE] =
g_signal_new("new_message", /* signal name */
@@ -326,6 +330,25 @@
G_TYPE_NONE, /* type of return value */
1, /* one additional parameter */
G_TYPE_POINTER); /* and its type */
+
+ netperf_netserver_signals[SEND_MESSAGE] =
+ g_signal_new("send_message", /* signal name */
+ TYPE_NETPERF_NETSERVER, /* class type id */
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, /* options,
+ not sure if
+ G_SIGNAL_DETAILED
+ is
+ indicated */
+ G_STRUCT_OFFSET(NetperfNetserverClass, send_message),
+ NULL, /* no accumulator */
+ NULL, /* so no accumulator data */
+ g_cclosure_marshal_VOID__POINTER, /* return void,
+ take pointer */
+ G_TYPE_NONE, /* type of return value */
+ 1, /* one additional parameter */
+ G_TYPE_POINTER); /* and its type */
+
+
netperf_netserver_signals[CONTROL_CLOSED] =
g_signal_new("control_closed",
TYPE_NETPERF_NETSERVER,
@@ -1483,6 +1506,32 @@
return;
}
+static void netperf_netserver_send_message(NetperfNetserver *netserver, gpointer *message)
+{
+ netperf_control_msg_desc_t *desc;
+
+ g_print("Netserver object %p asked to send a message from %p\n",
+ netserver->id,
+ message);
+
+ desc = g_malloc(sizeof(netperf_control_msg_desc_t));
+ desc->body = message;
+ if (netserver->is_netperf) {
+ desc->nid = g_strdup(netserver->id);
+ desc->fromnid = g_strdup("netperf");
+ }
+ else {
+ desc->nid = g_strdup("netperf");
+ desc->fromnid = g_strdup(netserver->id);
+ }
+
+ /* ok, now go ahead and tell the control object to do its thing */
+ g_signal_emit_by_name(netserver->control_object,
+ "message", desc);
+
+ return;
+}
+
/* signal handler for control connection closed */
static void netperf_netserver_control_closed(NetperfNetserver *netserver)
{
Modified: branches/gobject_migration/src/netperf-netserver.h
===================================================================
--- branches/gobject_migration/src/netperf-netserver.h 2007-03-16 21:51:00 UTC (rev 221)
+++ branches/gobject_migration/src/netperf-netserver.h 2007-03-21 21:42:45 UTC (rev 222)
@@ -134,6 +134,7 @@
void (*control_closed)(NetperfNetserver *netserver);
void (*connect_control)(NetperfNetserver *netserver);
void (*control_connected)(NetperfNetserver *netserver);
+ void (*send_message)(NetperfNetserver *netserver, gpointer message);
/* methods */
};
Modified: branches/gobject_migration/src/netperf-test.c
===================================================================
--- branches/gobject_migration/src/netperf-test.c 2007-03-16 21:51:00 UTC (rev 221)
+++ branches/gobject_migration/src/netperf-test.c 2007-03-21 21:42:45 UTC (rev 222)
@@ -56,7 +56,15 @@
#include "netperf.h"
#include "netperf-test.h"
+#include "netperf-netserver.h"
+#include "netperf-control.h"
+extern int debug;
+extern FILE * where;
+extern GHashTable *test_hash;
+extern GHashTable *test_set_hash;
+extern GHashTable *server_hash;
+
enum {
TEST_PROP_DUMMY_0, /* GObject does not like a zero value for a property id */
TEST_PROP_ID,
@@ -69,7 +77,8 @@
TEST_PROP_TEST_STATS,
TEST_PROP_TEST_DECODE,
TEST_PROP_TEST_ADD_DEPENDANT,
- TEST_PROP_TEST_DEL_DEPENDANT
+ TEST_PROP_TEST_DEL_DEPENDANT,
+ TEST_PROP_TEST_DEPENDENT_DATA
};
/* some forward declarations to make the compiler happy regardless of
@@ -185,6 +194,7 @@
GParamSpec *test_decode_param;
GParamSpec *test_add_dependant_param;
GParamSpec *test_del_dependant_param;
+ GParamSpec *test_dependent_data_param;
/* and on with the show */
GObjectClass *g_object_class;
@@ -208,7 +218,7 @@
NP_TST_PREINIT, /* min value */
NP_TST_DEAD, /* max value */
NP_TST_PREINIT, /* def value */
- G_PARAM_READABLE); /* should this be read only? */
+ G_PARAM_READWRITE);
id_param =
g_param_spec_string("id", /* identifier */
@@ -261,6 +271,13 @@
G_PARAM_READWRITE); /* should this be just
WRITABLE? */
+ test_dependent_data_param =
+ g_param_spec_pointer("dependent_data",
+ "dependent data",
+ "data other tests might depend upon",
+ G_PARAM_READWRITE); /* should this just be
+ READABLE */
+
/* if we go with a weak pointer reference then we probably don't
need/want a delete property, but if we simply keep a pointer to
the test instance then we do */
@@ -323,6 +340,10 @@
TEST_PROP_TEST_DEL_DEPENDANT,
test_del_dependant_param);
+ g_object_class_install_property(g_object_class,
+ TEST_PROP_TEST_DEPENDENT_DATA,
+ test_dependent_data_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. */
@@ -665,6 +686,213 @@
return(rc);
}
+static void netperf_test_initialize(NetperfTest *test)
+{
+
+ xmlNodePtr cur = NULL;
+ xmlNodePtr dependent_data = NULL;
+ guint dependent_state = NP_TST_PREINIT;
+
+ xmlChar *id = NULL;
+ NetperfTest *dependency;
+
+ /* we wish to be in the NP_TST_INIT state */
+ test->state_req = NP_TST_INIT;
+
+ cur = test->node->xmlChildrenNode;
+ while (cur != NULL) {
+ if (!xmlStrcmp(cur->name,(const xmlChar *)"dependson")) {
+ id = xmlGetProp(cur, (const xmlChar *)"testid");
+ if (test->debug) {
+ g_fprintf(test->where,"%s test %s has a dependency on %s\n",
+ __func__,
+ test->id,
+ id);
+ }
+ /* rc = resolve_dependency(id, &dep_data); */
+ dependency = g_hash_table_lookup(test_hash,id);
+ g_print("%s test %s has a dependency on %s at %p\n",
+ __func__,
+ test->id,
+ id,
+ dependency);
+ /* go ahead and tell the test we depend upon them. one of these
+ days we'll probably need to make sure we aren't in their list
+ multiple times, but we will probably leave that up to
+ them */
+ g_object_set(dependency,
+ "add_dependant", test,
+ NULL);
+
+ /* now then, see if there is dependent data to get */
+ g_object_get(dependency,
+ "state", &dependent_state,
+ "dependent_data", &dependent_data,
+ NULL);
+ g_print("dependent test in state %u with data %p\n",
+ dependent_state,
+ dependent_data);
+ break;
+ }
+ cur = cur->next;
+ }
+
+ /* OK, now what do we do :) If we had no depdency upon another test
+ we want to go ahead and send our test message now. otherwise, if
+ we had a dependency and have the dependent data, we want to send
+ it now. we do nothing only if we depend and the data isn't
+ ready, in which case, we should be covered by the signal we
+ should receive from the test upon which we depend once it is
+ initialized. */
+
+ if ((NULL == id) ||
+ ((dependent_state != NP_TST_PREINIT) && (NULL != dependent_data))) {
+ NetperfNetserver *server = NULL;
+ xmlNodePtr message = NULL;
+ /* find our server, send a message */
+ server = g_hash_table_lookup(server_hash,test->server_id);
+ g_print("frabjous day, the server for test %s is at %p\n",
+ test->id,server);
+ /* build-up a message, first copy our initial config info */
+ message = xmlCopyNode(test->node,1);
+ /* now add-in any dependency data */
+ if (NULL != dependent_data) {
+ cur = message->xmlChildrenNode;
+ while (NULL != cur) {
+ /* prune dependson node and replace with dependency data */
+ if (!xmlStrcmp(cur->name,(const xmlChar *)"dependson")) {
+ xmlReplaceNode(cur,dependent_data);
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ /* now ask the server to go ahead and send the message. the
+ netserver object will handle dealing with the control
+ connection object */
+ g_signal_emit_by_name(server,"send_message",message);
+
+ }
+ else {
+ /* do nothing */
+ g_print("test %s must await further initialization instruction\n",
+ test->id);
+ }
+}
+
+static void netperf_test_set_req_state(NetperfTest *test,
+ guint req_state) {
+
+ gboolean legal_transition = TRUE;
+
+ switch (req_state) {
+ case NP_TST_PREINIT:
+ if (NP_TST_PREINIT == test->state) test->state_req = req_state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_INIT:
+ if (NP_TST_PREINIT == test->state) netperf_test_initialize(test);
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_IDLE:
+ if ((NP_TST_INIT == test->state) ||
+ (NP_TST_LOADED == test->state)) test->state_req = req_state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_LOADED:
+ if ((NP_TST_IDLE == test->state) ||
+ (NP_TST_MEASURE == test->state)) test->state_req = req_state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_MEASURE:
+ if (NP_TST_LOADED == test->state) test->state_req = req_state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_ERROR:
+ test->state_req = req_state;
+
+ case NP_TST_DEAD:
+ /* not really sure */
+ test->state_req = req_state;
+
+ default:
+ legal_transition = FALSE;
+ }
+
+ if (!legal_transition)
+ g_print("Illegal attempt made to transition test id %s from state %u to %u\n",
+ test->id,
+ test->state,
+ req_state);
+
+}
+
+static void netperf_test_set_state(NetperfTest *test, guint state)
+{
+ gboolean legal_transition = TRUE;
+
+ switch (state) {
+ case NP_TST_PREINIT:
+ /* we really only allow it when it would be a noop */
+ if ((NP_TST_PREINIT == test->state) &&
+ (NP_TST_PREINIT == test->state_req)) test->state = state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_INIT:
+ if ((NP_TST_PREINIT == test->state) &&
+ (NP_TST_INIT == test->state_req)) test->state = state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_IDLE:
+ if ((NP_TST_IDLE == test->state_req) &&
+ ((NP_TST_INIT == test->state) ||
+ (NP_TST_LOADED == test->state))) test->state = state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_LOADED:
+ if ((NP_TST_LOADED == test->state_req) &&
+ ((NP_TST_MEASURE == test->state) ||
+ (NP_TST_IDLE == test->state))) test->state = state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_MEASURE:
+ if ((NP_TST_MEASURE == test->state_req) &&
+ (NP_TST_LOADED == test->state)) test->state = state;
+ else legal_transition = FALSE;
+ break;
+
+ case NP_TST_ERROR:
+ /* probably actually have to do something here besides just set
+ the state */
+ test->state = state;
+ test->state_req = state;
+
+ case NP_TST_DEAD:
+ /* not really sure */
+ test->state = state;
+
+ default:
+ legal_transition = FALSE;
+ }
+
+ if (!legal_transition)
+ g_print("Illegal state change test id %s from state %u to %u when state_req %u \n",
+ test->id,
+ test->state,
+ state,
+ test->state_req);
+
+}
+
/* get and set property routines */
static void netperf_test_set_property(GObject *object,
guint prop_id,
@@ -681,15 +909,15 @@
switch(prop_id) {
case TEST_PROP_STATE:
- g_print("naughty naughty, trying to set the state. rick should make that readonly \n");
+ /* might as well reuse req_state rather than a separate state
+ local */
+ req_state = g_value_get_uint(value);
+ netperf_test_set_state(test,req_state);
break;
case TEST_PROP_REQ_STATE:
req_state = g_value_get_uint(value);
- /* we really need to sanity check the reqeusted state against the
- current state here... and perhaps do some other work as
- well... */
- test->state_req = req_state;
+ netperf_test_set_req_state(test,req_state);
break;
case TEST_PROP_ID:
@@ -721,10 +949,21 @@
break;
case TEST_PROP_TEST_ADD_DEPENDANT:
+ g_print("test %s being told that test at %p depends upon it\n",
+ test->id,dependent);
+ /* only one entry in the list please */
dependent = g_value_get_pointer(value);
- item = g_list_append(NULL, dependent);
- g_object_add_weak_pointer(dependent, &item->data);
- test->dependent_tests = g_list_concat(item, test->dependent_tests);
+ item = g_list_find(test->dependent_tests,dependent);
+ if (NULL == item) {
+ item = g_list_append(NULL, dependent);
+ g_object_add_weak_pointer(dependent, &item->data);
+ test->dependent_tests = g_list_concat(item, test->dependent_tests);
+ }
+ else {
+ /* probably should be a debug thing only... */
+ g_print("suppressed an attempt to add a duplicate dependent %p\n",
+ dependent);
+ }
break;
case TEST_PROP_TEST_DEL_DEPENDANT:
@@ -732,6 +971,10 @@
g_print("Yo, add the code to delete a dependant!\n");
break;
+ case TEST_PROP_TEST_DEPENDENT_DATA:
+ g_print("I'm sorry Dave, I can't let you do that.\n");
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -784,10 +1027,14 @@
g_value_set_pointer(value, test->test_decode);
break;
+ case TEST_PROP_TEST_DEPENDENT_DATA:
+ g_value_set_pointer(value, test->dependent_data);
+ break;
+
/* it doesn't seem to make much sense to have "get" for add/del a
dependant test so we will let those fall-through to the default
case */
-
+
case TEST_PROP_TEST_ADD_DEPENDANT:
case TEST_PROP_TEST_DEL_DEPENDANT:
default:
Modified: branches/gobject_migration/src/netperf4.c
===================================================================
--- branches/gobject_migration/src/netperf4.c 2007-03-16 21:51:00 UTC (rev 221)
+++ branches/gobject_migration/src/netperf4.c 2007-03-21 21:42:45 UTC (rev 222)
@@ -439,11 +439,31 @@
}
}
+void set_test_state(gpointer key, gpointer value, gpointer user_data)
+{
+ /* remember that the value is the pointer to the test object, not
+ the key, which we don't really use here but to make
+ g_hash_mumble_for_each happy. the user_data will be the desired
+ state */
+ guint desired_state = GPOINTER_TO_UINT(user_data);
+
+ g_print("about to try to set the state of test %s at %p to %u\n",
+ (char *) key,
+ value,
+ desired_state);
+
+ g_object_set(value,
+ "req_state", desired_state,
+ NULL);
+
+}
+
void print_test_hash_entry(gpointer key, gpointer value, gpointer user_data)
{
NetperfTest *test;
guint state,req_state;
gchar *id;
+ gchar *server_id;
xmlNodePtr node;
xmlNodePtr tmp_node;
xmlDocPtr tmp_doc;
@@ -457,16 +477,18 @@
"state", &state,
"req-state", &req_state,
"id", &id,
+ "serverid", &server_id,
"node", &node,
NULL);
- g_print("test: %s, object %p, user_data %p id %s state %s (%d) req_state %s (%d) node %p\n",
+ g_print("test: %s, object %p, user_data %p id %s server %s state %s (%d) req_state %s (%d) node %p\n",
(char *)key,
value,
user_data,
id,
+ server_id,
netperf_test_state_to_string(state),
state,
- netperf_test_state_to_string(state),
+ netperf_test_state_to_string(req_state),
req_state,
node);
@@ -567,18 +589,81 @@
}
static gboolean unknown_interactive_command(char *arguments,
- gpointer data) {
+ gpointer data)
+{
g_print("The command you entered %s is presently unknown\n",
arguments);
return TRUE;
}
+static gboolean parse_interactive_set_netserver_command(char *arguments,
+ gpointer data)
+{
+ gboolean return_value = TRUE;
+
+ return return_value;
+}
+
+static gboolean parse_interactive_set_test_command(char *arguments,
+ gpointer data)
+{
+ gboolean return_value = TRUE;
+ NetperfTest *test;
+ gchar **split;
+ NETPERF_DEBUG_ENTRY(debug,where);
+
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+
+ if (g_strcasecmp(split[0],"all") == 0) {
+ g_hash_table_foreach(test_hash,set_test_state,data);
+ }
+ else {
+ test = g_hash_table_lookup(test_hash,split[0]);
+ if (NULL != test) {
+ set_test_state(split[0],test,data);
+ }
+ else {
+ g_print("test id %s unknown!\n",
+ split[0]);
+ }
+ }
+
+ g_strfreev(split);
+
+ NETPERF_DEBUG_EXIT(debug,where);
+
+ return return_value;
+}
+
static gboolean parse_interactive_set_command(char *arguments,
gpointer data)
{
gboolean return_value = TRUE;
+ gchar **split;
+ NETPERF_DEBUG_ENTRY(debug,where);
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+
+ if (g_strcasecmp(split[0],"test") == 0) {
+ return_value = parse_interactive_set_test_command(split[1],data);
+ }
+ else if (g_strcasecmp(split[0],"netserver") == 0) {
+ return_value = parse_interactive_set_netserver_command(split[1],data);
+ }
+ else {
+ g_print("%s is not sure what you are trying to set \n",
+ __func__);
+ }
+
+ g_strfreev(split);
+
+ NETPERF_DEBUG_EXIT(debug,where);
+
return return_value;
}
@@ -674,8 +759,8 @@
if (g_strcasecmp("netserver",split[0]) == 0)
return_value = parse_interactive_show_netserver_command(split[1],
data);
- else if (g_strcasecmp("test",split[0]) == 0)
- return_value = parse_interactive_show_test_command(split[1],
+ else if (g_strcasecmp("test",split[0]) == 0)
+ return_value = parse_interactive_show_test_command(split[1],
data);
else if (g_strcasecmp("all",split[0]) == 0)
return_value = execute_interactive_show_all_command(data);
@@ -709,19 +794,130 @@
return return_value;
}
+static gboolean parse_interactive_init_netserver_command(char *arguments,
+ gpointer data)
+{
+ gboolean return_value = TRUE;
+
+ return return_value;
+}
+
+static gboolean parse_interactive_init_test_command(char *arguments,
+ gpointer data)
+{
+
+ gboolean return_value = TRUE;
+ NetperfTest *test;
+ gchar **split;
+
+ NETPERF_DEBUG_ENTRY(debug,where);
+
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+
+ if (g_strcasecmp(split[0],"all") == 0) {
+ g_hash_table_foreach(test_hash,set_test_state,NP_TST_INIT);
+ }
+ else {
+ test = g_hash_table_lookup(test_hash,split[0]);
+ if (NULL != test) {
+ set_test_state(split[0],test,NP_TST_INIT);
+ }
+ else {
+ g_print("test id %s unknown!\n",
+ split[0]);
+ }
+ }
+
+ g_strfreev(split);
+
+ NETPERF_DEBUG_EXIT(debug,where);
+
+ return return_value;
+
+}
+
static gboolean parse_interactive_init_command(char *arguments,
gpointer data)
{
gboolean return_value = TRUE;
+ gchar **split;
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+ if (g_strcasecmp("netserver", split[0]) == 0)
+ return_value = parse_interactive_init_netserver_command(split[1],
+ data);
+ else if (g_strcasecmp("test", split[0]) == 0)
+ return_value = parse_interactive_init_test_command(split[1],
+ data);
+
+ g_strfreev(split);
return return_value;
}
+static gboolean parse_interactive_idle_netserver_command(char *arguments,
+ gpointer data)
+{
+ gboolean return_value = TRUE;
+
+ return return_value;
+}
+
+static gboolean parse_interactive_idle_test_command(char *arguments,
+ gpointer data)
+{
+ gboolean return_value = TRUE;
+ NetperfTest *test;
+ gchar **split;
+
+ NETPERF_DEBUG_ENTRY(debug,where);
+
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+
+ if (g_strcasecmp(split[0],"all") == 0) {
+ g_hash_table_foreach(test_hash,set_test_state,NP_TST_IDLE);
+ }
+ else {
+ test = g_hash_table_lookup(test_hash,split[0]);
+ if (NULL != test) {
+ set_test_state(split[0],test,NP_TST_IDLE);
+ }
+ else {
+ g_print("test id %s unknown!\n",
+ split[0]);
+ }
+ }
+
+ g_strfreev(split);
+
+ NETPERF_DEBUG_EXIT(debug,where);
+
+ return return_value;
+}
+
static gboolean parse_interactive_idle_command(char *arguments,
gpointer data)
{
gboolean return_value = TRUE;
+ gchar **split;
+ split = g_strsplit_set(arguments,
+ " \r\n",
+ 2);
+ if (g_strcasecmp("netserver", split[0]) == 0)
+ return_value = parse_interactive_idle_netserver_command(split[1],
+ data);
+ else if (g_strcasecmp("test", split[0]) == 0)
+ return_value = parse_interactive_idle_test_command(split[1],
+ data);
+
+ g_strfreev(split);
+
return return_value;
}
More information about the netperf-dev
mailing list