Opened 20 years ago
Closed 17 years ago
#80 closed Bugs (Fixed)
Bosot.Thread.condition(win32).notify_all
Reported by: | nobody | Owned by: | glassfordm |
---|---|---|---|
Milestone: | Component: | threads | |
Version: | None | Severity: | |
Keywords: | Cc: |
Description
Problem:this is a bug in the notify_all() methode in "Boost.Thread.Condition(win32)". Why:the bug causes a deadlock in my machine. Desc: ->suppose that i have two thread waiting for a condition, then the condition state will be ( m_block = 2, m_waiting = 0, m_gon = 0, the queue semaphore's count become = -2, and the mutex state unlocked). ->then suppose that there is another thread call the notify_one() methode of the shared condition ,thus the state of the condition become (m_block = 1, m_waiting = 1, m_gon = 0, the queue semaphore's count = -1, and the mutex state unlocked) -> then this thread or another reschudled before the waked up thread from the queue and called the notify_all() methode, it will find that m_waiting != 0 , and m_block != 0 and the state of the condition become after this call (m_block = 0, m_waiting = 2, m_gon = 0, the queue semaphore's count = -1(bug), and the muext state locked(deadlock)). **-> thus when we noted that there are a bug in the queue semaphore's count, and a deadlock in the mutex state that was unlocked. Bug Fix: here is the new version of the methode after correcting the bug. void condition::notify_all() { unsigned signals = 0; int res; res = WaitForSingleObject(reinterpret_cast<HANDLE> (m_mutex), INFINITE); assert(res == WAIT_OBJECT_0); if (m_waiting != 0) // the m_gate is already closed { if (m_blocked == 0) { res = ReleaseMutex(reinterpret_cast<HANDLE> (m_mutex)); assert(res); return; } m_waiting += (signals = m_blocked); m_blocked = 0; } else { res = WaitForSingleObject (reinterpret_cast<HANDLE>(m_gate), INFINITE); assert(res == WAIT_OBJECT_0); if (m_blocked > m_gone) { if (m_gone != 0) { m_blocked -= m_gone; m_gone = 0; } signals = m_waiting = m_blocked; m_blocked = 0; } else { res = ReleaseSemaphore (reinterpret_cast<HANDLE>(m_gate), 1,0); assert(res); } } res = ReleaseMutex(reinterpret_cast<HANDLE> (m_mutex)); assert(res); if (signals) { res = ReleaseSemaphore(reinterpret_cast<HANDLE> (m_queue), signals, 0); assert(res); } Note : sorry for my bed english. name: walead mohammed. thanks.
Note:
See TracTickets
for help on using tickets.