From: Michal Sojka Date: Sun, 20 Feb 2011 09:42:58 +0000 (+0100) Subject: forb: Fix synchronization error in forbrun X-Git-Url: http://rtime.felk.cvut.cz/gitweb/frescor/frsh-forb.git/commitdiff_plain/63aeaf83152befc7bb438b04b9921f1988d0011b forb: Fix synchronization error in forbrun 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. --- diff --git a/src/forb/src/forb-internal.h b/src/forb/src/forb-internal.h index a513d93b..2bd141dc 100644 --- a/src/forb/src/forb-internal.h +++ b/src/forb/src/forb-internal.h @@ -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, diff --git a/src/forb/src/forb.c b/src/forb/src/forb.c index 63e51eb7..79759dad 100644 --- a/src/forb/src/forb.c +++ b/src/forb/src/forb.c @@ -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; } diff --git a/src/forb/src/forbrun/forbrun.c b/src/forb/src/forbrun/forbrun.c index 9219cee4..426f773a 100644 --- a/src/forb/src/forbrun/forbrun.c +++ b/src/forb/src/forbrun/forbrun.c @@ -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) diff --git a/src/forb/src/forbrun/tests/forbrun_printargs.c b/src/forb/src/forbrun/tests/forbrun_printargs.c index 86aa4eb7..a28f0e75 100644 --- a/src/forb/src/forbrun/tests/forbrun_printargs.c +++ b/src/forb/src/forbrun/tests/forbrun_printargs.c @@ -1,15 +1,18 @@ #include #include +#include int forb_main(forb_orb orb, int argc, char *argv[]) { - int i; + int i, ret; for (i=0; i