Hi Holger,

On 26 Mar 2013, at 12:12, Holger Hans Peter Freyther <hol...@freyther.de> wrote:

> Hi,
> 
> I am porting a tooling class that I wrote on GST for my SIP and MGCP code
> to Pharo. This class will create a socket and then fork a RX and TX process.
> I have some issues with 'stopping' the socket. I have created an example
> that shows the issue in Pharo 2.0 and Pharo 1.4 with the pharovm (and to
> have more debug output with a re-compiled one).
> 
> 
>       | s rx |
>       s := Socket newUDP.
>       rx := [
>               [s waitForData. s halt]
>                       on: ConnectionClosed do: [ s halt]
>               ] fork.
>       "Wait for the process to hit the readSemaphore"
>       (Delay forSeconds: 3) wait.
>       s close.
> 
> 
> My expectation is that I will get the ConnectionClosed signal or at least
> that >>#waitForData will return once the socket is closed. This is based
> on reading the comment of >>#waitForData.
> 
> 
> The Socket>>#waitForData documentation reads like this:
>       "Wait for data to arrive.  This method will block until
>       data is available or the socket is closed.  If the socket is closed
>       a ConnectionClosed exception will be signaled."
> 
> 
> I had a look at the socket plugin and the following is happening. First
> aio is disabled, the state set to ThisEndClosed, then ::close is called
> and in the above case the result is '0' and the following code will be
> executed:
> 
> else if (0 == result)
>     {
>       /* close completed synchronously */
>       SOCKETSTATE(s)= Unconnected;
>       FPRINTF((stderr, "closeConnection: disconnected\n"));
>       SOCKET(s)= -1;
>     }
> 
> 
> this means that my 'rx' process will happily wait on the readSemaphore
> of the Socket and will never be woken up.
> 
> 
> My question are probably:
> 
> 1.) Is this the intended behavior for Socket>>#close and Socket>>#waitForData?
> 2.) How should I terminate my RX process?
> 
> kind regards
>       holger
> 
> PS: The issue is probably socket specific and not related to UDP.

Maybe I am telling you things you already know, but TCP and UDP are 
fundamentally different. UDP is really one-shot, try-and-hope, completely 
asynchronous. In networking you generally only get a ConnectionClosed when you 
actually read or write (and even then ;-). 

The Socket API has many strange methods, most of which you should not touch. 
You should use SocketStream. Looking in the VM code is also misleading because 
the 3 platforms (Mac, Win, *nix) are different. In Socket[Stream] there is lots 
of historic baggage.

I would suggest you look at Smalltalk code that actually works (for TCP, Zinc 
Client and Server code would do, for UDP, ZTimestampSNTPClient for example).

For your concrete question (2): just start a reading process, wrap it in a 
handler and clean up. For UDP this will never happen: you will keep on reading 
nothing. For TCP reading will eventually fail if the other end disappears.

HTH,

Sven 

--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill


Reply via email to