Bidirectional POA + callback + wide char data: giopStrand state emptied too early?

Daniel Krügler daniel.kruegler at gmail.com
Fri Nov 27 15:47:30 GMT 2015


Hi,

up to now we have worked with an unidirectional POA configuration on
the OmniORB (client) side combined with a JacORB server that has
always created a bidirectional POA, but we would like to switch to an
effective bidirectional communication between both by activating
bidirectional communication for OmniOrb as well.

So, as described on

http://omniorb.sourceforge.net/omni40/omniORB/omniORB008.html#sec:bidir

we ensured that the OmniORB POA is now created with BiDirPolicy::BOTH
(but no other explicit policy, the Java ORB has additionally
IdAssignmentPolicyValue.USER_ID and LifespanPolicyValue.TRANSIENT) and
that both offerBiDirectionalGIOP and acceptBiDirectionalGIOP have the
value 1 and

clientTransportRule =    *     bidir,unix,tcp
serverTransportRule =    *     bidir,unix,tcp

For both ORBs the native char and wchar code sets are explicitly set
to UTF-8 and UTF-16, respectively.

It seemed to work until we tested our usual case, that is a call-back
registered by the OmniOrb client which is invoked by the Java server
and among the callback function parameters we have wide char data
(wstring), which is dependent on a proper codeset negotiation. Here we
consistently run into a BAD_PARAM exception when the callback is
invoked the by the Java server (This error doesn't happen in the
unidirectional case).

We debugged the getCodeSetServiceContext and setCodeSetServiceContext
function in codeSets.cc and compared the behaviour to what I expected
from the CORBA specification: The following is the result of my
observations:

1) Both the C++ OmniOrb client and the Java ORB seem to perform the
codeset negotiation correctly and the OmniOrb client correctly sends
the IOP::CodeSets service context to the server with the result of the
negotiation, who is happily reporting the negotiation result.

2) After registration of the callback the Java server now switches its
role and becomes a client by invoking any callback function (it
doesn't matter which, it could even be the _non_existent function). If
that happens under bidirectional conditions on the OmniOrb side the
getCodeSetServiceContext event becomes notified with an giopStrand
that seems to be basically empty, in particular tcs_selected is false
and both tcs_c and tcs_w have null values. The also transmitted
ServiceContextList is now an empty list and we therefore run into the
fallback block

  if (!d.tcs_selected) {
    // In the absence of any codeset negotiation, we choose
    // ISO-8859-1 as the transmission code set for char
    d.version.major = ver.major; d.version.minor = ver.minor;
    tcs_c = d.tcs_c = omniCodeSet::getTCS_C(omniCodeSet::ID_8859_1,ver);
    tcs_w = d.tcs_w = 0;
    d.tcs_selected = 1;
  }

So from the OmniOrb perspective it seems as if the negotiation had
*not* happened (albeit we had seen in the step before the callback
registration (1) that it *had* happened and the Java process had sent
us his IOP::CodeSets result with the expected result). Given that both
the receive of the Java service object, and the callback invocation
later by the server should use the same "session" in the bidirectional
situation, the empty giopStrand of OmniOrb seems to contradict this
expectation.

I should point out here that both sides always use the NameService to
retrieve any service object with a corbaloc that has explicitly set an
iiop version of 1.2.

At this point we have no idea any more what have caused the
"premature" emptyness of the OmniOrb giopStrand, any ideas/suggestions
would be very much appreciated.

Thanks,

Daniel Krügler



More information about the omniORB-list mailing list