From a6448c3882b3f10dbcaefb722ec2ab492d992979 Mon Sep 17 00:00:00 2001 From: Petr Benes Date: Tue, 8 Feb 2011 14:52:56 +0100 Subject: [PATCH] Prepared for multiple executors in a single address space Object implementation invocation prepared for a use of multiple executors running in a single address space. One can call the iop methods in the same way as for the case of a remote invocation. --- src/exec_req.c | 15 +++++++++++---- src/exec_req.h | 11 +++++++++++ src/iop.c | 17 +++++++++++++++++ src/request.h | 1 - src/tests/executor_calls.c | 14 ++++++-------- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/exec_req.c b/src/exec_req.c index e5b9c76..028c532 100644 --- a/src/exec_req.c +++ b/src/exec_req.c @@ -93,10 +93,17 @@ void forb_exec_req_process(forb_exec_req_t *exec_req) &reply_codec, exec_req->obj, &env); - - forb_iop_send_reply(forb, &exec_req->source, - &reply_codec, - exec_req->request_id, &env); + + // The local invocation case + if ((exec_req->request_type = local)) { + *(exec_req->input_request->cdr_reply) = reply_codec; //FIXME: better without copying? + // notify that the reply is ready + forb_syncobj_signal(&exec_req->input_request->reply_ready); + } else { + forb_iop_send_reply(forb, &exec_req->source, + &reply_codec, + exec_req->request_id, &env); + } FORB_CDR_codec_release_buffer(&reply_codec); forb_exec_req_destroy(exec_req); } diff --git a/src/exec_req.h b/src/exec_req.h index 57b17ba..b8e2147 100644 --- a/src/exec_req.h +++ b/src/exec_req.h @@ -62,6 +62,15 @@ #include #include #include "executor.h" +#include "request.h" + +/** + * Distinguishing execution methods of a request. + */ +enum FORB_EXEC_REQ_TYPE { + local, // no serialization used + remote +}; /** * Request for ::forb_executor_t. @@ -74,6 +83,8 @@ typedef struct forb_exec_req { unsigned method_index; /**< Mehotd number to be invoked on the object @a obj. */ FORB_CDR_Codec codec; /**< Bufffer with serialized request parameters. */ ul_list_node_t node; /**< Node for forb_executor_t::requests. */ + enum FORB_EXEC_REQ_TYPE request_type; /**< Execution method. */ + forb_request_t *input_request; /**< Input request data for the case of local invocation */ } forb_exec_req_t; UL_LIST_CUST_DEC(forb_exec_req_nolock, /* cust_prefix */ diff --git a/src/iop.c b/src/iop.c index 5133069..248f94a 100644 --- a/src/iop.c +++ b/src/iop.c @@ -388,6 +388,7 @@ process_request(forb_port_t *port, FORB_CDR_Codec *codec, uint32_t message_size) exec_req = forb_malloc(sizeof(*exec_req)); if (exec_req) { memset(exec_req, 0, sizeof(exec_req)); + exec_req->request_type = remote; exec_req->request_id = request_header.request_id; exec_req->source = request_header.source; exec_req->obj = obj; @@ -732,6 +733,7 @@ forb_request_send(forb_request_t *req, CORBA_Environment *env) size_t len; fosa_abs_time_t timeout; forb_t *forb = forb_object_to_forb(req->obj); + forb_exec_req_t *exec_req; if (!forb) { env->major = FORB_EX_INTERNAL; @@ -748,6 +750,21 @@ forb_request_send(forb_request_t *req, CORBA_Environment *env) return; } + /* Local invocation case, destination of a message is only + * a different executor thread */ + if (forb_object_is_local(req->obj)) { + exec_req = forb_malloc(sizeof(*exec_req)); + memset(exec_req, 0, sizeof(exec_req)); + exec_req->request_type = local; + exec_req->input_request = req; + exec_req->obj = exec_req->input_request->obj; + //exec_req->method_index = req.method_index; + exec_req->codec = exec_req->input_request->cdr_request; //FIXME: or better without copying? + exec_req->request_id = exec_req->input_request->request_id; + forb_exec_req_ins_tail(forb_object_get_executor(exec_req->obj), exec_req); + return; + } + ret = forb_iop_prepend_message_header(&req->cdr_request, forb_iop_REQUEST); if (!ret) { /* This should never happen */ diff --git a/src/request.h b/src/request.h index 1b1d0fc..16f9049 100644 --- a/src/request.h +++ b/src/request.h @@ -66,7 +66,6 @@ #include - /** * Helper structure for sending ORB requests. * diff --git a/src/tests/executor_calls.c b/src/tests/executor_calls.c index 896c2d9..981145f 100644 --- a/src/tests/executor_calls.c +++ b/src/tests/executor_calls.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "myinterface.h" @@ -19,21 +20,18 @@ CORBA_long myinterface_add(myinterface _obj, const CORBA_long a, const CORBA_long b, CORBA_Environment *ev) { CORBA_long _forb_retval; - executor *exec_current; + forb_executor_t *exec_current; if (ev) ev->major = FORB_EX_NONE; /* local object */ - if (forb_object_is_local(_obj)) { + if (forb_object_is_local(_obj) && !forb_get_current_executor(exec_current) && + (forb_object_get_executor(_obj) == exec_current)) { if (!_obj->interface || strncmp(_obj->interface->name, "myinterface", 11) != 0) { ev->major = FORB_EX_BAD_OPERATION; return _forb_retval; } - if (!forb_get_current_executor(exec_current) && (forb_object_get_executor(_obj) == exec_current)) - /* direct invocation */ - _forb_retval = _myinterface_impl(_obj)->add(_obj, a, b, ev); - } else { - /* TODO inter-thread invocation*/ - } + /* direct invocation */ + _forb_retval = _myinterface_impl(_obj)->add(_obj, a, b, ev); } else { /* remote object - the same as before */ forb_request_t req; -- 2.39.2