<div>For worker implementation of "run loop", I am looking to implement MessageQueue::waitForMessage<span class="Apple-style-span" style="font-weight: bold;">WithTimeout</span>(), where timeout would be computed from the the JS timer with nearest expiration. I am looking at using WTF::ThreadCondition::timedWait for implementation but it seems it is not implemented right... Before trying to send a patch, I'd like to ask here to validate the idea.<br>
</div>
<div><br></div><div>It is defined with 'secondsToWait':</div><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"><span style="color:rgb(170, 13, 145)"><br></span></p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco">
<span style="color:#aa0d91">bool</span> <span style="color:#3f6e74">ThreadCondition</span>::timedWait(<span style="color:#3f6e74">Mutex</span>& mutex, <span style="color:#aa0d91">double</span> secondsToWait)</p><div>
<br></div><div>while a corresponding pthread function takes absolute time:</div><div><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"><span style="color:rgb(170, 13, 145)"><br></span></p>
<p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"><span style="color:#aa0d91">int</span> pthread_cond_timedwait(<span style="color:#5c2699">pthread_cond_t</span> *, <span style="color:rgb(92, 38, 153)">pthread_mutex_t<span style="color:#000000"> *</span><span style="color:#000000">, <span style="color:#aa0d91">const</span> <span style="color:#aa0d91">struct</span> timespec *);</span></span></p>
<div><br></div><div> The reason pthread function takes abs time is because pthread's function can return 'spuriously'. I think the reason is that most implementation lack the atomic "wake up and re-acquire the mutex" operation, so the conditions can change between waking up and re-acquiring the mutex - and the wait can return while in fact it should have not. Here is a piece of pthread doc (<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_cond_timedwait.txt" target="_blank">https://computing.llnl.gov/tutorials/pthreads/man/pthread_cond_timedwait.txt</a>):<br>
</div></div><div><br></div><div><span style="font-family:Tahoma;font-size:14px"><pre style="word-wrap:break-word;white-space:pre-wrap"> <span style="font-size:small">When using condition variables there is always a Boolean predicate involving
shared variables associated with each condition wait that is true if the thread
should proceed. Spurious wakeups from the pthread_cond_timedwait() or
pthread_cond_wait() functions may occur. Since the return from pthread_cond_timed-
wait() or pthread_cond_wait() does not imply anything about the value of this
predicate, the predicate should be re-evaluated upon such return.</span>
</pre><pre style="word-wrap:break-word;white-space:pre-wrap"><span style="font-size:small"><span style="font-family:arial;white-space:normal">That means the waiting should always be done in a loop, checking if the thread can actually proceed and if not, call wait function again, like here:</span></span></pre>
<p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"> <span style="color:#aa0d91">bool</span> <span style="color:#3f6e74">MessageQueue</span>::waitForMessage()</p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco">
{</p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"> MutexLocker <span style="color:#26474b">lock</span>(<span style="color:#3f6e74">m_mutex</span>);</p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco">
<span style="color:#aa0d91">while</span> (m_queue.<span style="color:#26474b">isEmpty</span>())</p>
<p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"> m_condition.<span style="color:#2e0d6e">wait</span>(<span style="color:#3f6e74">m_mutex</span>);</p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco">
.. consume message ...</p><p style="margin:0.0px 0.0px 0.0px 0.0px;font:10.0px Monaco"> }</p><pre style="word-wrap:break-word;white-space:pre-wrap"><span style="font-size:small"><span style="font-family:arial;white-space:normal"> In case of timed wait it means the absolute time should be computed before such loop, and it explains why pthreads have timed wait function with absolute time as a parameter. That means WTF timedWait method should change prototype to take absolute time:</span></span></pre>
<pre style="word-wrap:break-word;white-space:pre-wrap"><span style="font-family:arial;font-size:12px;white-space:normal"><span style="font-family:Monaco;font-size:10px"><span style="color:rgb(170, 13, 145)">bool</span> <span style="color:rgb(63, 110, 116)">ThreadCondition</span>::timedWait(<span style="color:rgb(63, 110, 116)">Mutex</span>& mutex, <span style="color:rgb(170, 13, 145)">const</span> <span style="color:rgb(170, 13, 145)">struct</span> timespec *timeoutTime)</span></span></pre>
<pre style="word-wrap:break-word;white-space:pre-wrap"><span style="font-family:arial;font-size:12px;white-space:normal">Then it's possible to implement blocking MessageQueue::waitForMessageWithTimeout() to return exactly after specified timeout or with a message.</span></pre>
<pre style="word-wrap:break-word;white-space:pre-wrap"><span class="Apple-style-span" style="font-family: arial; font-size: 12px; white-space: normal;">Ok to change?</span></pre><pre style="word-wrap: break-word; "><span class="Apple-style-span" style="font-family: arial; font-size: 12px; white-space: normal; ">Dmitry</span><br>
</pre></span></div>