From ae0502a73785bb3f470dfdfc38f3b37704bbafc7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 31 Mar 2015 13:54:04 +0200 Subject: [PATCH] added node type initalization (only called once per node type) --- server/include/node.h | 29 ++++++++++++++++++---- server/src/cfg.c | 8 ++++++- server/src/node.c | 56 ++++++++++++++++++++++++++++++++++++------- server/src/server.c | 21 ++++++---------- 4 files changed, 86 insertions(+), 28 deletions(-) diff --git a/server/include/node.h b/server/include/node.h index fe5ac91c9..d96759624 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -45,9 +45,11 @@ enum node_type { INVALID }; -/** C++ like vtable construct for node_types */ +/** C++ like vtable construct for node_types + * @todo Add comments + */ struct node_vtable { - enum node_type type; + const enum node_type type; const char *name; int (*parse)(config_setting_t *cfg, struct node *n); @@ -57,6 +59,11 @@ struct node_vtable { int (*close)(struct node *n); int (*read)(struct node *n, struct msg *m); int (*write)(struct node *n, struct msg *m); + + int (*init)(int argc, char *argv[]); + int (*deinit)(); + + int refcnt; }; /** The data structure for a node. @@ -72,7 +79,7 @@ struct node const char *name; /** C++ like virtual function call table */ - struct node_vtable const *vt; + struct node_vtable *vt; /** Virtual data (used by vtable functions) */ union { struct socket *socket; @@ -84,6 +91,20 @@ struct node config_setting_t *cfg; }; +/** Initialize node type subsystems. + * + * These routines are only called once per type (not node). + * See node_vtable::init + */ +int node_init(int argc, char *argv[]); + +/** De-initialize node type subsystems. + * + * These routines are only called once per type (not node). + * See node_vtable::deinit + */ +int node_deinit(); + /** Connect and bind the UDP socket of this node. * * Depending on the type (vtable) of this node, @@ -119,7 +140,7 @@ int node_stop(struct node *n); * @param str A string describing the socket type. This must be one of: tcp, tcpd, udp, ip, ieee802.3 or opal * @return A pointer to the vtable, or NULL if there is no socket type / vtable with this id. */ -struct node_vtable const * node_lookup_vtable(const char *str); +struct node_vtable * node_lookup_vtable(const char *str); /** Search list of nodes for a name. * diff --git a/server/src/cfg.c b/server/src/cfg.c index 9d708690a..ae37cea6f 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -132,8 +132,12 @@ int config_parse_path(config_setting_t *cfg, if (enabled) { p->in->refcnt++; - FOREACH(&p->destinations, it) + p->in->vt->refcnt++; + + FOREACH(&p->destinations, it) { it->node->refcnt++; + it->node->vt->refcnt++; + } if (reverse) { if (list_length(&p->destinations) > 1) @@ -149,6 +153,8 @@ int config_parse_path(config_setting_t *cfg, r->in->refcnt++; r->out->refcnt++; + r->in->vt->refcnt++; + r->out->vt->refcnt++; list_push(paths, r); } diff --git a/server/src/node.c b/server/src/node.c index 2a6e71db4..d5119fdc6 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -17,17 +17,24 @@ #include "opal.h" #endif -#define VTABLE(type, name, fnc) { type, name, config_parse_ ## fnc, \ - fnc ## _print, \ - fnc ## _open, \ - fnc ## _close, \ - fnc ## _read, \ - fnc ## _write } +#define VTABLE(type, name, fnc) { type, name, \ + fnc ## _parse, fnc ## _print, \ + fnc ## _open, fnc ## _close, \ + fnc ## _read, fnc ## _write } + +#define VTABLE2(type, name, fnc) { type, name, \ + fnc ## _parse, fnc ## _print, \ + fnc ## _open, fnc ## _close, \ + fnc ## _read, fnc ## _write, \ + fnc ## _init, fnc ## _deinit } /** Vtable for virtual node sub types */ -static const struct node_vtable vtables[] = { +struct node_vtable vtables[] = { #ifdef ENABLE_OPAL_ASYNC - VTABLE(OPAL_ASYNC, "opal", opal), + VTABLE2(OPAL_ASYNC, "opal", opal), +#endif +#ifdef ENABLE_GTFPGA + VTABLE2(GTFPGA, "gtfpga", gtfpga), #endif VTABLE(IEEE_802_3, "ieee802.3", socket), VTABLE(IP, "ip", socket), @@ -39,6 +46,37 @@ static const struct node_vtable vtables[] = { /** Linked list of nodes. */ struct list nodes; +int node_init(int argc, char *argv[]) +{ INDENT + for (int i=0; irefcnt && vt->init) { + if (vt->init(argc, argv)) + error("Failed to initialize '%s' node type", vt->name); + else + info("Initializing '%s' node type", vt->name); + } + } + + return 0; +} + +int node_deinit() +{ INDENT + /* De-initialize node types */ + for (int i=0; irefcnt && vt->deinit) { + if (vt->deinit()) + error("Failed to de-initialize '%s' node type", vt->name); + else + info("De-initializing '%s' node type", vt->name); + + } + } + return 0; +} + struct node * node_lookup_name(const char *str, struct list *nodes) { FOREACH(nodes, it) { @@ -49,7 +87,7 @@ struct node * node_lookup_name(const char *str, struct list *nodes) return NULL; } -struct node_vtable const * node_lookup_vtable(const char *str) +struct node_vtable * node_lookup_vtable(const char *str) { for (int i = 0; i < ARRAY_LEN(vtables); i++) { if (!strcmp(vtables[i].name, str)) diff --git a/server/src/server.c b/server/src/server.c index ccd1e1018..96b1d89be 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -51,15 +51,13 @@ static void quit() FOREACH(&interfaces, it) if_stop(it->interface); -#ifdef ENABLE_OPAL_ASYNC - opal_deinit(); -#endif - /* Freeing dynamically allocated memory */ list_destroy(&paths); list_destroy(&nodes); list_destroy(&interfaces); config_destroy(&config); + + node_deinit(); info("Goodbye!"); @@ -129,6 +127,8 @@ int main(int argc, char *argv[]) if (argc != 2) #endif usage(argv[0]); + + char *configfile = (argc == 2) ? argv[1] : "opal-shmem.conf"; info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s, debug=%d)", BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__)), _debug); @@ -149,19 +149,12 @@ int main(int argc, char *argv[]) info("Setup signals:"); signals_init(); + info("Initialize node types:"); + node_init(argc, argv); + info("Parsing configuration:"); config_init(&config); -#ifdef ENABLE_OPAL_ASYNC - /* Check if called we are called as an asynchronous process from RT-LAB. */ - opal_init(argc, argv); - - /* @todo: look in predefined locations for a file */ - char *configfile = "opal-shmem.conf"; -#else - char *configfile = argv[1]; -#endif - /* Parse configuration and create nodes/paths */ config_parse(configfile, &config, &settings, &nodes, &paths);