Folks,<div> There is a race condition in the basic pthread mutex lock code for dbus.</div><div><br></div><div>Thread 1:</div><div> Calls _dbus_connection_acquire_io_path -> grabs the mutex -> io_path_acquired = true -> releases the mutex -> exits the function.</div>
<div><br></div><div>Thread 2: </div><div> Calls _dbus_connection_acquire_io_path -> grabs the mutex -> io_path_acquired is already true -> _dbus_condvar_wait_timeout</div><div><br></div><div>Thread 1:</div><div>
Calls _dbus_connection_release_io_path -> grabs the mutex -> sets io_path_acquired = false -> signals thread 1 and releases the mutex.</div><div> </div><div> Calls _dbus_connection_acquire_io_path again tries to grab the mutex.</div>
<div> </div><div><br></div><div>Now, in _dbus_pthread_condvar_wait_timeout:</div><div><br></div><div> result = pthread_cond_timedwait (&pcond->cond, &pmutex->lock, &end_time);</div><div> ......</div>
<div> _dbus_assert (pmutex->count == 0);</div><div> pmutex->count = old_count;</div><div> pmutex->holder = pthread_self(); </div><div><br></div><div><br></div><div>We set the holder back to Thread 2 only after some time.</div>
<div>During this time Thread 1 can grab the mutex since pthread->holder is still set to Thread1. In _dbus_pthread_mutex_lock function</div><div>that check is enough to grab the lock.</div><div><br></div><div>So currently, Thread 2 has woken up from cond_timewait -> gone back to the acquire_io_path_function and set io_path_acquired to true.</div>
<div><br></div><div>Thread 1, has been able to grab the mutex -> checks io_path_acquired variable, sees that it already true -> calls condvar_wait_timeout.</div><div><br></div><div>which asserts that the pthread->holder and pthread_self is the same. This assert will fail.</div>
<div><br></div><div>Hope the above make sense. The attached patch fixes the problem for me.</div><div><br>Thanks</div>