Discussion:
[omniORB] Data relaying
Wernke zur Borg
2007-07-20 20:40:35 UTC
Permalink
Imagine an application that plays the role of a relay between a number
of data providers and a number of data consumers. Data providers call
methods of the relay to deliver data. Data consumers call methods on the
relay to fetch data. The relay has a queue for buffering the data. The
data structures are the same for both sides, say:

// IDL
struct Data {
...
};

The relay interface for the data providers is something like:

// IDL
interface DataRelay {
void putData( in Data d ); // queues the data
};

The relay interface for the data consumers is something like:

// IDL
interface DataRelay {
Data getData(); // delivers first item from queue
};

The C++ equivalent for this interface is

// C++
void DataRelay::putData( const Data& d );
Data* DataRelay::getData();

The problem with this is that each data item must be copied at least
once during putData(). Since performance is an issue in my case I am
looking for a way to minimise copying the data. However with the const
argument& I do not see a way to avoid it.

Any ideas?

Regards, Wernke
BaileyK at schneider.com ()
2007-07-20 22:13:34 UTC
Permalink
It would seem to be a consequence of the local/remote transparency of
CORBA, that you can't have both client and server with a private copy of
the data after a call unless one side or the other makes an explicit copy.
If the server is remote, it's clear that there are already two copies of
the data, but the ORB will want to delete one copy.

That said, if the client does not need the data any longer, you could shift
things by using an (inout sequence<Data>) and then manipulating the buffer
of the C++ sequence manually. Once the server has the data it can remove
the buffer, and replace it with an empty buffer and then the client side
ORB will delete it's copy.

If you make the parameter (in sequence<Data>), then cast away the const so
that you can manipulate the buffer, it might work to allow both client and
server to keep their copy of the data, but it would break the local/remote
transparency.

I haven't tested any of this, but it makes sense based on what I know about
the C++ mapping for sequence types.

---
Kendall Bailey
Engineering & Research
Schneider National, Inc.




"Wernke zur Borg"
<wernke.zur.borg@
vega.de> To
Sent by: <omniorb-***@omniorb-support.com>
omniorb-list-boun cc
***@omniorb-suppo
rt.com Subject
[omniORB] Data relaying

07/20/2007 09:40
AM








Imagine an application that plays the role of a relay between a number
of data providers and a number of data consumers. Data providers call
methods of the relay to deliver data. Data consumers call methods on the
relay to fetch data. The relay has a queue for buffering the data. The
data structures are the same for both sides, say:

// IDL
struct Data {
...
};

The relay interface for the data providers is something like:

// IDL
interface DataRelay {
void putData( in Data d ); // queues the data
};

The relay interface for the data consumers is something like:

// IDL
interface DataRelay {
Data getData(); // delivers first item from queue
};

The C++ equivalent for this interface is

// C++
void DataRelay::putData( const Data& d );
Data* DataRelay::getData();

The problem with this is that each data item must be copied at least
once during putData(). Since performance is an issue in my case I am
looking for a way to minimise copying the data. However with the const
argument& I do not see a way to avoid it.

Any ideas?

Regards, Wernke
Duncan Grisby
2007-07-31 21:51:01 UTC
Permalink
On Friday 20 July, "Wernke zur Borg" wrote:

[...]
Post by Wernke zur Borg
The C++ equivalent for this interface is
// C++
void DataRelay::putData( const Data& d );
Data* DataRelay::getData();
The problem with this is that each data item must be copied at least
once during putData(). Since performance is an issue in my case I am
looking for a way to minimise copying the data. However with the const
argument& I do not see a way to avoid it.
You can't avoid it if you stick with the standard C++ mapping. This is
one of the many issues that makes the C++ mapping far from ideal.

If you're willing to get your hands dirty and make your code omniORB
specific, you can get in at a level below the C++ mapping and avoid the
unnecessary copying. If you look at the code generated by omniidl, in
the SK.cc file, you'll find definitions of call descriptor classes for
each of the IDL operations. Those are the things responsible for
marshalling and unmarshalling arguments, and calling the servant
methods. What you can do is write your own versions of those classes
that do different memory management -- in your case, passing the in
struct argument by pointer instead of const reference.

Then you can override the _dispatch() method of the _impl_ class, which
is the thing responsible for creating the call descriptor and performing
the call.

Hopefully you'll be able to follow the logic through all the generated
code and see how to change it. I wouldn't recommend this path unless
you've definitely established that the data copying is a significant
performance issue, though.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Continue reading on narkive:
Loading...