[omniORB] Sleeping current thread

David Riddoch djr@uk.research.att.com
Mon, 28 Aug 2000 10:32:00 +0100 (BST)


Hi,


On Mon, 28 Aug 2000, Matthew Berry wrote:

> I have a server function in my implementation class that creates two (omni)
> threads. I want the current thread to yield until either of the other two
> have returned a result/error.  Is there a way to get a pointer to the
> omni_thread object in which the server is running?

Yes:  omni_thread::self() returns the omni_thread object for the currently
running context.  But I don't see why this is useful for what you want to
do.


> The "sub-threads" each call a different CORBA object and I want to return
> from the main thread as soon as I can if an error occurs and not have to
> wait for the other thread to complete.

I suggest that you have a mutex and condition variable somewhere,  and
have the omniORB server thread wait on the condition variable until both
sub-threads return a result, or one returns an error.

The difficult bit is deciding where to put the mutex and condition
variable, and completion state.  I suggest you have a reference counted
object (ordinary c++ object, not CORBA) that the server thread, and two
sub-threads each hold a reference to.  This would contain the condition
variable, mutex and info about completion/errors.  I've given a partial
implementation below (yep, bored by what I am _supposed_ to be doing!).


Cheers,
David

-------------------------------------

class TaskSync {
public:
  TaskSync(int nst)
    : c(&m), n_subthreads(nst), refs(nst+1), error(0), done_count(0) {}

  void subthread_error(int i) {
    m.lock();
    error = 1;
    m.unlock();  
    c.signal();
    remove_ref();
  }
  void subthread_done(int i) {
    m.lock();
    done_count++;
    m.unlock();
    c.signal();
    remove_ref();
  }

  int completed() { return error || done_count == n_subthreads; }

  void mainthread_wait() {
    m.lock();
    while( !completed() )  c.wait();
    m.unlock();
  }

  void remove_ref() {
    m.lock();
    int done = --refs == 0;
    m.unlock();
    if( done )  delete this;
  }

private:
  omni_mutex     m;
  omni_condition c;
  int            n_subthreads;
  int            refs;
  int            error;
  int            done_count;
  // + results ????
};

-------------------------------------