SUBDIRS = tests-idl tests
EXTRA_RULES_SUBDIRS = forb-idl
+CFLAGS += -I.
+
IDL_COMPILER += --pidl
lib_LIBRARIES += forb
config_include_HEADERS = forb/config.h
config_DEFINES = CONFIG_FORB_PROTO_UNIX \
CONFIG_FORB_RECV_BUF_SIZE
+
+include-pass_HOOKS = log_domains.inc request_gavl.inc
+
+log_domains.inc:
+ @echo " UL_LOG $@"
+ $(Q)$(SOURCES_DIR)/ul_log_domains $(SOURCES_DIR) > $@
+
+clean-custom:
+ $(Q)rm log_domains.inc
+
+request_gavl.inc: $(SOURCES_DIR)/request_gavl.c
+ @echo " CPP $@"
+ $(Q)$(c_o_COMPILE) -o $@.tmp -E $<
+ $(Q)tail -n 1 $@.tmp|indent > $@
+
CDR_Codec *c;
c=forb_malloc(sizeof(CDR_Codec));
- CDR_codec_init_static(c);
+ if (c) {
+ CDR_codec_init_static(c);
+ }
return(c);
}
fprintf(of, " } else {\n");
fprintf(of, " /* remote object */\n"
- " CDR_Codec codec;\n"
- " forb_request_t req;\n"
- " CDR_codec_init_static(&codec);\n"
- " ex_on_fail(CDR_buffer_init(&codec, 256, forb_iop_MESSAGE_HEADER_SIZE), FORB_EX_NO_MEMORY);\n");
- fprintf(of, " ex_on_fail(forb_request_init(&req, _obj->orb) == 0, FORB_EX_INTERNAL);\n");
- fprintf(of, " forb_iop_prepare_request(&req, &codec, \"%s\", _obj, FORB_METHOD_INDEX(%s), ev);\n",
+ " forb_request_t req;\n");
+ fprintf(of, " ex_on_fail(forb_request_init(&req, _obj) == 0, FORB_EX_INTERNAL);\n");
+ fprintf(of, " forb_iop_prepare_request(&req, \"%s\", FORB_METHOD_INDEX(%s), ev);\n",
iface_id, opname);
fprintf(of, " if (forb_exception_occured(ev)) goto exception;\n");
for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
fprintf(of, " ex_on_fail(");
forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
- fprintf(of, "_serialize(&codec, %s%s), FORB_EX_IMP_LIMIT);\n",
+ fprintf(of, "_serialize(&req.cdr_request, %s%s), FORB_EX_IMP_LIMIT);\n",
role == DATA_IN ? "&":"",
name);
}
fprintf(of, "_deserialize(req.cdr_reply, %s);\n", name);
}
}
- fprintf(of, "exception:\n"
- " forb_request_signal_processed(&req);\n"
- " forb_request_destroy(&req);\n"
- " CDR_codec_release_buffer(&codec);\n");
+ fprintf(of, " forb_request_signal_processed(&req);\n"
+ "exception:\n"
+ " forb_request_destroy(&req);\n");
fprintf(of, " }\n");
if (has_retval) {
fprintf(of, " return " FORB_RETVAL_VAR_NAME ";\n");
+#define _BSD_SOURCE /* Because of on_exit() */
+#include <stdlib.h>
#include <forb/forb-internal.h>
#include <forb/forb.h>
#include <string.h>
#include <forb/iop.h>
#include <forb/config.h>
#include <forb/proto.h>
+#include <ul_logreg.h>
#ifdef CONFIG_FORB_PROTO_UNIX
#include <forb/proto_unix.h>
#endif
#include <stdio.h>
+#define UL_LOGL_DEF UL_LOGL_ERR
+#include "log_domains.inc"
+
+static void
+destroy_forb_on_exit(int exitcode, void *arg)
+{
+ forb_orb orb = arg;
+ forb_destroy(orb);
+}
+
forb_orb forb_init(void)
{
forb_orb object;
forb_t *forb;
- object = forb_malloc(sizeof(*object));
+ object = forb_object_new(NULL, NULL, 0); /* TODO: Initialize this after forb_t, so that we can fill server_id */
if (!object) goto err;
- memset(object, 0, sizeof(*object));
forb = forb_malloc(sizeof(*forb));
if (!forb) goto err1;
memset(forb, 0, sizeof(*forb));
+
+ /* Initialize ULUT logging facility */
+ ul_logreg_domains_static(ul_log_domains_array,
+ sizeof(ul_log_domains_array)/sizeof(ul_log_domains_array[0]));
object->instance_data = forb;
forb_server_id_init(&forb->server_id);
}
}
#endif
- /* TODO: atexit(destroy_all_forbs); */
+ on_exit(destroy_forb_on_exit, object);
return object;
err2: forb_free(forb);
{
forb_object obj = forb_malloc(sizeof(*obj));
if (obj) {
+ memset(obj, 0, sizeof(*obj));
obj->orb = orb;
if (key == 0) {
obj->objkey = (forb_object_key)(unsigned)obj;
if (server_id) {
obj->server = *server_id;
} else {
- obj->server = forb_obj_to_forb(obj)->server_id;
+ if (orb) {
+ obj->server = forb_obj_to_forb(obj)->server_id;
+ }
}
}
return obj;
* exceptions.
*/
enum forb_exception {
- FORB_EX_NONE,
- FORB_EX_UNKNOWN,
- FORB_EX_BAD_PARAM,
- FORB_EX_NO_MEMORY,
- FORB_EX_IMP_LIMIT,
- FORB_EX_COMM_FAILURE,
- FORB_EX_INV_OBJREF,
- FORB_EX_NO_PERMISSION,
- FORB_EX_INTERNAL,
- FORB_EX_MARSHAL,
- FORB_EX_INITIALIZE,
- FORB_EX_NO_IMPLEMENT,
- FORB_EX_BAD_OPERATION,
- FORB_EX_NO_RESOURCES,
- FORB_EX_NO_RESPONSE,
- FORB_EX_TRANSIENT,
- FORB_EX_FREE_MEM,
- FORB_EX_INV_IDENT,
- FORB_EX_INV_FLAG,
- FORB_EX_DATA_CONVERSION,
- FORB_EX_OBJECT_NOT_EXIST,
- FORB_EX_TIMEOUT,
+ FORB_EX_NONE, /* 0 */
+ FORB_EX_UNKNOWN, /* 1 */
+ FORB_EX_BAD_PARAM, /* 2 */
+ FORB_EX_NO_MEMORY, /* 3 */
+ FORB_EX_IMP_LIMIT, /* 4 */
+ FORB_EX_COMM_FAILURE, /* 5 */
+ FORB_EX_INV_OBJREF, /* 6 */
+ FORB_EX_NO_PERMISSION, /* 7 */
+ FORB_EX_INTERNAL, /* 8 */
+ FORB_EX_MARSHAL, /* 9 */
+ FORB_EX_INITIALIZE, /* 10 */
+ FORB_EX_NO_IMPLEMENT, /* 11 */
+ FORB_EX_BAD_OPERATION, /* 12 */
+ FORB_EX_NO_RESOURCES, /* 13 */
+ FORB_EX_NO_RESPONSE, /* 14 */
+ FORB_EX_TRANSIENT, /* 15 */
+ FORB_EX_FREE_MEM, /* 16 */
+ FORB_EX_INV_IDENT, /* 17 */
+ FORB_EX_INV_FLAG, /* 18 */
+ FORB_EX_DATA_CONVERSION, /* 19 */
+ FORB_EX_OBJECT_NOT_EXIST, /* 20 */
+ FORB_EX_TIMEOUT, /* 21 */
};
struct forb_env {
CORBA_boolean
forb_iop_prepare_request(forb_request_t *req,
- CDR_Codec *codec,
char *iface,
- forb_object obj,
unsigned method_ind,
CORBA_Environment *env)
{
rh.request_id = req->request_id;
rh.iface = iface;
- rh.objkey = forb_object_to_key(obj);
+ rh.objkey = forb_object_to_key(req->obj);
rh.method_index = method_ind;
- ret = forb_iop_request_header_serialize(codec, &rh);
+ rh.source = forb_obj_to_forb(req->obj)->server_id;
+ ret = forb_iop_request_header_serialize(&req->cdr_request, &rh);
return ret;
}
CORBA_boolean
forb_iop_prepare_request(forb_request_t *req,
- CDR_Codec *codec,
char *iface,
- forb_object obj,
unsigned method_ind,
CORBA_Environment *env);
#include <stdio.h>
#include <ul_log.h>
-UL_LOG_CUST(ulogd_proto);
+extern UL_LOG_CUST(ulogd_proto);
GAVL_CUST_NODE_INT_IMP(forb_peer_nolock,/* cust_prefix */
forb_t, /* cust_root_t */
static inline CORBA_boolean
forb_exception_deserialize(CDR_Codec *codec, struct forb_env *env)
{
- /* FIXME: Declare exceptions in IDL and don't typecast here. */
+ /* TODO: Declare exceptions in IDL and don't typecast here. */
return CORBA_long_deserialize(codec, (CORBA_long*)&env->major);
}
peer = forb_get_next_hop(forb, dest);
if (!peer) {
+ ul_logerr("Reply destination not found\n");
goto err;
}
forb_proto_send(peer, codec);
forb_iop_REPLY_HEADER_SIZE);
if (!ret) {
/* Without codec, we cannot send any reply so return silently. */
- ul_logerr("No memory for reply buffer");
+ ul_logerr("No memory for reply buffer\n");
return;
}
goto out;
}
env.major = FORB_EX_NONE;
- /* TODO: Introduce forb_request_processor and acompanying
+ /* TODO: Introduce forb_executor_t and acompanying
* stuff to execute skeletons and implementation in a separate thread. */
obj->interface->skeletons[request_header.method_index](codec, &reply_codec, obj, &env);
out:
forb_iop_reply_header_deserialize(codec, &rh);
req = forb_request_find(forb, &rh.request_id);
if (!req) {
- ul_logerr("Received reply to unknown request_id %ud\n", rh.request_id);
+ ul_logerr("Received reply to unknown request_id %u\n", rh.request_id);
return;
}
if (rh.flags & forb_iop_FLAG_EXCEPTION) {
req->env = env; /* Remember, where to return exceptions */
- ret = forb_iop_prepend_message_header(req->cdr_request, forb_iop_REQUEST);
+ ret = forb_iop_prepend_message_header(&req->cdr_request, forb_iop_REQUEST);
if (!ret) {
/* This should never happen */
env->major = FORB_EX_INTERNAL;
}
peer = forb_get_next_hop(forb, &req->obj->server);
if (!peer) {
+ char str[50];
+ ul_logerr("Cannot find peer for server: %s",
+ forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
env->major = FORB_EX_TRANSIENT;
return;
}
- forb_request_insert(forb, req);
+ ret = forb_request_insert(forb, req);
+ if (ret <= 0) {
+ ul_logerr("Insert request error %d\n", ret);
+ env->major = FORB_EX_INTERNAL;
+ return;
+ }
- size = forb_proto_send(peer, req->cdr_request);
+ size = forb_proto_send(peer, &req->cdr_request);
if (size <= 0) {
forb_request_delete(forb, req);
env->major = FORB_EX_COMM_FAILURE;
#include <forb/forb-internal.h>
#include "syncobj.h"
#include "request.h"
+#include <ul_logbase.h>
+
+extern ul_log_domain_t ulogd_proto;
typedef struct forb_proto forb_proto_t;
typedef struct forb_port forb_port_t;
#include <forb/forb-internal.h>
#include "request.h"
+#include <forb/iop-idl.h>
static inline int forb_request_cmp(CORBA_unsigned_long *a, CORBA_unsigned_long *b)
{
- return (a<b) ? -1 :
- (a>b) ? +1 :
- 0;
+ return (*a<*b) ? -1 :
+ ((*a>*b) ? +1 :
+ 0);
}
+#if 0
GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
forb_t /* cust_root_t */,
forb_request_t /* cust_item_t */,
node /* cust_item_node */,
request_id /* cust_item_key */,
forb_request_cmp/* cust_cmp_fnc */);
-
+#else
+#include "request_gavl.inc"
+#endif
/**
* Initializes @a req structure for sending new request to object @a obj.
forb_request_init(forb_request_t *req, forb_object obj)
{
int ret = 0;
-
forb_t *forb = forb_obj_to_forb(obj);
+ CORBA_boolean bret;
+
+ memset(req, 0, sizeof(*req));
req->obj = obj;
+
fosa_mutex_lock(&forb->id_mutex);
- req->request_id = forb_data(obj->orb)->request_id++;
+ req->request_id = forb->request_id++;
fosa_mutex_unlock(&forb->id_mutex);
+ CDR_codec_init_static(&req->cdr_request);
+ bret = CDR_buffer_init(&req->cdr_request, 256, forb_iop_MESSAGE_HEADER_SIZE);
+ if (bret == CORBA_FALSE) {
+ return FOSA_ENOMEM;
+ }
+
ret = forb_syncobj_init(&req->reply_ready, 0);
return ret;
}
void
forb_request_destroy(forb_request_t *req)
{
+ CDR_codec_release_buffer(&req->cdr_request);
forb_syncobj_destroy(&req->reply_ready);
}
*/
struct forb_request {
CORBA_unsigned_long request_id;
- CDR_Codec *cdr_request;
+ CDR_Codec cdr_request;
CDR_Codec *cdr_reply;
gavl_node_t node;
forb_object obj;
request_id /* cust_item_key */,
forb_request_cmp/* cust_cmp_fnc */);
-static inline void
+static inline int
forb_request_insert(forb_t *forb, forb_request_t *req)
{
+ int ret;
fosa_mutex_lock(&forb->request_mutex);
- forb_request_nolock_insert(forb, req);
+ ret = forb_request_nolock_insert(forb, req);
fosa_mutex_unlock(&forb->request_mutex);
+ return ret;
}
static inline void
--- /dev/null
+#include <ul_gavlcust.h>
+
+GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ forb_request_t /* cust_item_t */,
+ CORBA_unsigned_long /* cust_key_t */,
+ requests /* cust_root_node */,
+ node /* cust_item_node */,
+ request_id /* cust_item_key */,
+ forb_request_cmp/* cust_cmp_fnc */);
SUBDIRS = $(ALL_OMK_SUBDIRS)
-test_PROGRAMS = hello_inproc proto_unix discovery
+test_PROGRAMS = hello_inproc hello_remote proto_unix discovery
CFLAGS += -DTEST
lib_LOADLIBES = forb ulut fosa rt
hello_inproc_CLIENT_IDL = hello.idl
hello_inproc_SERVER_IDL = hello.idl
+hello_remote_SOURCES = hello_remote.c hello_impl.c
+hello_remote_CLIENT_IDL = hello.idl
+hello_remote_SERVER_IDL = hello.idl
+
include_GEN_HEADERS = hello.h
# test_PROGRAMS += hello_client
--- /dev/null
+/**
+ * @file hello_remote.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Sep 25 16:05:27 2008
+ *
+ * @brief Test of remote invocation.
+ *
+ * In this test, two FORBs are created, one for running the server of
+ * hello interface and the second for running the client code. Since
+ * the client and server are registered in different FORBs, remote
+ * communication is used even if the two FORBs share the same
+ * memory. This way we can easily test remote communication without
+ * writing separate applications for client and server.
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb/forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+void *server_thread(void *arg)
+{
+ hello hobj = arg;
+
+ forb_execute_object(hobj);
+ return NULL;
+}
+
+char *start_server()
+{
+ forb_orb orb;
+ hello hobj;
+
+ fosa_thread_id_t tid;
+
+ orb = forb_init();
+ hobj = hello_impl_initialize(orb);
+ fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+ return forb_object_to_string(hobj);
+}
+
+
+
+void client(void *arg)
+{
+ forb_orb orb;
+ hello hobj;
+ struct forb_env env;
+ char *objref = arg;
+
+ orb = forb_init();
+
+ sleep(1); /* Hack to wait for dicovery of the two peers */
+
+ hobj = forb_string_to_object(orb, objref);
+ if (!hobj) {
+ error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+ }
+
+ hello_message(hobj, "Hello world!", &env);
+ if (forb_exception_occured(&env)) {
+ error(1, 0, "FORB exception %d", env.major);
+ }
+
+}
+
+int main(int argc, char *argv[])
+{
+
+ char *objref_str;
+
+ objref_str = start_server();
+
+ client(objref_str);
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+
+DOMAINS=$(find -L $1 '(' -name '*.c' -o -name '*.cc' ')' -exec grep UL_LOG_CUST '{}' ';' | \
+ sed -n -e 's/^.*UL_LOG_CUST(\([^)]*\)).*$/\1/p' | sort -u )
+
+#echo $DOMAINS
+
+#echo -e "#define UL_LOGL_DEF UL_LOGL_DEB\n"
+
+echo "/*"
+echo " * This is generated file, do not edit it directly."
+echo " * Take it from standard output of \"ul_log_domains\""
+echo " * script called in the top level project directory"
+echo " */"
+
+for i in $DOMAINS ; do
+ echo "ul_log_domain_t $i = {UL_LOGL_DEF, \"$(echo -n $i | sed -n -e 's/ulogd_\(.*\)/\1/pg' )\"};"
+done
+
+echo
+echo "ul_log_domain_t *ul_log_domains_array[] = {"
+
+for i in $DOMAINS ; do
+ echo " &$i,"
+done
+
+echo "};"