Avoiding deadlocks with ACE_Reactor

Originally ACE_Reactor was designed for event driven single threaded applications.
Design requires executing ACE_Reactor::run_reactor_event_loop() in one thread which is responsible
for processing all application events.

Also ACE developers used mutex to enable ACE_Reactor in multi threaded environment.
Thus it is easy to get a deadlock in the situation explained below.

When timer is scheduled:

	 int id = ACE_Reactor::instance()->schedule_timer(this, pVoid, 5, 0 );


ACE internally obtains a mutex lock:

	 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));

The same mutex is obtained when ACE is executing user supplied handler routine.

	int UserTimerHandler::handle_timeout (const ACE_Time_Value &current_time, const void * pData){
		//... some user code
		return 0;
	}


Assuming that schedule_timer and handle_timeout are executed in two different threads.
If these two threads will operate on another (second) mutex it will lead to a classical deadlock.

The good solution for this is to have a lightweight handle_timeout function.
It may insert new events to the event queue and the queue should be processed by a third thread.
In this case handle_timeout will release the lock on the Reactor mutex quickly and other threads will process events efficiently.

Leave a Reply