]> rtime.felk.cvut.cz Git - frescor/forb.git/commitdiff
forb: Fix synchronization error in forbrun
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 20 Feb 2011 09:42:58 +0000 (10:42 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 20 Feb 2011 10:00:48 +0000 (11:00 +0100)
forbrun starts servers synchronously, i.e. the next server is started
only after the previous one is fully initialized (see
forb_signal_server_ready()). This synchronization was broken because
forb_signal_server_ready() was incorrectly called in
forb_execute_object() called from forb_execution_thread() called from
forb_init(). This caused that the semaphore for the synchronization had
the value of one (instead of zero) when forb_init() finished.
Therefore, the first waiting for the semaphore returned immediately
without actually waiting for the server.

This is now fixed by introduction of default_executor which is declared
in struct forb. This executor is initialized "manually", without
forb_execute_object(), so that the forb_signal_server_ready() is not
called.

In future, we might want use the default executor for executing requests
to other objects, which do not require a separate thread.

src/forb-internal.h
src/forb.c
src/forbrun/forbrun.c
src/forbrun/tests/forbrun_printargs.c

index a513d93b38b421dd87648d3a9a4a89256dcdb74e..2bd141dc03972755a4338dabe2f7512b99fc189a 100644 (file)
@@ -113,7 +113,8 @@ typedef struct forb {
        fosa_mutex_t regref_mutex;
        gavl_cust_root_field_t regrefs; /**< Container for ::forb_regref_t */
 
-       fosa_thread_id_t execution_thread; /**< Thread which executes remote requests for this forb::orb interface. */
+       fosa_thread_id_t execution_thread; /**< Thread which runs @a default_executor. */
+       forb_executor_t default_executor; /**< Executor that executes remote requests for this forb::orb interface. */
 } forb_t;
 
 typedef void (*forb_skel_func)(FORB_CDR_Codec *cin,
index 63e51eb72979063cfb3fb02a4001d9dc6a97cee7..79759dad948213d0dc3f15231c243d9983df43c3 100644 (file)
@@ -150,9 +150,8 @@ forb_init_tmp_dir(void)
 static void *
 forb_execution_thread(void *arg)
 {
-       forb_orb orb = arg;
-
-       forb_execute_object(orb);
+       forb_executor_t *executor = arg;
+       forb_executor_run(executor);
        return NULL;
 }
 
@@ -236,10 +235,15 @@ forb_init(int *argc, char **argv[], const struct forb_init_attr *attr)
         * can accept remote request to our new ORB. */
        forb_objects_nolock_insert(forb, orb);
 
+       ret = forb_executor_init(&forb->default_executor);
+       if (ret) goto err2;
+       ret = forb_executor_register_object(&forb->default_executor, orb);
+       if (ret) goto err3;
+
        ret = fosa_thread_create(&forb->execution_thread, NULL,
-                                forb_execution_thread, orb);
+                                forb_execution_thread, &forb->default_executor);
        if (ret != 0)
-               goto err2;
+               goto err3;
 
        /* FIXME: I do not know how to deregister the exit handler if
         * forb_destroy() is called manually. */
@@ -258,7 +262,7 @@ forb_init(int *argc, char **argv[], const struct forb_init_attr *attr)
                }
        err_free_unix:
                free(port);
-               goto err2;
+               goto err3;
        unix_ok:;
        }
 #endif
@@ -279,13 +283,14 @@ forb_init(int *argc, char **argv[], const struct forb_init_attr *attr)
                }
        err_free_inet:
                free(port);
-               goto err2;
+               goto err3;
        inet_ok:;
                hack_register_fcb(orb, port);
        }
 #endif
        return orb;
 
+err3:   forb_executor_destroy(&forb->default_executor);
 err2:  forb_free(forb);
 err:   return NULL;
 }
index 9219cee4da3893b60d378b8881fc6ec1c96db62a..426f773ae1f0a283f4793ca4a4981f1a5efe1417 100644 (file)
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
        forb_orb orb;
        bool opt_daemon = false;
        char *opt_pidfile = NULL;
-       int i;
+       int i, ret;
        forb_init_attr_t attr = {
                .orb_id = "",
                .peer_discovery_callback = NULL, /* TODO */
@@ -80,7 +80,6 @@ int main(int argc, char *argv[])
                                        exit(0);
                                }
                                {
-                                       int ret;
                                        ret = ul_log_domain_arg2levels(optarg);
                                        if (ret) 
                                                error(1, EINVAL, "Error parsing -l argument at char %d\n", ret);
@@ -142,7 +141,9 @@ int main(int argc, char *argv[])
                fosa_thread_create(&tid, NULL, forb_main_thread, data);
                libs_loaded_cnt++;
 
-               forb_wait_for_server_ready(orb);
+               ret = forb_wait_for_server_ready(orb);
+               if (ret)
+                       error(1, errno, "forb_wait_for_server_ready");
        }
 
        if (opt_daemon)
index 86aa4eb7d9e9af3f536f37af6274ccfda521558e..a28f0e7573ab1412298297d176be4513876262a8 100644 (file)
@@ -1,15 +1,18 @@
 #include <forb.h>
 #include <stdio.h>
+#include <error.h>
 
 int forb_main(forb_orb orb, int argc, char *argv[])
 {
-       int i;
+       int i, ret;
        for (i=0; i<argc; i++)
                printf("%s%s", argv[i], i+1 < argc ? " " : "");
        printf("\n");
        if (argc < 2 || strcmp(argv[1], "--exit") != 0) {
                /* Allow starting the next shared library */
-               forb_signal_server_ready(orb);
+               ret = forb_signal_server_ready(orb);
+               if (ret)
+                       error(1, errno, "forb_signal_server_ready");
                /* Exit only this thread, not the whole forbrun */
                pthread_exit(0);
        }