[omniORB] thread policy per interface function

black hole neyrith at gmail.com
Fri Aug 17 19:32:15 BST 2007


On 8/17/07, Thomas Lockhart <lockhart at fourpalms.org> wrote:
> > Yes, it is a downside. And there is more to it. Imagine a CORBA
> > implementation that is not multi-threaded in ORB_CTRL_MODEL[*].
> > Then I would have to create new threads for the several functions I need.
>
> That was prohibited by your "Note2" constraint. And wouldn't this still
> restrict you to serial servicing of requests? You might be able to use
> multiple threads to service a single request, but the ORB will not let
> another request through until that is finished.

Well, not prohibited (next time, I'll use the word 'constraint'
instead of 'note').
I'll explain.

First, the (simplified) idl:
module M
{
  typedef sequence<octet> ByteString;
  typedef sequence<ByteString> ByteStringSeq;

  interface I
  {
    // Download component to repository.
    // Can be multi-threaded or single-threaded.
    void download_component(in ByteString component);

    // Instantiate component, return instance Id.
    // Must be always multi-threaded.
    ByteString instantiate_component(in ByteString component,
      in ByteStringSeq arguments);
  };
};

On the server side, I now have one servant
that implements the interface M::I.
The server runs a simplified cycle:
for(;;){
  while(orb->work_pending())
    orb->perform_work();
  // do some other work;
  // sleep;
}

The client issues a request, calls download_component().
Regarding this function, I do not care about thread policy.
That means requests to this function can be processed
sequentially or parallel.

The client issues another request, calls instantiate_component().
The catch with this one is that a component, that is being instantiated,
can instantiate other components. This can lead to another
instantiate_component() request on the same servant. If requests
for this function are handled sequentially, than this results in a deadlock.

If the CORBA implementation is multi-threaded in ORB_CTRL_MODEL,
such as omniORB, then there is no issue.

Regarding the instantiate_component() function. This function looks like this:
M::ByteString* instantiate_component(const M::ByteString& component,
  const M::ByteStringSeq& arguments)
{
  // instantiate a component in an OS-specific way.
  return __instantiate_component(component, arguments);
}

It makes no sense to spawn a thread inside instantiate_component()
and have it call __instantiate_component() since the return value is needed.
The return value identifies a newly created component instance,
and it is what client should receive after the instance is created.

But it is perferctly OK, if something else (ORB for example) does this:
1) read a request from a socket descriptor
2) is it a request for instantiate_component()?
    if yes, then create a new thread and let it execute this function
    if not, then proceed as with ORB_CTRL_MODEL.

I did not find a way to hide the above two steps into these two calls:
if(orb->work_pending()) orb->perform_work();

I took a look at interceptors, default servants and related stuff,
but yet without any clue.

> > I understand CORBA specification that there is way to force
> > a single-threaded POA, but not a multi-threaded one.
>
> Forced or not, you know you can get either single- or multi-threaded POAs.

Actually, I don't know :)


Tomas Klacko



More information about the omniORB-list mailing list