Stability opf Squeak on Linux

John M McIntosh johnmci at smalltalkconsulting.com
Thu Nov 16 19:05:14 UTC 2000


>John M McIntosh wrote:
>>  Now on the mac if I close my side, we want to go to ThisSideClosed
>>  but since I'm in the state OtherSideClosed I issue a disconnect&close
>>  to terminate the connection and the socket state really goes to
>>  UnConnected. So what would your model do? would it show
>>  ThisSideClosed, and the actual state be Disconnected? Which leads to
>
>No, it closes the socket and the data is not available, even though it
>is still in the buffer.  So we are the same?  It is strictly incorrect,
>isn't it?

Well on the mac I allow the read if data is in the buffer. The 
Smalltalk code seems to want to do this

>
>
>>  If I transition to OtherSideClosed with data pending how come this
>>  isn't a problem? Well it's currently handled by most of the Smalltalk
>>  code (rightly or wrongly) Here is a chunk of code from the HTTPSocket
>>  class which seems typical, or at least used as an example by others.
>>  You can see it checks either for connectivity or for data pending and
>>  as long as data is available it reads it. There are some places were
>>  it does not check for dataAvailable (an error?)
>
>This is a workaround, isn't it?  The assumption in most code, thus the
>defacto standard, is that only when isConnected is true can we read and
>write.  We really need isReadable and isWritable.  While we are at it,
>we could expose the various close semantics to squeak as well like
>shutdownRead, shutdownWrite, and use setOption to change SO_LINGER for
>the regular close call.  And model all those half-closed states in the
>plugin.

You could say this is a workaround, however lots of code might be 
based on it, one of the issues of changing is what to do with 
backwards compatibility. One of the issues with exposing isReadable, 
isWritable is that you always have this race condition between 
checking the flag then doing something.

>
>>  Remember if we are waiting on the read semaphore we could get
>>  signaled, and the state will go to OtherSideClosed, the
>>  primSocket:receiveDataInto may or maynot read ALL the data but will
>>  continue looping until the dataAvailable state indicates there is no
>>  more data.
>
>yes and thus get all of the data up to the FIN.  However, in the code
>below there may be an exception thrown on the read.  It happens when you
>are waiting for data and the FIN comes in.

On a fin the read semaphore is triggered and the 
primSocket:receiveDataInto: returns 0 bytes read, NOT an exception 
this lets the whileTrue: loop below complete.


>
>>    (response position < buf size) & (self isConnected | self
>>  dataAvailable)] whileTrue: [
>>                  (self waitForDataUntil: (Socket deadlineSecs: 5)) ifFalse: [
>>                          Transcript show: 'data was late'; cr].
>>                  bytesRead _ self primSocket: socketHandle 
>>receiveDataInto: buf
>>                          startingAt: response position + 1 count: buf
>>  size - response position.
>>
>>  >
>>  >>  Also note if we are in ThisEndClosed state and we get a
>>  >>  otherEndClosed I disconnect the socket (state goes to Unconnected)
>>  >>  (which seems reasonable to me at the time).
>>  >
>>  >absolutely, although I do a close to finish the job.
>>
>>  Same here.
>
>But like above, if there is dataAvailable, then the squeak state should
>really be ThisEndClosed until all data has been read (since we are
>readable in thisendclosed, writable in otherendclosed, exceptions thrown
>when it's a full-duplex close).  Do you allow dataAvailable and read in
>this state?  (yes - last paragraph ;)

Ok technically that is correct, but we run into this dual state issue 
because we are buffering the read and end up with the socket 
transition to OtherEndClosed and data lurking in a buffer outside of 
the Socket, if we didn't buffer any data anywhere then I believe we 
would have this issue since the transition to OtherEndClosed wouldn't 
occur until all the data was read.

My point was that the Smalltalk code currently (for the most part) 
handles the situation. The issue now is now to present state to 
Squeak which is meaningful. What you seem to be doing is hiding the 
actual socket state, as long as you deal with issues like having the 
socket closed, yet reporting Connected or ThisEndClosed with 
dataAvailable I can't see this is an issue. I'll consider doing the 
same for the mac, but there isn't a pressing need to change the 
current code there.  One of the issues of course is what the 
Smalltalk code should look like of course and how it will behave on 
different platforms... Do you write it to the correct state, or to 
the existing somewhat undefined viewpoint?

>
>>  >
>>  >John, could you explain the situation around what the return is when you
>>  >primRead from an otherEndClosed socket (and the buffers are empty).  How
>>  >about primWriting to a thisEndClosed socket?  Previously they were
>>  returning 0 (bytesRead/Wrote), I believe.  Are we expecting exceptions
>>
>>  I'm not sure we really handle this correctly. I found an issue with
>>  swikis were sometimes they read on unbound sockets that had gotten at
>
>What is an unbound socket?

The socket structure is created, but it's not been bound to a port yet.

>
>>  some point into read flow control (very interesting state), they got
>>  zero bytes read but just continued looping (why? unknown) For that
>
>I'm not quite sure what the read flow control state is.  Is this
>situation throttling the data window when a large amount of data is
>being sent?

Yes, when a data has arrived is signaled and I don't have anywhere to 
put the data we basically tell the underlying socket we are in read 
flow control. This percolates back to the sender to prevent flooding. 
You might want to understand what you do? Since buffers aren't free! 
When this happens we note it and signal the read semaphore. Later 
when Squeak reads the socket we note the read flow control, ensure 
any queued read buffers are read from then we actually read directly 
into the given Squeak byteArray. This always allows us to read 
somewhere since of course the Squeak Smalltalk code has this 
bytearray it's given us. There is a performance issue here since we 
now are signaling and waiting for Squeak to give us a buffer area 
which takes a bit of time.

So what do you do if there are no read buffers? Hint assuming you 
have one might not be a good thing...

There is some slightly different code to handle this case and some 
different error handling which didn't quite work right for some werid 
socket state errors. However I think these are fixed in the 2.8.4 VM.

PS for minnow I've given them a mac 'Server' VM which has some 
different much higher number for sockets and buffers. Although the 
code 'scales' based on load a dump they sent me last week seemed to 
point to a problem with running low on System Heap space. 
Preallocating lots of System resource ahead of time might have fixed 
the issue with minnow crashing.

>
>>  special case I signaled a primitive failure. Actually this I belive
>>  is a very special case were we had data to read but were flow
>>  controled and couldn't buffer then we got disconnected and closed but
>>  perhaps a stale flag lurks somewhere indicating data is still pending
>>  to read, but now you can't read it...
>>
>>  Right now as long as the socket is valid the read is allowed but
>>  returns zero as  it's result. Typically a read is guarded by a check
>>  for data. If a socket is closed then no more data is available so one
>>  doesn't get to the point of reading since the logic usually is check
>>  for data? if data then read it.
>
>Right.  However, if we were to do a straight read, then we should throw
>an exception, correct?  It is just like if we were to do a write, when
>we are in otherEndClosed and the other end closed both channels.  We
>really have an large number of close states, either (2^4 - 2) or (4^2 -
>2).  :)   The minus two is Established state and Closed state.

Right now we don't really throw any exceptions on read issues. 
However I believe we should change this

**** For lurkers **** This could affect your code

I suggest we change the read logic so that a primitive failure? is 
thrown if the socket is unreadable. Right now the historical response 
is to return -1 which is bogus. The Swiki code actually has a patch 
to catch the -1 and return 0!

However we do not want to throw an exception if the state is 
unconnected because much of the smalltalk code does, waitForData, 
read, check if dataAvailable. As you see the waitForData terminates 
when we transition from Connected to Unconnected, but the read will 
run...

>
>>  I allow reading on sockets that are valid and closed, because of
>>  course they might have data in the buffer still pending to read, and
>>  as  you see from the code fragment above Squeak is happy with that
>  > state.
>
>I can change this for unix, no problem.  However, I would rather keep
>the public state as ThisEndClosed until all data is read.

That is fair, and of course you keep it as connected and transition 
to OtherEndClosed if you've got the state of data pending and an 
OtherEndClosed pending. I can see no problems in doing since 
technically it's correct from the state perspective.

>
>So what to do.
>
>cheers,
>Rob
>
>>  >now
>>  >Rob
>>  --
>>  --
>>  ===========================================================================
>>  John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
>>  Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
>>  ===========================================================================
>>  Custom Macintosh programming & various Smalltalk dialects
>>  PGP Key: DSS/Diff/46FC3BE6
>>  Fingerprint=B22F 7D67 92B7 5D52 72D7  E94A EE69 2D21 46FC 3BE6
>>  ===========================================================================
>
>--
>--------------------------------------------------
>Smalltalking by choice.  Isn't it nice to have one!

-- 
--
===========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================
Custom Macintosh programming & various Smalltalk dialects
PGP Key: DSS/Diff/46FC3BE6
Fingerprint=B22F 7D67 92B7 5D52 72D7  E94A EE69 2D21 46FC 3BE6
===========================================================================





More information about the Squeak-dev mailing list