The segfault was due to a really obscure bug that I really don't have
time to investigate - it involved wrapping initialization of the orb,
and the mimic object in one try block and the "work_pending, perform
work" in another try block. I didn't bother to investigate further as a
work around was just to wrap the entire thing in one try block.

Anyhow, it turns out my scheme won't work because in order for the
ServerRequestInterceptor::receive_request to be called, you have to
parse the arguments in the DynamicImplementation::invoke method, first.
Of course, since this is an attempt to be completely generic, this isn't
possible without prior knowledge of the requests. It's a real bummer
that there isn't a way to just leave the arguments as they're encoded in
a buffer and forward on the request argument buffer - allowing it to be
a generic solution.

As such, I've had to abandon this solution for a hard-coded non-generic
solution (the other option being implementing TII or a GIOP server that
goes low level to forward requests to different objects - both of which
would involve too much time).

On a side note, apparently 'ForwardRequest' exceptions are not caught
during invocation, but are only caught during Interceptor,
ServantManager and ServantLocator upcalls. A ForwardRequest exception
during an invocation results in an attempt to marshal it back to the
client, which results in an assertion failure - ForwardRequest
exceptions are not to be sent across the wire, but are to be turned into
a LOCATION_FORWARD (a GIOP reply).

A quick, dirty, untested patch/fix to this (if it should be fixed) would
be the following:

In poa_impl.cc, for mico-2.3.11, lines 3790-3798:

    if (thread_policy->value() == PortableServer::MAIN_THREAD_MODEL) {
      MICOMT::AutoLock t_lock(S_global_invoke_lock);
      servant->doinvoke(svr);
    } else if (thread_policy->value() ==
PortableServer::SINGLE_THREAD_MODEL) {
      MICOMT::AutoLock l(serialize_invoke);
      servant->doinvoke (svr);
    } else {
      servant->doinvoke (svr);
    }

Encapsulating the above in a try block with the following catch block
should do the trick:

      } catch (PortableServer::ForwardRequest_catch & fwr) {
        orb->answer_invoke (ir->id(), CORBA::InvokeForward,
                            fwr->forward_reference,
                            ir->get_or(), 0);
        return;
      } catch (CORBA::SystemException_catch & sex2) {
        CORBA::ServerRequest_ptr svr = ir->make_dyn_req (this);
        svr->exception (sex2->_clone());
        return;
      }

Don't forget to encapsulate the try and catch phrases with the
HAVE_EXCEPTIONS #define guard.

Note that this patch/fix is untested and is just an educated guess from
reverse-engineering - it may not even compile. However, it's a step in
the right direction. 

Considering that I had to abandon my approach, I no longer can spend any
more time devoted to the investigation. Hope this all helped, for those
who have the need for something similar.

Brian Lindahl
Spacecraft Software Engineer
858-375-2077
[EMAIL PROTECTED] 
SpaceDev, Inc.
"We Make Space Happen"


_______________________________________________
Mico-devel mailing list
[email protected]
http://www.mico.org/mailman/listinfo/mico-devel

Reply via email to