]> rtime.felk.cvut.cz Git - frescor/forb.git/commitdiff
forb: First implementation of forbrun
authorMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 15 Feb 2011 16:12:15 +0000 (17:12 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 15 Feb 2011 16:17:35 +0000 (17:17 +0100)
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/Makefile.omk
src/forbrun/Makefile [new file with mode: 0644]
src/forbrun/Makefile.omk [new file with mode: 0644]
src/forbrun/forbrun.c [new file with mode: 0644]

index 8a382b8d5d5f278c35871a00497a2238656c648d..ab847f905e7f42ec1389842e86fcc1e4348fea0f 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = tests forbrun
 
 CFLAGS += -I.
 
diff --git a/src/forbrun/Makefile b/src/forbrun/Makefile
new file mode 100644 (file)
index 0000000..d538d21
--- /dev/null
@@ -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/forbrun/Makefile.omk b/src/forbrun/Makefile.omk
new file mode 100644 (file)
index 0000000..46e1430
--- /dev/null
@@ -0,0 +1,4 @@
+bin_PROGRAMS = forbrun
+forbrun_SOURCES = forbrun.c
+
+lib_LOADLIBES = forb ulut fosa rt dl
diff --git a/src/forbrun/forbrun.c b/src/forbrun/forbrun.c
new file mode 100644 (file)
index 0000000..6f33ade
--- /dev/null
@@ -0,0 +1,148 @@
+#define WITH_C99               /* For ul_gsa.h iterators */
+#include <getopt.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ul_log.h>
+#include <stdbool.h>
+#include <dlfcn.h>
+#include <forb/forb-internal.h>
+#include <pthread.h>
+
+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 ] <forb-server>.so ... [-- <options for forb_main()>] \n");
+       printf("  -d, --daemon [pid-file]   go to background after initialization of servers\n");
+       printf("  -i, --id <orb id>         \n");
+/*     printf("  -l, --loglevel <number>|<domain>=<number>,...\n"); */
+       printf("  -p, --port <number>       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;
+}