lib_LIBRARIES += forb
forb_SOURCES = forb.c cdr.c sha1.c uuid.c iop.c proto.c syncobj.c \
- request.c executor.c
+ request.c executor.c object.c
forb_CLIENT_IDL = types.idl iop-idl.idl
to_forb_subdir=$(1)->forb/$(strip $(1))
$(call to_forb_subdir, syncobj.h) \
$(call to_forb_subdir, request.h) \
$(call to_forb_subdir, executor.h) \
+ $(call to_forb_subdir, object.h) \
$(call to_forb_subdir, proto.h)
renamed_include_GEN_HEADERS = \
"#include <forb/basic_types.h>\n"
"\n");
} else {
- fprintf(ci->fh, "#include <forb/forb-internal.h>\n\n");
+ fprintf(ci->fh, "#include <forb/forb-internal.h>\n");
+ fprintf(ci->fh, "#include <forb/object.h>\n\n");
}
fprintf(ci->fh, "#ifdef __cplusplus\n");
fprintf(ci->fh, " .type_hash = 0 /* not implemented */\n");
fprintf(ci->fh, "};\n\n");
- fprintf(ci->fh, "void forb_register_%s_interface(void)\n"
- "{\n"
- " forb_register_interface(&%s_interface);\n"
- "}\n\n", id, id);
+/* fprintf(ci->fh, "void forb_register_%s_interface(void)\n" */
+/* "{\n" */
+/* " forb_register_interface(&%s_interface);\n" */
+/* "}\n\n", id, id); */
fprintf(ci->fh, "%s forb_%s_new(void *instance_data, "
"const struct forb_%s_impl *impl, forb_orb orb)\n"
*
* @brief Declarationd necessary for IDL-generated code.
*
- *
*/
#ifndef FORB_INTERNAL_H
#include <ul_gavlcust.h>
#include <forb/forb.h>
-/** Object reference structure */
-struct forb_object {
- /** @name Fields valid only for implementation */
- /*@{*/
-
- /** Any data for implementation (in server) */
- void *instance_data;
-
- /** Description of interface implemented by this object (for
- * servers); FIXME: What about clients? */
- const forb_interface_t *interface;
-
- /** Pointer to the object implementation methods or NULL in
- * case of remote object. */
- const void *implementation;
- /*@}*/
-
- /** Server implementing this object */
- forb_server_id server;
- /** Object key is just a pointer to the object in the
- * implementation's address space. */
- forb_object_key objkey;
-
- forb_orb orb; /**< FORB reference */
-};
-
-struct forb_interface {
- char *name;
- unsigned num_methods;
- const forb_skel_func *skeletons;
- uint32_t type_hash;
-};
typedef struct forb_rt {
} forb_rt;
struct forb {
forb_server_id server_id;
- fosa_mutex_t id_mutex; /**< Mutex for request_id */
+ fosa_mutex_t request_id_mutex; /**< Mutex for request_id */
CORBA_long request_id; /**< Value of next sent request_id */
+ fosa_mutex_t objkey_mutex; /**< Mutex for objkey and objects */
+ forb_object_key objkey; /**< Objkey value of next created object */
+ gavl_cust_root_field_t objects; /**< Tree of objects registered with this FORB. */
+
//forb_rt rt; /**< Routing table */
//gavl_cust_root_field_t types;
gavl_cust_root_field_t peers;
};
-static inline forb_t *
-forb_data(forb_orb orb)
-{ return forb_instance_data(orb); }
-
-static inline forb_t *
-forb_obj_to_forb(forb_object obj)
-{ return forb_data(obj->orb); }
-
-forb_object_key forb_object_to_key(forb_object obj);
-forb_object forb_key_to_object(forb_object_key key);
-
void
forb_server_id_init(forb_server_id *serer);
return forb_uuid_to_string(dest, (forb_uuid_t*)server_id->uuid, n);
}
+static inline forb_server_id *
+forb_server_id_from_string(forb_server_id *server_id, const char *string)
+{
+ return (forb_server_id *)forb_uuid_from_string((forb_uuid_t*)&server_id->uuid, string);
+}
#endif
#define _BSD_SOURCE /* Because of on_exit() */
#include <stdlib.h>
#include <forb/forb-internal.h>
+#include <forb/object.h>
#include <forb/forb.h>
#include <string.h>
#include <ul_gavlcust.h>
object->instance_data = forb;
forb_server_id_init(&forb->server_id);
- if (fosa_mutex_init(&forb->id_mutex, 0) != 0) goto err2;
+ if (fosa_mutex_init(&forb->request_id_mutex, 0) != 0) goto err2;
if (fosa_mutex_init(&forb->port_mutex, 0) != 0) goto err2;
forb_port_init_head(forb);
if (fosa_mutex_init(&forb->peer_mutex, 0) != 0) goto err2;
forb_peer_nolock_init_root_field(forb);
+ if (fosa_mutex_init(&forb->objkey_mutex, 0) != 0) goto err2;
+ forb_objects_nolock_init_root_field(forb);
+
#ifdef CONFIG_FORB_PROTO_UNIX
{
err: return NULL;
}
+/* FIXME: forb_destroy is now called automatically on exit. Therefore
+ * forb_destroy() should be either static or should deregister on_exit
+ * handler (how???). */
void forb_destroy(forb_orb orb)
{
forb_t *forb = orb->instance_data;
forb_destroy_port(port);
}
forb_free(forb);
- forb_free(orb);
-}
-
-void
-forb_register_interface(const struct forb_interface *interface)
-{
- //gavl_insert(&type_registry, &interface->node);
-}
-
-/**
- * Creates a new object reference.
- *
- * @param orb FORB pseudo object this object reference is handled by.
- *
- * @param server_id Server ID of the FORB, where this object is
- * implemented or NULL if the object is implemented by @a orb.
- *
- * @param key Key of the remote object or zero if the object is
- * implemented by @a orb.
- *
- * @return FORB object reference of NULL in case of error.
- */
-forb_object
-forb_object_new(forb_orb orb,
- forb_server_id *server_id,
- forb_object_key key)
-{
- forb_object obj = forb_malloc(sizeof(*obj));
- if (obj) {
- memset(obj, 0, sizeof(*obj));
- obj->orb = orb;
- if (key == 0) {
-#warning Rework objkeys to something different than address
- obj->objkey = (forb_object_key)(unsigned)obj;
- } else {
- obj->objkey = key;
- }
- if (server_id) {
- obj->server = *server_id;
- } else {
- if (orb) {
- obj->server = forb_obj_to_forb(obj)->server_id;
- }
- }
- }
- return obj;
-}
-
-/**
- * Releases all memory associated with a object reference.
- *
- * @param obj Object reference to release
- */
-void forb_object_release(forb_object obj)
-{
- forb_free(obj);
+ forb_object_release(orb);
}
-forb_object_key forb_object_to_key(forb_object obj)
-{
- return obj->objkey;
-}
-
-forb_object forb_key_to_object(forb_object_key key)
-{
- forb_object obj;
- obj = (forb_object)(unsigned)key;
- return obj;
-}
+/* void */
+/* forb_register_interface(const struct forb_interface *interface) */
+/* { */
+/* gavl_insert(&type_registry, &interface->node); */
+/* } */
void
forb_server_id_init(forb_server_id *server_id)
forb_uuid_generate((forb_uuid_t*)server_id->uuid);
}
-forb_server_id *
-forb_server_id_from_string(forb_server_id *server_id, const char *string)
-{
- return (forb_server_id *)forb_uuid_from_string((forb_uuid_t*)&server_id->uuid, string);
-}
-
-/**
- * Converts object reference to string.
- *
- * @param obj Object reference to convert.
- *
- * @return String, which must be freed by forb_free() or NULL in case
- * of error.
- */
-char *
-forb_object_to_string(const forb_object obj)
-{
- char *str;
- size_t s;
- forb_object_key key;
- char server_id[65];
-
- s = 2*sizeof(forb_server_id)+1+2*sizeof(size_t)+1;
- str = malloc(s);
- if (!str) {
- return NULL;
- }
-
- forb_server_id_to_string(server_id, &obj->server, s);
- key = forb_object_to_key(obj);
- snprintf(str, s, "%s-%llx", server_id, key);
-
- return str;
-}
-
-/**
- * Creates object reference from string.
- *
- * The string should be generated by forb_object_to_string() in the
- * same or another FORB. When the returned reference is not needed, it
- * should be freed by forb_object_release().
- *
- * @param orb FORB which should handle the object.
- * @param string The string returned by forb_object_to_string().
- *
- * @return FORB object reference or NULL in case of error.
- */
-forb_object
-forb_string_to_object(const forb_orb orb, const char *string)
-{
- forb_object obj;
- forb_object_key key;
- forb_server_id server_id;
- int ret;
-
- if (forb_server_id_from_string(&server_id, string) == NULL)
- return NULL;
-
- if (string[2*sizeof(server_id)] != '-')
- return NULL;
-
- ret = sscanf(&string[2*sizeof(server_id)+1], "%llx", &key);
- if (ret == 0 || ret == EOF)
- return NULL;
-
- obj = forb_object_new(orb, &server_id, key);
-
- return obj;
-}
struct forb_object;
-#define forb_instance_data(obj) ((obj)->instance_data)
-
#define FORB_METHOD_INDEX(m) (m ## __method_index)
/**
* Deallocates all resources consumed by FORB.
+ *
+ * @note Called automatically on application exit.
*
* @param orb FORB object reference to destroy.
*/
forb_server_id *server_id,
forb_object_key key);
void
-forb_object_destroy(forb_object obj);
+forb_object_release(forb_object obj);
void
-forb_register_reference(const char *id, forb_object object);
+forb_register_reference(const forb_orb orb, const char *id, forb_object object);
forb_object
-forb_resolve_reference(const char *id);
-
-void
-forb_register_interface(const struct forb_interface *interface);
+forb_resolve_reference(const forb_orb orb, const char *id);
forb_object
forb_string_to_object(const forb_orb orb, const char *string);
*/
#include <forb/iop.h>
#include <forb/cdr.h>
+#include <forb/object.h>
/** Version of the protocol */
#define VER_MAJOR 0
rh.iface = iface;
rh.objkey = forb_object_to_key(req->obj);
rh.method_index = method_ind;
- rh.source = forb_obj_to_forb(req->obj)->server_id;
+ rh.source = forb_object_to_forb(req->obj)->server_id;
ret = forb_iop_request_header_serialize(&req->cdr_request, &rh);
return ret;
}
--- /dev/null
+#include <forb/forb-internal.h>
+#include <forb/object.h>
+#include <stdio.h>
+
+GAVL_CUST_NODE_INT_IMP(forb_objects_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ struct forb_object /* cust_item_t */,
+ forb_object_key /* cust_key_t */,
+ objects /* cust_root_node */,
+ node /* cust_item_node */,
+ objkey /* cust_item_key */,
+ forb_objkey_cmp/* cust_cmp_fnc */);
+
+/**
+ * Creates a new object reference.
+ *
+ * @param orb FORB pseudo object this object reference is handled
+ * by. This can be NULL only when forb_orb reference is created in
+ * forb_init().
+ *
+ * @param server_id Server ID of the FORB, where this object is
+ * implemented or NULL if the object is implemented by @a orb.
+ *
+ * @param key Key of the remote object. If server_id is NULL this
+ * value is ignored and new objkey is allocated.
+ *
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_object
+forb_object_new(forb_orb orb,
+ forb_server_id *server_id,
+ forb_object_key key)
+{
+ forb_object obj = forb_malloc(sizeof(*obj));
+ if (obj) {
+ memset(obj, 0, sizeof(*obj));
+ obj->orb = orb;
+ if (server_id) {
+ obj->server = *server_id;
+ obj->objkey = key;
+ } else {
+ if (orb) {
+ forb_t *forb = forb_object_to_forb(obj);
+ obj->server = forb->server_id;
+ fosa_mutex_lock(&forb->objkey_mutex);
+ obj->objkey = ++forb->objkey;
+ forb_objects_nolock_insert(forb, obj);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+ }
+ }
+ }
+ return obj;
+}
+
+/**
+ * Releases all memory associated with a object reference and
+ * deregister the object from FORB.
+ *
+ * @param obj Object reference to release
+ */
+void forb_object_release(forb_object obj)
+{
+ if (obj->orb) {
+ forb_t *forb = forb_object_to_forb(obj);
+ forb_objects_delete(forb, obj);
+ }
+ forb_free(obj);
+}
+
+forb_object_key forb_object_to_key(forb_object obj)
+{
+ return obj->objkey;
+}
+
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key)
+{
+ forb_object obj;
+ obj = forb_objects_find(forb, key);
+ return obj;
+}
+
+/**
+ * Converts object reference to string.
+ *
+ * @param obj Object reference to convert.
+ *
+ * @return String, which must be freed by forb_free() or NULL in case
+ * of error.
+ */
+char *
+forb_object_to_string(const forb_object obj)
+{
+ char *str;
+ size_t s;
+ forb_object_key key;
+ char server_id[65];
+
+ s = 2*sizeof(forb_server_id)+1+2*sizeof(size_t)+1;
+ str = malloc(s);
+ if (!str) {
+ return NULL;
+ }
+
+ forb_server_id_to_string(server_id, &obj->server, s);
+ key = forb_object_to_key(obj);
+ snprintf(str, s, "%s-%llx", server_id, key);
+
+ return str;
+}
+
+/**
+ * Creates object reference from string.
+ *
+ * The string should be generated by forb_object_to_string() in the
+ * same or another FORB. When the returned reference is not needed, it
+ * should be freed by forb_object_release().
+ *
+ * @param orb FORB which should handle the object.
+ * @param string The string returned by forb_object_to_string().
+ *
+ * @return FORB object reference or NULL in case of error.
+ */
+forb_object
+forb_string_to_object(const forb_orb orb, const char *string)
+{
+ forb_object obj;
+ forb_object_key key;
+ forb_server_id server_id;
+ int ret;
+
+ if (forb_server_id_from_string(&server_id, string) == NULL)
+ return NULL;
+
+ if (string[2*sizeof(server_id)] != '-')
+ return NULL;
+
+ ret = sscanf(&string[2*sizeof(server_id)+1], "%llx", &key);
+ if (ret == 0 || ret == EOF)
+ return NULL;
+
+ obj = forb_object_new(orb, &server_id, key);
+
+ return obj;
+}
--- /dev/null
+#ifndef FORB_OBJECT_H
+#define FORB_OBJECT_H
+
+#include <ul_gavlcust.h>
+#include <forb/forb-internal.h>
+
+/** Object reference structure */
+struct forb_object {
+ /** @name Fields valid only for implementation */
+ /*@{*/
+
+ /** Any data for implementation (in server) */
+ void *instance_data;
+
+ /** Description of interface implemented by this object (for
+ * servers); FIXME: What about clients? */
+ const forb_interface_t *interface;
+
+ /** Pointer to the object implementation methods or NULL in
+ * case of remote object. */
+ const void *implementation;
+
+ gavl_node_t node; /**< Node for forb->objects tree */
+ /*@}*/
+
+ /** Server implementing this object */
+ forb_server_id server;
+ /** Object key is just a pointer to the object in the
+ * implementation's address space. */
+ forb_object_key objkey;
+
+ forb_orb orb; /**< FORB reference */
+};
+
+struct forb_interface {
+ char *name;
+ unsigned num_methods;
+ const forb_skel_func *skeletons;
+ uint32_t type_hash;
+};
+
+#define forb_object_instance_data(obj) ((obj)->instance_data)
+
+/** Return forb_t from an object reference. */
+static inline forb_t *
+forb_data(forb_orb orb)
+{ return forb_object_instance_data(orb); }
+
+
+static inline forb_t *
+forb_object_to_forb(forb_object obj)
+{ return forb_data(obj->orb); }
+
+forb_object_key forb_object_to_key(forb_object obj);
+forb_object forb_key_to_object(forb_t *forb, forb_object_key key);
+
+static inline int forb_objkey_cmp(forb_object_key *a, forb_object_key *b)
+{
+ return (*a<*b) ? -1 :
+ ((*a>*b) ? +1 :
+ 0);
+}
+
+/* Declaration of typesafe function for storing objects in GAVL tree
+ * ordered by object keys. */
+GAVL_CUST_NODE_INT_DEC(forb_objects_nolock /* cust_prefix */,
+ forb_t /* cust_root_t */,
+ struct forb_object /* cust_item_t */,
+ forb_object_key /* cust_key_t */,
+ objects /* cust_root_node */,
+ node /* cust_item_node */,
+ objkey /* cust_item_key */,
+ forb_objkey_cmp/* cust_cmp_fnc */);
+
+
+static inline void
+forb_objects_delete(forb_t *forb, forb_object obj)
+{
+ fosa_mutex_lock(&forb->objkey_mutex);
+ forb_objects_nolock_delete(forb, obj);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+}
+
+static inline forb_object
+forb_objects_find(forb_t *forb, forb_object_key objkey)
+{
+ forb_object ret;
+ fosa_mutex_lock(&forb->objkey_mutex);
+ ret = forb_objects_nolock_find(forb, &objkey);
+ fosa_mutex_unlock(&forb->objkey_mutex);
+ return ret;
+}
+
+#endif
#include <forb/config.h>
#include <stdio.h>
#include <ul_log.h>
+#include <forb/object.h>
extern UL_LOG_CUST(ulogd_proto);
CORBA_boolean ret;
forb_object obj;
size_t n;
+ forb_t *forb = port->forb;
struct forb_env env;
CDR_codec_init_static(&reply_codec);
goto out;
}
- obj = forb_key_to_object(request_header.objkey);
+ obj = forb_key_to_object(forb, request_header.objkey);
n = strlen(request_header.iface);
if (strncmp(request_header.iface, obj->interface->name, n) != 0) {
env.major = FORB_EX_INV_OBJREF;
CORBA_boolean ret;
forb_peer_t *peer;
size_t size;
- forb_t *forb = forb_obj_to_forb(req->obj);
+ forb_t *forb = forb_object_to_forb(req->obj);
if (!forb) {
env->major = FORB_EX_INTERNAL;
return;
#include <forb/forb-internal.h>
#include "request.h"
#include <forb/iop-idl.h>
+#include <forb/object.h>
static inline int forb_request_cmp(CORBA_unsigned_long *a, CORBA_unsigned_long *b)
{
forb_request_init(forb_request_t *req, forb_object obj)
{
int ret = 0;
- forb_t *forb = forb_obj_to_forb(obj);
+ forb_t *forb = forb_object_to_forb(obj);
CORBA_boolean bret;
memset(req, 0, sizeof(*req));
req->obj = obj;
- fosa_mutex_lock(&forb->id_mutex);
+ fosa_mutex_lock(&forb->request_id_mutex);
req->request_id = forb->request_id++;
- fosa_mutex_unlock(&forb->id_mutex);
+ fosa_mutex_unlock(&forb->request_id_mutex);
CDR_codec_init_static(&req->cdr_request);
bret = CDR_buffer_init(&req->cdr_request, 256, forb_iop_MESSAGE_HEADER_SIZE);
#include <stdbool.h>
#include <forb/forb.h>
+#include <forb/object.h>
#include <forb/forb-internal.h>
#include <forb/config.h>
#include <unistd.h>
}
}
- for (i=0; i<NUM_ORBS; i++) {
- forb_destroy(orb[i]);
- }
-
return 0;
}
forb_object hello_impl_initialize(forb_orb orb)
{
- forb_register_hello_interface();
return forb_hello_new(NULL, &impl, orb);
}