From d9444ac5ee45d965070c1ee4aab3252000f7e2eb Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Tue, 15 Feb 2011 17:12:15 +0100 Subject: [PATCH] forb: First implementation of forbrun Not tested! forbrun should executed FORB servers implemented as shared libraries. Its aim is to allow execution of multiple independent servers in a single process. This is done in preparation of porting FRSH/FORB to RTEMS (and other single-address space executives). --- src/forb/src/Makefile.omk | 2 +- src/forb/src/forbrun/Makefile | 14 +++ src/forb/src/forbrun/Makefile.omk | 4 + src/forb/src/forbrun/forbrun.c | 148 ++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/forb/src/forbrun/Makefile create mode 100644 src/forb/src/forbrun/Makefile.omk create mode 100644 src/forb/src/forbrun/forbrun.c diff --git a/src/forb/src/Makefile.omk b/src/forb/src/Makefile.omk index 8a382b8d..ab847f90 100644 --- a/src/forb/src/Makefile.omk +++ b/src/forb/src/Makefile.omk @@ -1,4 +1,4 @@ -SUBDIRS = tests +SUBDIRS = tests forbrun CFLAGS += -I. diff --git a/src/forb/src/forbrun/Makefile b/src/forb/src/forbrun/Makefile new file mode 100644 index 00000000..d538d218 --- /dev/null +++ b/src/forb/src/forbrun/Makefile @@ -0,0 +1,14 @@ +# Generic directory or leaf node makefile for OCERA make framework + +ifndef MAKERULES_DIR +MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) ) +endif + +ifeq ($(MAKERULES_DIR),) +all : default +.DEFAULT:: + @echo -e "\nThe Makefile.rules has not been found in this or partent directory: `pwd`\n" +else +include $(MAKERULES_DIR)/Makefile.rules +endif + diff --git a/src/forb/src/forbrun/Makefile.omk b/src/forb/src/forbrun/Makefile.omk new file mode 100644 index 00000000..46e14307 --- /dev/null +++ b/src/forb/src/forbrun/Makefile.omk @@ -0,0 +1,4 @@ +bin_PROGRAMS = forbrun +forbrun_SOURCES = forbrun.c + +lib_LOADLIBES = forb ulut fosa rt dl diff --git a/src/forb/src/forbrun/forbrun.c b/src/forb/src/forbrun/forbrun.c new file mode 100644 index 00000000..6f33ade5 --- /dev/null +++ b/src/forb/src/forbrun/forbrun.c @@ -0,0 +1,148 @@ +#define WITH_C99 /* For ul_gsa.h iterators */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct option long_opts[] = { + { "daemon", optional_argument, NULL, 'd' }, + { "id", required_argument, NULL, 'i' }, +/* { "loglevel", required_argument, NULL, 'l' }, */ + { "port", required_argument, NULL, 'p' }, + { 0, 0, 0, 0} +}; + +static void +usage(void) +{ + printf("usage: forbrun [ options ] .so ... [-- ] \n"); + printf(" -d, --daemon [pid-file] go to background after initialization of servers\n"); + printf(" -i, --id \n"); +/* printf(" -l, --loglevel |=,...\n"); */ + printf(" -p, --port listen on a fixed port number\n"); +} + +int print_log_domain(ul_log_domain_t *domain, void *context) +{ + printf("%s = %d\n", domain->name, domain->level); + return 0; +} + +struct forb_main_data { + char *filename; + forb_orb orb; + int (*forb_main)(forb_orb orb, int argc, char *argv[]); + int argc; + char **argv; +}; + +void *forb_main_thread(void *arg) +{ + struct forb_main_data *data = arg; + int ret; + ret = data->forb_main(data->orb, data->argc, data->argv); + if (ret != 0) + fprintf(stderr, "forb_main() in %s returned %d\n", + data->filename, ret); + return NULL; +} + +int main(int argc, char *argv[]) +{ + forb_orb orb; + bool opt_daemon = false; + char *opt_pidfile = NULL; + int i; + forb_init_attr_t attr = { + .orb_id = "org.frescor.fcb", + .peer_discovery_callback = NULL, /* TODO */ + .peer_dead_callback = NULL, /* TODO */ + .fixed_tcp_port = 0, +#ifdef CONFIG_FORB_PROTO_INET_DEFAULT + .fixed_server_id = 0, /* TODO */ + .redistribute_hellos = false , /* TODO */ +#endif + }; + int opt; + + while ((opt = getopt_long(argc, argv, "d::hil:p:", &long_opts[0], NULL)) != EOF) { + switch (opt) { +#if 0 + case 'l': + if (*optarg == '?') { + ul_logreg_for_each_domain(print_log_domain, NULL); + exit(0); + } + { + int ret; + ret = ul_log_domain_arg2levels(optarg); + if (ret) + error(1, EINVAL, "Error parsing -l argument at char %d\n", ret); + } + break; +#endif + case 'd': + opt_daemon = true; + opt_pidfile = optarg; + break; + case 'i': + attr.orb_id = optarg; + break; + case 'h': + /*default:*/ + usage(); + exit(opt == 'h' ? 0 : 1); + break; + case 'p': + attr.fixed_tcp_port = atol(optarg); + break; + } + } + + if (opt_daemon) + forb_daemon_prepare(opt_pidfile); /* == fork() */ + + orb = forb_init(&argc, &argv, &attr); + if (!orb) error(1, errno, "FORB initialization failed"); + +#if CONFIG_FCB_INET && !CONFIG_FORB_PROTO_INET_DEFAULT + ret = register_inet_port(orb); + if (ret) error(0, errno, "INET port registration failed"); +#endif + + for (i = optind; i < argc; i++) { + void *handle; + fosa_thread_id_t tid; + struct forb_main_data data; + + data.filename = argv[i]; + handle = dlopen(data.filename, RTLD_LOCAL|RTLD_LAZY); + if (!handle) + error(1, errno, "dlopen(\"%s\") failed", data.filename); + data.forb_main = dlsym(handle, "forb_main"); + if (!data.forb_main) + error(1, errno, "Cannot find forb_main() in %s", data.filename); + + data.orb = orb; + data.argc = 0; /* TODO argc and argv after "--" */ + data.argv = NULL; /* TODO argc and argv after "--" */ + fosa_thread_create(&tid, NULL, forb_main_thread, &data); + + forb_wait_for_server_ready(orb); + } + + if (opt_daemon) + forb_daemon_ready(); + + /* Allow other threads to continue execution, but exit + * ourselves (without exit()ing the whole process. */ + pthread_exit(NULL); + + return 0; +} -- 2.39.2