Hi Holger,
On 26 Mar 2013, at 12:12, Holger Hans Peter Freyther <[email protected]> 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