<div dir="ltr">Hi All,<div><br></div><div>    while the changes below are correct, in that they prevent primitive failures that shouldn&#39;t happen, they cause the testSocketReuse test to now lock up the system.  I;m trying to understand what&#39;s going on and develop a proper fix.  Levente, you allude to a VM bug in <span style="color:rgb(0,0,0);font-size:12.8px">waitForDataIfClosed .  Can you be more precise?  </span>It seems to me that the bug is that a socket&#39;s semaphore is not necessarily signalled when a socket becomes invalid, closes, etc.  Is that right?  I suppose that the primitive failures are preferrable to a lock up wuerh running the test suite, so perhaps we should revert the changes below.  But it feels wrong to mask a bug with a primitive failure.  It would be nicer to have something in the code that explicitly prevented getting into the lockup, even if by raising an error.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 25, 2016 at 1:07 PM,  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Eliot Miranda uploaded a new version of Network to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Network-eem.172.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Network-eem.172.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Network-eem.172<br>
Author: eem<br>
Time: 25 February 2016, 1:07:33.303622 pm<br>
UUID: 5c73783a-d4e2-413e-b5eb-f04ad8decee2<br>
Ancestors: Network-ul.171<br>
<br>
Fix two failures to check if a socket is closed (socketHandle is nil) before attempting to read from the socket.<br>
<br>
=============== Diff against Network-ul.171 ===============<br>
<br>
Item was changed:<br>
  ----- Method: Socket&gt;&gt;receiveDataInto:startingAt: (in category &#39;receiving&#39;) -----<br>
  receiveDataInto: aStringOrByteArray startingAt: aNumber<br>
        &quot;Receive data into the given buffer and return the number of bytes received.<br>
        Note the given buffer may be only partially filled by the received data.<br>
        Waits for data once.  The answer may be zero (indicating that no data was<br>
        available before the socket closed).&quot;<br>
<br>
+       | bytesRead open |<br>
-       | bytesRead closed |<br>
        bytesRead := 0.<br>
+       open := true.<br>
+       [open and: [bytesRead = 0]] whileTrue:<br>
+               [self waitForDataIfClosed: [open := false].<br>
+                open ifTrue:<br>
+                       [bytesRead := self primSocket: socketHandle<br>
+                                                               receiveDataInto: aStringOrByteArray<br>
+                                                               startingAt: aNumber<br>
+                                                               count: aStringOrByteArray size - aNumber + 1]].<br>
-       closed := false.<br>
-       [closed not and: [bytesRead = 0]]<br>
-               whileTrue: [<br>
-                       self waitForDataIfClosed: [closed := true].<br>
-                       bytesRead := self primSocket: socketHandle<br>
-                               receiveDataInto: aStringOrByteArray<br>
-                               startingAt: aNumber<br>
-                               count: aStringOrByteArray size-aNumber+1].<br>
        ^bytesRead<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: Socket&gt;&gt;waitForDataIfClosed: (in category &#39;waiting&#39;) -----<br>
  waitForDataIfClosed: closedBlock<br>
        &quot;Wait indefinitely for data to arrive.  This method will block until<br>
        data is available or the socket is closed.&quot;<br>
<br>
+       [(socketHandle ~~ nil<br>
+         and: [self primSocketReceiveDataAvailable: socketHandle]) ifTrue:<br>
+               [^self].<br>
+        self isConnected ifFalse:<br>
+               [^closedBlock value].<br>
+        &quot;ul 8/13/2014 21:16<br>
+         Providing a maximum for the time for waiting is a workaround for a VM bug which<br>
+         causes sockets waiting for data forever in some rare cases, because the semaphore<br>
+         doesn&#39;t get signaled. Replace the &quot;&quot;waitTimeoutMSecs: self class maximumReadSemaphoreWaitTimeout&quot;&quot;<br>
+         part with &quot;&quot;wait&quot;&quot; when the bug is fixed.&quot;<br>
+        self readSemaphore waitTimeoutMSecs: self class maximumReadSemaphoreWaitTimeout] repeat!<br>
-       [<br>
-               (self primSocketReceiveDataAvailable: socketHandle)<br>
-                       ifTrue: [^self].<br>
-               self isConnected<br>
-                       ifFalse: [^closedBlock value].<br>
-               &quot;Providing a maximum for the time for waiting is a workaround for a VM bug which causes sockets waiting for data forever in some rare cases, because the semaphore doesn&#39;t get signaled. Replace the &quot;&quot;waitTimeoutMSecs: self class maximumReadSemaphoreWaitTimeout&quot;&quot; part with &quot;&quot;wait&quot;&quot; when the bug is fixed.&quot;<br>
-               self readSemaphore waitTimeoutMSecs: self class maximumReadSemaphoreWaitTimeout ] repeat<br>
- !<br>
<br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div>