diff --git a/include/node.h b/include/node.h index 686b54044..b5a15df33 100644 --- a/include/node.h +++ b/include/node.h @@ -171,15 +171,8 @@ struct node NODE_STOPPED /**< Node was running, but has been stopped by calling node_close() */ } state; /**< Node state */ - struct node_type *_vt; /**< C++ like virtual function call table */ - - union { - struct socket *socket; - struct opal *opal; - struct gtfpga *gtfpga; - struct file *file; - struct ngsi *ngsi; - }; /** Virtual data (used by struct node::_vt functions) */ + struct node_type *_vt; /**< Virtual functions (C++ OOP style) */ + void *_vd; /**< Virtual data (used by struct node::_vt functions) */ config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this node */ }; diff --git a/lib/file.c b/lib/file.c index eb00a2814..37401e14b 100644 --- a/lib/file.c +++ b/lib/file.c @@ -18,7 +18,7 @@ int file_reverse(struct node *n) { - struct file *f = n->file; + struct file *f = n->_vd; SWAP(f->read, f->write); @@ -70,7 +70,7 @@ static int file_parse_direction(config_setting_t *cfg, struct file *f, int d) int file_parse(struct node *n, config_setting_t *cfg) { - struct file *f = alloc(sizeof(struct file)); + struct file *f = n->_vd; config_setting_t *cfg_in, *cfg_out; @@ -117,14 +117,14 @@ int file_parse(struct node *n, config_setting_t *cfg) cerror(cfg_in, "Invalid value '%s' for setting 'epoch_mode'", epoch_mode); } - n->file = f; + n->_vd = f; return 0; } char * file_print(struct node *n) { - struct file *f = n->file; + struct file *f = n->_vd; char *buf = NULL; if (f->read.fmt) { @@ -178,7 +178,7 @@ char * file_print(struct node *n) int file_open(struct node *n) { - struct file *f = n->file; + struct file *f = n->_vd; struct timespec now = time_now(); @@ -258,7 +258,7 @@ int file_open(struct node *n) int file_close(struct node *n) { - struct file *f = n->file; + struct file *f = n->_vd; free(f->read.path); free(f->write.path); @@ -275,8 +275,8 @@ int file_close(struct node *n) int file_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { + struct file *f = n->_vd; int values, flags, i = 0; - struct file *f = n->file; if (f->read.handle) { for (i = 0; i < cnt; i++) { @@ -338,7 +338,7 @@ retry: values = msg_fscan(f->read.handle, cur, &flags, NULL); int file_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { int i = 0; - struct file *f = n->file; + struct file *f = n->_vd; if (f->write.handle) { for (i = 0; i < cnt; i++) { @@ -364,6 +364,7 @@ int file_write(struct node *n, struct msg *pool, int poolsize, int first, int cn static struct node_type vt = { .name = "file", .description = "support for file log / replay node type", + .size = sizeof(struct file), .reverse = file_reverse, .parse = file_parse, .print = file_print, diff --git a/lib/gtfpga.c b/lib/gtfpga.c index c362a1ebd..6df6bab48 100644 --- a/lib/gtfpga.c +++ b/lib/gtfpga.c @@ -58,7 +58,7 @@ int gtfpga_deinit() int gtfpga_parse(struct node *n, config_setting_t *cfg) { - struct gtfpga *g = alloc(sizeof(struct gtfpga)); + struct gtfpga *g = n->_vd; const char *slot, *id, *err; config_setting_t *cfg_slot, *cfg_id; @@ -92,14 +92,12 @@ int gtfpga_parse(struct node *n, config_setting_t *cfg) if (!config_setting_lookup_float(cfg, "rate", &g->rate)) g->rate = 0; - n->gtfpga = g; - return 0; } char * gtfpga_print(struct node *n) { - struct gtfpga *g = n->gtfpga; + struct gtfpga *g = n->_vd; char *buf = NULL; if (g->dev) { @@ -181,7 +179,7 @@ static int gtfpga_mmap(struct gtfpga *g) int gtfpga_open(struct node *n) { - struct gtfpga *g = n->gtfpga; + struct gtfpga *g = n->_vd; struct pci_dev *dev; int ret; @@ -223,7 +221,7 @@ int gtfpga_open(struct node *n) int gtfpga_close(struct node *n) { - struct gtfpga *g = n->gtfpga; + struct gtfpga *g = n->_vd; if (g->map) munmap(g->map, g->dev->size[GTFPGA_BAR]); @@ -238,7 +236,7 @@ int gtfpga_close(struct node *n) /** @todo implement */ int gtfpga_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct gtfpga *g = n->gtfpga; + struct gtfpga *g = n->_vd; struct msg *m = &pool[first % poolsize]; @@ -258,7 +256,7 @@ int gtfpga_read(struct node *n, struct msg *pool, int poolsize, int first, int c /** @todo implement */ int gtfpga_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - // struct gtfpga *g = n->gtfpga; + // struct gtfpga *g = n->_vd; // struct msg *m = &pool[first % poolsize]; if (cnt != 1) diff --git a/lib/ngsi.c b/lib/ngsi.c index b1f22bbca..3eba383ea 100644 --- a/lib/ngsi.c +++ b/lib/ngsi.c @@ -430,7 +430,7 @@ int ngsi_deinit() int ngsi_parse(struct node *n, config_setting_t *cfg) { - struct ngsi *i = alloc(sizeof(struct ngsi)); + struct ngsi *i = n->_vd; if (!config_setting_lookup_string(cfg, "access_token", &i->access_token)) i->access_token = NULL; /* disabled by default */ @@ -458,8 +458,6 @@ int ngsi_parse(struct node *n, config_setting_t *cfg) cerror(cfg, "Missing mapping for node %s", node_name(n)); if (ngsi_parse_mapping(&i->mapping, cfg_mapping)) - - n->ngsi = i; cerror(cfg_mapping, "Invalid mapping for node %s", node_name(n)); return 0; @@ -467,7 +465,7 @@ int ngsi_parse(struct node *n, config_setting_t *cfg) char * ngsi_print(struct node *n) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; char *buf = NULL; return strcatf(&buf, "endpoint=%s, timeout=%.3f secs, #mappings=%zu", @@ -476,7 +474,7 @@ char * ngsi_print(struct node *n) int ngsi_destroy(struct node *n) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; list_destroy(&i->mapping); @@ -485,7 +483,7 @@ int ngsi_destroy(struct node *n) int ngsi_open(struct node *n) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; int ret; i->curl = curl_easy_init(); @@ -537,7 +535,7 @@ int ngsi_open(struct node *n) int ngsi_close(struct node *n) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; int ret; /* Delete complete entity (not just attributes) */ @@ -555,7 +553,7 @@ int ngsi_close(struct node *n) int ngsi_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; int ret; timerfd_wait(i->tfd); @@ -579,7 +577,7 @@ out: json_decref(entity); int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct ngsi *i = n->ngsi; + struct ngsi *i = n->_vd; int ret; json_t *entity = ngsi_build_entity(i, pool, poolsize, first, cnt, NGSI_ENTITY_VALUES); @@ -594,6 +592,7 @@ int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cn static struct node_type vt = { .name = "ngsi", .description = "OMA Next Generation Services Interface 10 (libcurl, libjansson, libuuid)", + .size = sizeof(struct ngsi), .parse = ngsi_parse, .print = ngsi_print, .open = ngsi_open, diff --git a/lib/node.c b/lib/node.c index 5120c4ab8..d11c80062 100644 --- a/lib/node.c +++ b/lib/node.c @@ -130,6 +130,11 @@ struct node * node_create(struct node_type *vt) list_push(&vt->instances, n); n->_vt = vt; + n->_vd = alloc(n->_vt->size); + + if (n->_vt->create) + n->_vt->create(n); + n->state = NODE_CREATED; return n; @@ -140,7 +145,7 @@ void node_destroy(struct node *n) if (n->_vt->destroy) n->_vt->destroy(n); - free(n->socket); + free(n->_vd); free(n->_name); free(n); } diff --git a/lib/opal.c b/lib/opal.c index 01378cfa2..59af0ba5b 100644 --- a/lib/opal.c +++ b/lib/opal.c @@ -130,15 +130,12 @@ int opal_print_global(struct opal_global *g) int opal_parse(struct node *n, config_setting_t *cfg) { - struct opal *o = alloc(sizeof(struct opal)); + struct opal *o = n->_vd; config_setting_lookup_int(cfg, "send_id", &o->send_id); config_setting_lookup_int(cfg, "recv_id", &o->recv_id); config_setting_lookup_bool(cfg, "reply", &o->reply); - n->opal = o; - n->cfg = cfg; - return 0; } @@ -155,7 +152,7 @@ char * opal_print(struct node *n) int opal_open(struct node *n) { - struct opal *o = n->opal; + struct opal *o = n->_vd; if (!og) error("The server was not started as an OPAL asynchronous process!"); @@ -187,7 +184,7 @@ int opal_close(struct node *n) int opal_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct opal *o = n->opal; + struct opal *o = n->_vd; int state, len, ret; unsigned id; @@ -252,7 +249,7 @@ int opal_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct opal *o = n->opal; + struct opal *o = n->_vd; struct msg *m = &pool[first % poolsize]; @@ -286,6 +283,7 @@ int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cn static struct node_type vt = { .name = "opal", .description = "run as OPAL Asynchronous Process (libOpalAsyncApi)", + .size = sizeof(struct opal), .parse = opal_parse, .print = opal_print, .open = opal_open, diff --git a/lib/socket.c b/lib/socket.c index 65afc106b..6fd332e35 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -48,7 +48,7 @@ int socket_init(int argc, char * argv[], struct settings *set) /* Gather list of used network interfaces */ list_foreach(struct node *n, &vt.instances) { - struct socket *s = n->socket; + struct socket *s = n->_vd; struct rtnl_link *link; /* Determine outgoing interface */ @@ -85,7 +85,7 @@ int socket_deinit() char * socket_print(struct node *n) { - struct socket *s = n->socket; + struct socket *s = n->_vd; char *layer = NULL, *buf = NULL; switch (s->layer) { @@ -107,7 +107,7 @@ char * socket_print(struct node *n) int socket_open(struct node *n) { - struct socket *s = n->socket; + struct socket *s = n->_vd; struct sockaddr_in *sin = (struct sockaddr_in *) &s->local; struct sockaddr_ll *sll = (struct sockaddr_ll *) &s->local; int ret; @@ -161,7 +161,7 @@ int socket_open(struct node *n) int socket_reverse(struct node *n) { - struct socket *s = n->socket; + struct socket *s = n->_vd; SWAP(s->remote, s->local); @@ -170,7 +170,7 @@ int socket_reverse(struct node *n) int socket_close(struct node *n) { - struct socket *s = n->socket; + struct socket *s = n->_vd; if (s->sd >= 0) close(s->sd); @@ -180,7 +180,7 @@ int socket_close(struct node *n) int socket_destroy(struct node *n) { - struct socket *s = n->socket; + struct socket *s = n->_vd; rtnl_qdisc_put(s->tc_qdisc); rtnl_cls_put(s->tc_classifier); @@ -190,7 +190,7 @@ int socket_destroy(struct node *n) int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct socket *s = n->socket; + struct socket *s = n->_vd; int bytes; struct iovec iov[cnt]; @@ -249,7 +249,7 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c int socket_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt) { - struct socket *s = n->socket; + struct socket *s = n->_vd; int bytes, sent = 0; /** @todo we should check the MTU */ @@ -296,7 +296,7 @@ int socket_parse(struct node *n, config_setting_t *cfg) const char *local, *remote, *layer; int ret; - struct socket *s = alloc(sizeof(struct socket)); + struct socket *s = n->_vd; if (!config_setting_lookup_string(cfg, "layer", &layer)) cerror(cfg, "Missing layer for node %s", node_name(n)); @@ -335,8 +335,6 @@ int socket_parse(struct node *n, config_setting_t *cfg) tc_parse(cfg_netem, &s->tc_qdisc); } - n->socket = s; - return 0; } @@ -478,6 +476,7 @@ int socket_parse_addr(const char *addr, struct sockaddr *saddr, enum socket_laye static struct node_type vt = { .name = "socket", .description = "Network socket (libnl3)", + .size = sizeof(struct socket), .destroy = socket_destroy, .reverse = socket_reverse, .parse = socket_parse,