Squeak Socket Primitives

Marcel Weiher marcel at metaobject.com
Fri Nov 12 17:00:27 UTC 1999


> From: Craig Latta <Craig.Latta at NetJam.ORG>
[Andreas wrote]
> > "Client pushing data (using Correspondants prims)"
> > client _ NetStream tcpClientToPort: 22334 atHostNamed: 'localhost'. 
> > client nextPutAll: (String new: 100000). "<- This will block!"
> >
> > ...and your Squeak stands forever.
> -	My code only blocked because select() on win32 is broken (as  
I found out during
> debugging). According to the Microsoft manual pages (and all  
Berkeley sockets
> manual pages, and my own experience), select() on a blocking  
socket is supposed
> to block until a desired operation (in this case, writing) is  
possible without
> blocking. Instead, in this case (when the socket is an endpoint of  
a virtual
> circuit from which a substantial amount of data has been written  
without being
> consumed), it returns immediately, when the socket is not ready  
for writing. My
> (blocking) write primitive is only called after this select()  
returns. Since
> that return comes before the socket is ready for writing, it  
blocks. I have a
> workaround if you truly think that example is compelling.
[..]

I am probably about to place my foot squarely into my mouth but here  
it goes anyway:

select() only tells you that the descriptor is now ready to receive  
*some* data.  It doesn't specify how much.  With a socket/pipe etc.  
on UNIX it is usually one kernel buffer's worth ( typically 4K or  
8K).  That is the amount you should be able to safely write without  
blocking.  If you write more than a buffer's worth, your write() call  
will *definitely* block, even if the receiver is picking up data  
just fine, even in a pipe-situation, just to context-switch to the  
other process and give it a chance to read.

So in the example above, the primitive should split any write into  
4K chunks (or 1K just to be on the safe side) and then check before  
each write.  Of course, it could also just use non-blocking I/O.

> 	Anyway, it was true that at some point the client socket was  
unable to send
> further data (no matter which primitives you use). The strange  
thing was that my
> code blocked, since, as I've been trying to say, I designed my  
framework to do any
> necessary waiting before actually attempting a blocking operation.  
There
> seemed to be a bug somewhere.

See discussion above, this is to be expected, unless there is  
something about your code that I do not understand.

BTW, this entire has been very interesting.  I have a feeling that  
it points to a need for a general solution for dealing with 'events'  
from the outside world, essentially an abstraction that concentrates  
event handling into a single place where these types of variables (  
who is in charge, who blocks, etc. ).

Such an abstraction needs to be able to be used effortlessly by  
implemenetations with minimal to no OS support (this is important  
because they have the hardest task already), but should also not  
stand in the way of integrating nicely with OSes that have rich  
facilities in this area.

Marcel
(trying to extract foot from mouth...)





More information about the Squeak-dev mailing list