[openamq-dev] Regarding amq_client_session_wait

blog blog at yankeeboysoftware.com
Wed Dec 19 10:45:23 CET 2007


Use of amq_client_session_wait is troubling.

An application should not be bound in a tight loop checking for the
arrival of a message.  So, code like this is unsatisfying:

while(run)
{
  if (amq_client_session_wait (session, 0))
  {
    if (session->alive)    //  timeout expired
      yield(); // not a good idea
    else
      //  session died
      break;
  }
  else
  {
    //  zero or more contents arrived
  }
}

Equally troubling is a long timeout.  This would likely be implemented
in a thread which is either in a tight loop as above, or blocking
infinitely - which causes it's own problems.

The *preferred* solution is a to make use of a synchronization primitive
(preferably a named semaphore). This should be passed to the WireAPI in
the call to amq_client_session_wait, which should then return
asynchronously (immediately).  When a message arrives, the
synchronization object should become signaled.  This has the added
feature of allowing an application to easily and cleanly control worker
threads, since the application may signal the sync object to release the
thread from the wait.

This yields *nice* code as follows.

thread_func()
{
   semaphore sync("Unique_name");
   initialize_semaphore(sync, NOT_SIGNALED);
   amq_client_session_wait (session, sync); //non-blocking call

   semaphore_wait(sync);// blocks until signaled - very efficiently.
   if(amq_client_session_basic_arrived_count (session)) 
   {
     while (content && run)
     {
       //  process content
       content = amq_client_session_basic_arrived (session);
     }
   }
   else
   {
      // something else happened on the sync object
      // perhaps the app wants the thread to shutdown,
      // either way, we have fallen out of the blocking call
   }
}

Most modern Operating Systems will simply not schedule a timeslice for
any thread waiting on a non-signaled object.  This is far more efficient
than constant thread context switching to run a thread that is simply
going to call yield() (or sleep(0) - a poor equivalent) in a tight loop
waiting for a message to arrive.

For further reference please feel free to read 
http://www.yankeeboysoftware.com/wordpress/?p=15



More information about the openamq-dev mailing list