<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 12 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Courier New";}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal>I was looking at _thread_cond_timedwait in thread_code. There is a section of the code that I do not understand the purpose of. Could someone please explain to me what the purpose of the other part of the code is?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Before the code enters a loop it serializes access to the passed in cond structure pointer, increments a counter and makes a local copy of a value before releasing the cond again.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> EnterCriticalSection(&cond->csection);<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> cond->num_waiting++;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> generation = cond->generation;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> LeaveCriticalSection(&cond->csection);<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>What is the purpose of ‘num_waiting’ and ‘generation’?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The next part looks odd to me. Why does the code unlock the mutex when what is desired is to lock it?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> apr_thread_mutex_unlock(mutex);<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> <o:p></o:p></span></pre><p class=MsoNormal>The code then enters a do { } while (true); loop.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>do</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> {<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The first thing it does is to wait for access to a semaphore. This is a limited time wait and may time out before the event is encountered. The result of this wait is checked later.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> res = WaitForSingleObject(cond->semaphore, timeout_ms);<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The ‘cond’ structure is going to be modified again and the code needs to have exclusive access. <o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> EnterCriticalSection(&cond->csection);<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> <o:p></o:p></span></pre><p class=MsoNormal>I do not know what the purpose of this is. Can someone explain it to me? What is the purpose of this particular block?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>if</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> (cond->num_wake) {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>if</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> (cond->generation != generation) {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> cond->num_wake--;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> cond->num_waiting--;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> rv = APR_SUCCESS;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>break</span><span style='font-size:8.0pt;font-family:Consolas;color:black'>;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> } </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>else</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> wake = 1;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> }<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> }<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>else</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>if</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> (res != WAIT_OBJECT_0) {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> cond->num_waiting--;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> rv = APR_TIMEUP;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>break</span><span style='font-size:8.0pt;font-family:Consolas;color:black'>;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> }<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>If neither ‘break’ executes then the code releases the critical section. The code would be less obtuse (and smaller) if the two ‘break’ functions were removed. That would save having duplicate LeaveCriticalSection() functions. In any case, the code releases the critical section.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> LeaveCriticalSection(&cond->csection);<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>What is the purpose of the next bock? It only executes if the semaphone acquisition was successful but the ‘cond->generation’ has changed while attempting to determine if it is OK to execute the mutex lock. <o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>if</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> (wake) {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> wake = 0;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> ReleaseSemaphore(cond->semaphore, 1, NULL);<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> }<o:p></o:p></span></pre><p class=MsoNormal>Note: If the two ‘break’ statements were removed from above and the following lines added. At this point in the code the critical section would have been released so it would not be necessary to explicitly do so outside of the forever loop.<o:p></o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>else</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> {<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>break</span><span style='font-size:8.0pt;font-family:Consolas;color:black'>;<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> }<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Under what conditions can ‘cond->generation’ change?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The bottom of the loop is encountered.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> } </span><span style='font-size:8.0pt;font-family:Consolas;color:blue'>while</span><span style='font-size:8.0pt;font-family:Consolas;color:black'> (1);<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>To get here one of the two ‘break’ statements must have been hit. The critical section is still locked and must be released. Note: if my suggested changes were implemented then it would not be necessary to have this line:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> LeaveCriticalSection(&cond->csection);<o:p></o:p></span></pre><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'><o:p> </o:p></span></pre><p class=MsoNormal>And now, finally, the mutex gets locked.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><pre style='background:white'><span style='font-size:8.0pt;font-family:Consolas;color:black'> apr_thread_mutex_lock(mutex);<o:p></o:p></span></pre><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><div><div><div><div><div><div><div><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:12.0pt;font-family:"Arial","sans-serif"'>==============================<br>Richard Lewis Haggard</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'> <br><br></span><span style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p></div></div></div></div></div></div></div><p class=MsoNormal><o:p> </o:p></p></div></body></html>