]> rtime.felk.cvut.cz Git - frescor/forb.git/commitdiff
Added preliminary implementation of remote request handling
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 14 Sep 2008 21:28:22 +0000 (23:28 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 14 Sep 2008 21:28:22 +0000 (23:28 +0200)
forb-idl.idl
forb.c
proto.c
tests/discovery.c

index 3f39f9ef859f5b6073c9da72b23b697b154098e8..e4780158f20360f058c12b0c6ba0466081c6dfc1 100644 (file)
@@ -36,13 +36,14 @@ module forb {
                        string iface;
                        object_key objkey;
                        short method_index;
+                       server_id source; ///< Server ID of request originator
                };
 
-               typedef short reply_flags;
+               typedef unsigned short reply_flags;
                const reply_flags FLAG_EXCEPTION = 1;
                struct reply_header {
                        unsigned long request_id;
-                       unsigned short flags;
+                       reply_flags flags;
                };
                const long REPLY_HEADER_SIZE = 8;
 
diff --git a/forb.c b/forb.c
index a74feb39cf134c4fa0e9b8cd7cc5690677c8cca9..853f4fbbcc2af6190a2a632a2d71f43c5cc86e4b 100644 (file)
--- a/forb.c
+++ b/forb.c
@@ -111,12 +111,12 @@ forb_new_request(forb_request_t *req, forb_object obj)
  *
  * The request @a req has to be prepared by
  * forb_iop_prepare_request(). Then, this function adds a message
- * header connects to the destination FORB and sends the request.
+ * header, connects to the destination FORB and sends the request.
  *
- * If no exceptionis reported, ten caller must wait for response by
- * calling forb_wait_for_reply().
+ * If no exception is reported, then the caller must wait for response
+ * by calling forb_wait_for_reply().
  * 
- * @param req Request prepared by forb_iop_prepare_request()
+ * @param req A request prepared by forb_iop_prepare_request()
  * @param env Environment for returning exceptions
  */
 void
@@ -132,7 +132,7 @@ forb_send_request(forb_request_t *req, CORBA_Environment *env)
                return;
        }
        ret = forb_iop_prepend_message_header(req->codec, forb_iop_REQUEST);
-       if (!ret || !forb) {
+       if (!ret) {
                /* This should never happen */
                env->major = FORB_EX_INTERNAL;
                return;
@@ -163,7 +163,6 @@ forb_send_request(forb_request_t *req, CORBA_Environment *env)
                env->major = FORB_EX_COMM_FAILURE;
        }
 exception:
-       //forb_put_connection(conn);
        ;
 }
 
diff --git a/proto.c b/proto.c
index b3b0592706e0eef760c0655c45ec45c2feee2044..66897ddbfd23a86c70ee4278263673f70339061d 100644 (file)
--- a/proto.c
+++ b/proto.c
@@ -1,5 +1,6 @@
 #include <forb/proto.h>
 #include <forb/forb-idl.h>
+#include <forb/forb-internal.h>
 #include <forb/iop.h>
 #include <forb/config.h>
 #include <stdio.h>
@@ -11,14 +12,94 @@ GAVL_CUST_NODE_INT_IMP(forb_peer_nolock,/* cust_prefix */
                       peers,           /* cust_root_node */
                       node,            /* cust_item_node */
                       server_id,       /* cust_item_key */
-                      forb_server_id_cmp)/* cust_cmp_fnc */
+                      forb_server_id_cmp);/* cust_cmp_fnc */
+
+static inline CORBA_boolean
+forb_exception_serialize(CDR_Codec *codec, struct forb_env *env)
+{
+       return CORBA_long_serialize(codec, &env->major);
+}
+
+static void
+send_reply(forb_t *forb,
+          forb_server_id *dest,
+          CDR_Codec *codec,
+          CORBA_long request_id,
+          struct forb_env *env)
+{
+       forb_iop_reply_header reply_header;
+       CORBA_boolean ret;
+       forb_peer_t *peer;
+       
+       reply_header.request_id = request_id;
+       reply_header.flags = 0;
+       if (forb_exception_occured(env)) {
+               reply_header.flags |= forb_iop_FLAG_EXCEPTION;
+               forb_exception_serialize(codec, env);
+       }
+       ret = CDR_buffer_prepend(codec, forb_iop_REPLY_HEADER_SIZE);
+       if (!ret) {
+               goto err;
+       }
+       ret = forb_iop_reply_header_serialize(codec, &reply_header);
+       if (!ret) {
+               goto err;
+       }
+       forb_iop_prepend_message_header(codec, forb_iop_REPLY);
+
+       peer = forb_get_next_hop(forb, dest);
+       if (!peer) {
+               goto err;
+       }
+       forb_proto_send(peer, codec);
+err:
+       ;
+}
 
 
 static void
 process_request(forb_port_t *port, CDR_Codec *codec)
 {
-       forb_iop_request_header rh;
-       forb_iop_request_header_deserialize(codec, &rh);
+       forb_iop_request_header request_header;
+       CDR_Codec reply_codec;
+       CORBA_boolean ret;
+       forb_object obj;
+       size_t n;
+       struct forb_env env;
+               
+       CDR_codec_init_static(&reply_codec);    
+       ret = CDR_buffer_init(&reply_codec, 4096,
+                             forb_iop_MESSAGE_HEADER_SIZE +
+                             forb_iop_REPLY_HEADER_SIZE);
+       if (!ret)
+               return;
+       
+       ret = forb_iop_request_header_deserialize(codec, &request_header);
+       if (!ret) {
+               printf("ERR1\n");
+               env.major = FORB_EX_NO_MEMORY;
+               goto out;
+       } 
+       
+       obj = forb_key_to_object(request_header.objkey);
+       n = strlen(request_header.iface);
+       if (strncmp(request_header.iface, obj->interface->name, n) != 0) {
+               env.major = FORB_EX_INV_OBJREF;
+               printf("ERR2\n");
+               goto out;
+       }
+       if (request_header.method_index >= obj->interface->num_methods) {
+               env.major = FORB_EX_INV_OBJREF;
+               printf("ERR3\n");
+               goto out;
+       }
+       env.major = FORB_EX_NONE;
+       /* TODO: Introduce forb_request_processor 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:
+       send_reply(port->forb, &request_header.source, &reply_codec, request_header.request_id, &env);
+       CDR_codec_release_buffer(&reply_codec);
 }
 
 static void
@@ -79,6 +160,8 @@ process_hello(forb_port_t *port, CDR_Codec *codec)
 static void
 process_message(forb_port_t *port, forb_iop_message_header *mh, CDR_Codec *codec)
 {
+       /* TODO: Check destination address, whether the message is for
+        * us or should be routed. */
        switch (mh->message_type) {
                case forb_iop_REQUEST:
                        process_request(port, codec);
@@ -287,6 +370,17 @@ size_t forb_proto_send(forb_peer_t *peer, CDR_Codec *codec)
 }
 
 
+/** 
+ * Finds next hop on the way to the particular server.
+ *
+ * Currently, as routing is not implemented, this function searches
+ * only peers.
+ * 
+ * @param forb Forb to ask.
+ * @param server_id Destination server.
+ * 
+ * @return Next hop peer of NULL, if the destination is not found.
+ */
 forb_peer_t *
 forb_get_next_hop(forb_t *forb, forb_server_id *server_id)
 {
index 5e5c36fa5a25e479addfbcec9575aa2f161fb54e..81c80c36dab45add8c2618e42c06b83644471426 100644 (file)
 #error This test should only work with UNIX protocol enabled.
 #endif
 
-/** 
- * Check whether peer identified by @a server_id is discovered by the
- * @a forb.
- *
- * This function traverses all the ports and their peers in order to
- * find the requested peer.
- * 
- * @param forb 
- * @param server_id 
- * 
- * @return @c true, if the peer is discovered, @c false otherwise.
- */
-bool find_peer(forb_t *forb, forb_server_id *server_id)
-{
-       forb_peer_t *peer;
-       return (peer != NULL);
-}
-
 int main(int argc, char *argv[])
 {
        forb_orb orb[NUM_ORBS];