/* fprintf(of, " return "FORB_RETVAL_VAR_NAME";\n"); */
/* } */
fprintf(of, " if (ev) ev->major = FORB_EX_NONE;\n");
- fprintf(of, " if (forb_object_is_local(_obj)) {\n");
+ fprintf(of, " if (forb_object_is_local(_obj) &&\n"
+ "forb_get_current_executor() == forb_object_get_executor(_obj)) {\n");
fprintf(of, " if (!_obj->interface ||\n"
" strncmp(_obj->interface->name, \"%s\", %zd) != 0) {\n"
" ev->major = FORB_EX_BAD_OPERATION;\n"
/**
* Determines the executor we are currently in.
*
- * @param executor Current executor pointer.
- *
- * @return Zero in case of success.
+ * @return Pointer to the current executor or NULL if not called
+ * within executor.
*/
-int forb_get_current_executor(forb_executor_t **executor)
+forb_executor_t *forb_get_current_executor(void)
{
- int ret = 0;
- *executor = (void *) pthread_getspecific(forb_executor_key);
-
- if (!(*executor))
- ret = 1;
- return ret;
+ return pthread_getspecific(forb_executor_key);
}
int forb_executor_run(forb_executor_t *executor);
int forb_execute_object(forb_object obj);
-int forb_get_current_executor(forb_executor_t **executor);
+forb_executor_t *forb_get_current_executor(void);
#endif
--- /dev/null
+# 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
+
--- /dev/null
+wvtest_PROGRAMS = executor_test
+executor_test_SOURCES = executor_test.c
+executor_test_SERVER_IDL = executor_test.idl
+executor_test_CLIENT_IDL = executor_test.idl
+
+INCLUDES += -I.
+
+lib_LOADLIBES = forb ulut fosa rt wvtest
--- /dev/null
+#include <forb.h>
+#include <executor_test.h>
+#define WVTEST_CONFIGURED
+#include <wvtest.h>
+#include <forb/executor.h>
+#include <forb/object.h>
+
+static CORBA_long add(executor_test obj, CORBA_long val, CORBA_Environment *ev)
+{
+ int to_add = (intptr_t)forb_object_instance_data(obj);
+ return val + to_add;
+}
+
+static CORBA_long add_indirect(executor_test obj, executor_test indirect_obj, CORBA_long val, CORBA_Environment *ev)
+{
+ return executor_test_add(indirect_obj, val, ev);
+}
+
+static const struct forb_executor_test_impl executor_test_impl = {
+ .add = add,
+ .add_indirect = add_indirect,
+};
+
+
+void *executor_thread(void *arg)
+{
+ forb_executor_t *executor = arg;
+ forb_executor_run(executor);
+ return NULL;
+}
+
+WVTEST_MAIN("remote (inter-server) invocation")
+{
+ forb_orb orb1, orb2;
+ fosa_thread_id_t tid;
+ executor_test testobj, remote_obj;
+ forb_executor_t executor;
+ char *str;
+ struct forb_env env;
+
+ /* Create the first FORB server */
+ WVPASS(orb1 = forb_init(NULL, NULL,
+ &(struct forb_init_attr){.orb_id = "server1"}));
+
+ /* This object adds 1 to the argument of add() */
+ WVPASS(testobj = forb_executor_test_new(orb1, &executor_test_impl, (void*)1));
+ WVPASSEQ(forb_executor_init(&executor), 0);
+ WVPASSEQ(forb_executor_register_object(&executor, testobj), 0);
+
+ /* Execute executor in a separate thread */
+ fosa_thread_create(&tid, NULL, executor_thread, &executor);
+
+ /* Create the second FORB server in the same process */
+ WVPASS(orb2 = forb_init(NULL, NULL,
+ &(struct forb_init_attr){.orb_id = "server2"}));
+
+ str = forb_object_to_string(testobj);
+ remote_obj = forb_string_to_object(orb2, str);
+
+ WVPASS(forb_object_is_local(testobj));
+ WVFAIL(forb_object_is_local(remote_obj));
+
+ /* Remote invocation of the object */
+ WVPASSEQ(executor_test_add(remote_obj, 1, &env), 2);
+ WVFAIL(forb_exception_occurred(&env));
+}
+
+WVTEST_MAIN("inter_thread_invocation")
+{
+ forb_orb orb;
+ fosa_thread_id_t tid1, tid2;
+ executor_test testobj1, testobj2;
+ forb_executor_t executor1, executor2;
+ struct forb_env env;
+
+ /* Create the first FORB server */
+ WVPASS(orb = forb_init(NULL, NULL,
+ &(struct forb_init_attr){.orb_id = "server"}));
+
+ /* This object adds 1 to the argument of add() */
+ WVPASS(testobj1 = forb_executor_test_new(orb, &executor_test_impl, (void*)1));
+ WVPASSEQ(forb_executor_init(&executor1), 0);
+ WVPASSEQ(forb_executor_register_object(&executor1, testobj1), 0);
+
+ /* This object adds 2 to the argument of add() */
+ WVPASS(testobj2 = forb_executor_test_new(orb, &executor_test_impl, (void*)2));
+ WVPASSEQ(forb_executor_init(&executor2), 0);
+ WVPASSEQ(forb_executor_register_object(&executor2, testobj2), 0);
+
+ /* Execute executors in separate threads */
+ fosa_thread_create(&tid1, NULL, executor_thread, &executor1);
+ fosa_thread_create(&tid2, NULL, executor_thread, &executor2);
+
+ WVPASS(forb_object_is_local(testobj1));
+ WVPASS(forb_object_is_local(testobj2));
+
+ /* Inter-thread invocation: application->executor */
+ WVPASSEQ(executor_test_add(testobj1, 1, &env), 2);
+ WVFAIL(forb_exception_occurred(&env));
+
+ /* Inter-thread invocation: (application->)executor->executor */
+ WVPASSEQ(executor_test_add_indirect(testobj1, testobj2, 1, &env), 3);
+ WVFAIL(forb_exception_occurred(&env));
+
+ /* Direct invocation in the same executor: (application->)executor->executor */
+ WVPASSEQ(executor_test_add_indirect(testobj1, testobj1, 1, &env), 2);
+ WVFAIL(forb_exception_occurred(&env));
+}
--- /dev/null
+interface executor_test {
+ // Adds some number the value @a val
+ long add(in long val);
+ // Adds some number the value @a val by calling @a add method of indirect_obj
+ long add_indirect(in executor_test indirect_obj, in long val);
+};
}
// ------------------------------------------------------
- if (forb_get_current_executor(&executor)) {
+ if ((executor = forb_get_current_executor())) {
printf("Test: Error while getting current executor\n");
if (executor == NULL)
printf("Test: Executor: NULL\n");
* Licensed under the GNU Library General Public License, version 2.
* See the included file named LICENSE for license information.
*/
+#define _GNU_SOURCE
#include "wvtest.h"
#include <stdio.h>
#include <string.h>
bool wvtest_start_check_eq(const char *file, int line,
- int a, int b, bool expect_pass)
+ int a, int b, bool expect_pass,
+ const char *a_str, const char *b_str)
+{
+ char *str;
+ char sa[20], sb[20];
+ char *a_op = " == ", *b_op = " == ";
+ sprintf(sa, "%d", a);
+ sprintf(sb, "%d", b);
+ if (strcmp(sa, a_str) == 0)
+ a_str = a_op = "";
+ if (strcmp(sb, b_str) == 0)
+ b_str = b_op = "";
+ asprintf(&str, "%s%s%d %s %s%s%d", a_str, a_op, a, expect_pass ? "==" : "!=",
+ b_str, b_op, b);
+
+ wvtest_start(file, line, str);
+ free(str);
+
+ bool cond = (a == b);
+ if (!expect_pass)
+ cond = !cond;
+
+ wvtest_check(cond, NULL);
+ return cond;
+}
+
+bool wvtest_start_check_eq_ptr(const char *file, int line,
+ void *a, void *b, bool expect_pass)
{
size_t len = 11 + 11 + 8 + 1;
char *str = malloc(len);
- sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b);
+ sprintf(str, "%p %s %p", a, expect_pass ? "==" : "!=", b);
wvtest_start(file, line, str);
free(str);
const char *condstr, bool cond)
{ wvtest_start(file, line, condstr); wvtest_check(cond, NULL); return cond; }
bool wvtest_start_check_eq(const char *file, int line,
- int a, int b, bool expect_pass);
+ int a, int b, bool expect_pass,
+ const char *a_str, const char *b_str);
bool wvtest_start_check_lt(const char *file, int line,
int a, int b);
+bool wvtest_start_check_eq_ptr(const char *file, int line,
+ void *a, void *b, bool expect_pass);
bool wvtest_start_check_eq_str(const char *file, int line,
const char *a, const char *b, bool expect_pass);
bool wvtest_start_check_lt_str(const char *file, int line,
#define WVPASS(cond) \
wvtest_start_check(__FILE__, __LINE__, #cond, (cond))
#define WVPASSEQ(a, b) \
- wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), true)
+ wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), true, #a, #b)
#define WVPASSLT(a, b) \
wvtest_start_check_lt(__FILE__, __LINE__, (a), (b))
+#define WVPASSEQPTR(a, b) \
+ wvtest_start_check_eq_ptr(__FILE__, __LINE__, (a), (b), true)
+#define WVFAILEQPTR(a, b) \
+ wvtest_start_check_eq_ptr(__FILE__, __LINE__, (a), (b), false)
#define WVPASSEQSTR(a, b) \
wvtest_start_check_eq_str(__FILE__, __LINE__, (a), (b), true)
#define WVPASSLTSTR(a, b) \
#define WVFAIL(cond) \
wvtest_start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond))
#define WVFAILEQ(a, b) \
- wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), false)
+ wvtest_start_check_eq(__FILE__, __LINE__, (a), (b), false, #a, #b)
#define WVFAILEQSTR(a, b) \
- wvtest_start_check_eq_str(__FILE__, __LINE__, (a), (b), false)
+ wvtest_start_check_eq_str(__FILE__, __LINE__, (a), (b), false)
#define WVPASSNE(a, b) WVFAILEQ(a, b)
#define WVPASSNESTR(a, b) WVFAILEQSTR(a, b)
#define WVFAILNE(a, b) WVPASSEQ(a, b)