Link to home
Start Free TrialLog in
Avatar of bachra04
bachra04Flag for Canada

asked on

Async call help

I have a need to implement synchronous method that calls an asynchronous method and the way I have found is
to use semaphore :

AsyncMethod1{
}

HandleAsyncMethod1Callback{
      do sthg
      sem_post(&m_Sem);
}


SynchMethod  (){

- call AsyncMethod1.
sem_wait(&m_Sem);

}

My question is :

Is that solution good and without risk or is there any better solution ?
Pls provide it.

Thanks
Avatar of ambience
ambience
Flag of Pakistan image

Well there is risk of waiting forever if "do sthg" throws and exception.

I would recommend

class Locker {
Locker(Sem& s) : _s(s) {}
~Locker() {
   sem_post(&_s);
}
private: Sem& _s;
}

HandleAsyncMethod1Callback{
      Locker locker(m_Sem);
      do sthg; [b]// m_sem is released no matter how we exit method[/b]
}

Open in new window


I'm not sure where m_Sem is kept and therefore can not comment much, if its a global then there could be risks with that as well.
Avatar of bachra04

ASKER

Hi ambiance,

m_sem is an is instance member variable ( not global).
Thank you for your answer but I still think  there is potential risk especially if AsyncMethod and AsyncMethodCb access same variable ( obviously from different threads).

I thought about using condition variable and got this interesting discussion but then again I need help from experts to fully understand the discussion:

condition variables vs mutex

in particular the following piece of code :

Open in new window

int  thread_flag = 0;
pthread_cond_t  thread_flag_condition;
pthread_mutex_t  thread_flag_mutex;


void *thread_function1 (void *thread_arg) {
  while(1) {
    pthread_mutex_lock (&thread_flag_mutex);
    while (!thread_flag)
       // now we can just hang here
       // it's important to know this atomically unnlocks the mutex and then when signaled reaquires the lock
       pthread_cond_wait(&thread_flag_condition, &thread_flag_mutex);
     // when we get here we know someone set the flag
     pthread_mutex_unlock (&thread_flag_mutex);
     do_junk();
      // now send the other thread blocked in while (thread_flag) on it's merry way
      set_thread_flag(0);
   }
   return NULL;
}

void set_thread_flag(int flag_value) {
  pthread_mutex_lock (&thread_flag_mutex);
  thread_flag=flag_value;
  pthread_cond_signal(&thread_flag_condition);
  // nothing can check the flag till this lock is removed
  pthread_mutex_unlock (&thread_flag_mutex);
}
 
void *thread_function2 (void *thread_arg) {
  while(1) {
    pthread_mutex_lock (&thread_flag_mutex);
    while (thread_flag)
       // now we can just hang here
       // it's important to know this atomically unnlocks the mutex and then when signaled reaquires the lock
       pthread_cond_wait(&thread_flag_condition, &thread_flag_mutex);
     // when we get here we know someone set the flag
     pthread_mutex_unlock (&thread_flag_mutex);
     do_other_junk();
      // now send the other thread blocked in while (!thread_flag) on it's merry way
      set_thread_flag(1);
   }
   return NULL;
}
a semaphore is some kind of counter which could be used to let have first n of threads access to a resource while the (n + 1)-th thread needs to wait until at least one of the first n threads has released the semaphore.

of course you could use 1 for maximum if you only want to have one thread for exclusive access and the second thread waits. but for that case (your case) you don't need a semaphore but only an event object:

void sync_method(Data * data)
{
      Event event;
      if (async_method(&event, data))
      {
          // wait until async_method signals event
          event.wait();
       }
}

Open in new window


note, the async_method starts the thread that does the asynchronous work. the thread would do the work and after filling data it would signal the event such that the calling thread could proceed. if the data object is exclusively created for the call the access to data is automatically thread-safe.

Sara
Is Event a posix object, can you give a reference link or sample code
no event isn't a posix object but i found a class implementation ... using a semaphore :)

http://qstuff.blogspot.com/2005/06/events-new-posix-implementation.html

when using boost you could use Boost.Signals.

Sara
ASKER CERTIFIED SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial