Stability opf Squeak on Linux
slosher2 at home.com
Thu Nov 16 06:32:22 UTC 2000
John M McIntosh wrote:
> > >
> >> We should decide if this is valid? Technically I could get a read
> >> event, where we read the data into an internal buffer, then signal
> >> the read semaphore, then the otherEndClosed event comes in. Thus we
> >> now have the socket in otherEndClosed state but data still pending to
> >> be read.
> >I do this too by keeping 2 states, the os descriptor state and the
> >squeak socket state. At that point in time I have (TCPOtherEndClosed,
> >Connected, data in buffer). When the last data is read from the buffer,
> >I transition the squeak state to OtherEndClosed. I am fluxuating
> >between whether it is still writable in this state. If the other end,
> >whatever the environment, does a shutdown(SHUT_WR), then we should still
> >be writable on this end.
> There are some issues with keeping a dual state model. However right
> now on the macintosh the state goes to othersideclosed with data
> pending. In your model I'm assuming the visible state stays as
> connected with data pending, but the actual state is othersideclosed
> with data pending.
That's it. Furthermore, I select for write (if the write flag is set
for the semaphore) events on the half-closed descriptor.
> 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,
> my question do you want to run a dual state model, what does it buy?
The state machines for the os sockets and Squeak are different.
Tracking them separately allows each state machine to transition out of
phase and allows for a different number of states. For instance, I can
model the listen state as distinct from the waitingForConnection state,
as well as the closed state. I wanted to buffer the read and write,
originally, but ended up just buffering the read. This allows the host
socket state to transition immediately in response to the FIN and any
other errors. If this dual state needed to be removed, then I would
keep the os state machine, and figure out the squeak state in the status
There are two changes that I would like to make, when time permits.
First, move to a free buffer list, like you use. Second, I only modeled
the state machine for select events, whereas I should also model the
different command events in the state machine. For example, a write
command has different actions when the descriptor is in different
states, as we are discussing.
> Now the reason I ask is because some of the issues with a single
> state model are handled with Smalltalk code (trial and error I think).
This seems to be the same view I have. *Some* of the issues are
handled, but which ones?
> 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
> 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.
> (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 ;)
> >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?
> 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
> 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.
> 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
I can change this for unix, no problem. However, I would rather keep
the public state as ThisEndClosed until all data is read.
So what to do.
> 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!
More information about the Squeak-dev