[omniORB] Problem using omni_condition::broadcast in an omniORB thread

baileyk at schneider.com baileyk at schneider.com
Wed Jul 2 09:28:43 BST 2003


Any condition variable I've seen is linked to a mutex.  I think you need to
lock the mutex associated with the condition variable prior to calling wait
(), timedwait(), signal() or broadcast().  The threads blocked in wait()
are going to try to lock that mutex when the broadcast wakes them up.  Only
one will get it, as you've seen.  The omni_condition object's constructor
takes a pointer to a mutex.  It's that mutex you have to lock.  Change your
code to something like this:

     if (this->nbOfClientsConnected == this->maxNbOfClientsConnected) {
       omni_mutex_lock l( mutex );
       this->bufferOfRequests->broadcast();
     } else {
       cout << "Waiting for buffer filled.\n";
       omni_mutex_lock l( mutex );
       this->bufferOfRequests->wait();
     }

Where "mutex" is a reference to whatever mutex object the
*(this->bufferOfRequests) condition variable was created with.

Also, a call to wait() may return for reasons other than the condition you
want to be true.  The waiting thread(s) should always check the condition
and go back to waiting if it is false, so further change the code like so:

     } else {
       cout << "Waiting for buffer filled.\n";
       omni_mutex_lock l( mutex );
       while( this->nbOfClientsConnected < this->maxNbOfClientsConnected )
{
          this->bufferOfRequests->wait();
       }
     }

The call to wait() will atomically unlock the mutex to allow other threads
to enter one of the two critical sections.  The reason to hold the lock
while calling broadcast, is so that a thread that is between checking the
condition and starting to wait does not miss the signal to wake up.  Since
the broadcasting thread holds the lock, all other threads either have not
checked the condition yet, or are blocked and definitely will wake up.
Once the broadcasting thread releases the lock, all the other threads will
(one at a time, due to the fact that returning from wait re-aquires the
lock) re-check the condition, see that its true, and leave the critical
section.

Good luck,
Kendall



                                                                                                                                         
                      Philippe Combes                                                                                                    
                      <Philippe.Combes at ens-lyon.fr>        To:       omniorb-list at omniorb-support.com                                    
                      Sent by:                             cc:                                                                           
                      omniorb-list-bounces at omniorb-        Fax to:                                                                       
                      support.com                          Subject:  [omniORB] Problem using omni_condition::broadcast in an omniORB     
                                                            thread                                                                       
                                                                                                                                         
                      07/02/2003 07:37 AM                                                                                                
                                                                                                                                         
                                                                                                                                         





Hi all,

I use omniORB 4.0.1 on a Debian Linux (2.4.20) - which means Posix
threads, doesn't it ?

I try to program a server that processes requests (submitted through the
method "submit" of the server) only once a given amount
(maxNbOfClientsConnected) of such requests have arrived.
I thought that each of these "submit" invokations was processed in an
omniORB thread. So using an omni_condition (bufferOfRequests) would have
been very useful :


CORBA::Long
ServerImpl::submit(...)
{
   // As the requests arrive sequentially, there is no need to
   // lock/unlock a mutex for this->nbOfClientsConnected

   if (this->nbOfClientsConnected < this->maxNbOfClientsConnected) {
     this->nbOfClientsConnected++;
     if (this->nbOfClientsConnected == this->maxNbOfClientsConnected) {
       this->bufferOfRequests->broadcast();
     } else {
       cout << "Waiting for buffer filled.\n";
       this->bufferOfRequests->wait();
     }
   }

   // Processing a request ...
}


Actually, when the maxNbOfClientsConnected-th request arrives, the
broadcast awakens only the first request, and lets the last one
continue, of course. It is exactly the same behaviour as if I used
omni_condition::signal !!!

In another part of my application, I successfully use
omni_condition::broadcast on omni_threads that I created and manage
myself. Is the problem related to the fact that the "submit" invokations
are managed by the omniORB pool of threads ?

If anyone can give me a hand ...

Thanks in advance.

Philippe Combes
-------------------------------------------------
Philippe Combes. IE INRIA, LIP - ENS Lyon
46, allée d'Italie
69364 Lyon Cedex 07, France
Tel: (+33)4 72 72 84 70, Fax: (+33)4 72 72 80 80
Web Page: http://www.ens-lyon.fr/~pcombes/
-------------------------------------------------


_______________________________________________
omniORB-list mailing list
omniORB-list at omniorb-support.com
http://www.omniorb-support.com/mailman/listinfo/omniorb-list








More information about the omniORB-list mailing list