> > * why the extra op_marshaller method in the skels? why not everything in
> > one skel wrapper?
>
> It's a multiple inheritance issue:
> For each call the skeleton operation needs to cast the void* pointer
> into the appropriate C++ skeleton type. With multiple inheritence
> (virtual inheritance) C++ relies on the cast to do the appropriate
> vtable thunk. This means that you need a function per interface per
> operation to ensure that the void* c++ servant pointer gets casted to
> the right C++ servant type (you cant share them).
> The marshalling code for inherited operations is common across all the
> interfaces, and so gets factored out into a single op_marshaller
> function.
>
> If you grab a copy of ORBit-C++ and compile the diamond-inheritance test
> and look at the skels file, you will see how this works. (mail me if you
> want me to send you the C file and save you faffing about with
> PYTHON_PATHs ;-)
Got that. In o2cpp, I chose to generate all the marshalling code for
every inheriting interface, leaving a "*** FIXME we might save code
here" (it's still there - see pass_stubs.cc :). Of course, this was a
kludge. I also had the two-method solution in mind (yet didn't remember
it yesterday), but i wondered whether there was some more efficient way
than to re-pass all those parameters. i thought of doing it by messing
with the servant struct in some tricky way, but obviously this couldn't
survive diamond-shaped inheritance. something else i thought of was
having sort of a widening function for every interface, pointed to by
the servant struct, but this is neither faster nor more elegant. can you
think of a better way? if not, the two-method thing is the way to go.
one improvement for the two-method thing just came to my mind: keep the
*_marshaller as well as the *_callback (i would call it *_caster for
clarity) static methods and thus be able to put the *_marshaller into
the epv. this saves an extra call in a non-inheritance setting.
> > * are you sure the environment singleton does not cause reentrancy
> > problems (e.g. a calls b and b calls a back before returning) apart from
> > being not thread-safe (aka: is creating the env on the stack much more
> > inefficient?)
>
> You're righ, it will cause reentrancy problems and it isn't thread safe.
> I wrapped it in an accessor method in order to defer the decision on how
> to create/manage environments until later. e.g. maybe some pooling will
> yield the best performance/thread safety compromise.
> Creating and initialising envs on the stack may be more efficient as
> well.
Have a look at the cEnvironment thing from old o2cpp
(o2cpp_exception.hh) and tell me what you think of it.
cu
andy
|