- OSErr err;
- err = ::ThreadBeginCritical();
-
- if (m_locked > 0)
- m_locked--;
-
- // this mutex is not owned by anybody anmore
- m_internal->m_owner = kNoThreadID;
-
- // now pass on to the first waiting thread
- ThreadID firstWaiting = kNoThreadID;
- bool found = false;
- while (!m_internal->m_waiters.IsEmpty() && !found)
- {
- firstWaiting = m_internal->m_waiters[0];
- err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
- // in case this was not successful (dead thread), we just loop on and reset the id
- found = (err != threadNotFoundErr);
- if ( !found )
- firstWaiting = kNoThreadID ;
- m_internal->m_waiters.RemoveAt(0) ;
- }
- // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
- // critical section and invoke the scheduler
- err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);