[squeak-dev] Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Klaus D. Witzel
I'm trying to provoke the Exceptions which Socket>>#waitForDataFor: would  
signal on failure (and test that it does so), to no avail (no, the .image  
isn't locked and the process doesn't hang).

The below runs in both the Squeak 3.9,3.8 final .images with both the  
3.10.2,3.10.6 VMs on win32; the worker process always terminates without  
an exception.

The implementation of #waitForDataFor:  
(#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable returns  
true but there cannot be any data since nothing was ever sent. *but* after  
closing the client side, the other side's #dataAvailable  
(#primSocketReceiveDataAvailable) returns true ...

Any hint(s) on what's going on (or wrong) will be recognized with  
gratitude.

/Klaus

  | localhost serverSocket sessionSocket clientSocket worker |

  localhost := NetNameResolver localHostAddress.
"warning:" Socket allInstancesDo: [:socket | socket destroy].
  serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1.
  clientSocket := Socket newTCP connectNonBlockingTo: localhost port: 7680.
  sessionSocket := serverSocket waitForAcceptFor: 1.
  worker := [sessionSocket waitForDataFor: 1] fork.
  Processor yield.
  Transcript cr; show: serverSocket statusString, ' [server]';
        cr; show: clientSocket statusString, ' [client]';
        cr; show: sessionSocket statusString, ' [session], dataAvailable: '
                , sessionSocket dataAvailable storeString;
        cr; show: 'worker: ', worker browserPrintString.
  [clientSocket close] on: Exception do: [:ex|].
  Processor yield.
  Transcript cr; show: serverSocket statusString, ' [server]';
        cr; show: clientSocket statusString, ' [client]';
        cr; show: sessionSocket statusString, ' [session], dataAvailable: '
                , sessionSocket dataAvailable storeString;
        cr; show: 'worker: ', worker browserPrintString; cr.
  [sessionSocket destroy] on: Exception do: [:ex|].
  [clientSocket destroy] on: Exception do: [:ex|].
  [serverSocket destroy] on: Exception do: [:ex|]


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Igor Stasenko
I think it was done intentionally,
when socket closed , it signals that data available, to awake process
which waiting for data. Then, when process tries to read it, it
returns 0 bytes.

I think it's same as with socket's read() function.
If remote side closed gracefully, a blocking read() function returns
with 0, indicating that there 0 bytes read, and connection is closed.

On 25/02/2008, Klaus D. Witzel <[hidden email]> wrote:

> I'm trying to provoke the Exceptions which Socket>>#waitForDataFor: would
>  signal on failure (and test that it does so), to no avail (no, the .image
>  isn't locked and the process doesn't hang).
>
>  The below runs in both the Squeak 3.9,3.8 final .images with both the
>  3.10.2,3.10.6 VMs on win32; the worker process always terminates without
>  an exception.
>
>  The implementation of #waitForDataFor:
>  (#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable returns
>  true but there cannot be any data since nothing was ever sent. *but* after
>  closing the client side, the other side's #dataAvailable
>  (#primSocketReceiveDataAvailable) returns true ...
>
>  Any hint(s) on what's going on (or wrong) will be recognized with
>  gratitude.
>
>  /Klaus
>
>   | localhost serverSocket sessionSocket clientSocket worker |
>
>   localhost := NetNameResolver localHostAddress.
>  "warning:" Socket allInstancesDo: [:socket | socket destroy].
>   serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1.
>   clientSocket := Socket newTCP connectNonBlockingTo: localhost port: 7680.
>   sessionSocket := serverSocket waitForAcceptFor: 1.
>   worker := [sessionSocket waitForDataFor: 1] fork.
>   Processor yield.
>   Transcript cr; show: serverSocket statusString, ' [server]';
>         cr; show: clientSocket statusString, ' [client]';
>         cr; show: sessionSocket statusString, ' [session], dataAvailable: '
>                 , sessionSocket dataAvailable storeString;
>         cr; show: 'worker: ', worker browserPrintString.
>   [clientSocket close] on: Exception do: [:ex|].
>   Processor yield.
>   Transcript cr; show: serverSocket statusString, ' [server]';
>         cr; show: clientSocket statusString, ' [client]';
>         cr; show: sessionSocket statusString, ' [session], dataAvailable: '
>                 , sessionSocket dataAvailable storeString;
>         cr; show: 'worker: ', worker browserPrintString; cr.
>   [sessionSocket destroy] on: Exception do: [:ex|].
>   [clientSocket destroy] on: Exception do: [:ex|].
>   [serverSocket destroy] on: Exception do: [:ex|]
>
>
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Klaus D. Witzel
On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote:

> I think it was done intentionally,
> when socket closed , it signals that data available, to awake process
> which waiting for data. Then, when process tries to read it, it
> returns 0 bytes.

Nothing speaks against such behavior except the method's comment "Wait for  
the given nr of seconds for data to arrive. Signal a time out or  
connection close exception if either happens before data becomes  
available."

> I think it's same as with socket's read() function.
> If remote side closed gracefully, a blocking read() function returns
> with 0, indicating that there 0 bytes read, and connection is closed.

So senders of #waitForDataFor: cannot know about closed connections (even  
if the comment says the opposite) and *must* do at least #receiveSomeData  
because #waitForDataFor: can't handle all the possible situations?

> On 25/02/2008, Klaus D. Witzel wrote:
>> I'm trying to provoke the Exceptions which Socket>>#waitForDataFor:  
>> would
>>  signal on failure (and test that it does so), to no avail (no, the  
>> .image
>>  isn't locked and the process doesn't hang).
>>
>>  The below runs in both the Squeak 3.9,3.8 final .images with both the
>>  3.10.2,3.10.6 VMs on win32; the worker process always terminates  
>> without
>>  an exception.
>>
>>  The implementation of #waitForDataFor:
>>  (#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable  
>> returns
>>  true but there cannot be any data since nothing was ever sent. *but*  
>> after
>>  closing the client side, the other side's #dataAvailable
>>  (#primSocketReceiveDataAvailable) returns true ...
>>
>>  Any hint(s) on what's going on (or wrong) will be recognized with
>>  gratitude.
>>
>>  /Klaus
>>
>>   | localhost serverSocket sessionSocket clientSocket worker |
>>
>>   localhost := NetNameResolver localHostAddress.
>>  "warning:" Socket allInstancesDo: [:socket | socket destroy].
>>   serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1.
>>   clientSocket := Socket newTCP connectNonBlockingTo: localhost port:  
>> 7680.
>>   sessionSocket := serverSocket waitForAcceptFor: 1.
>>   worker := [sessionSocket waitForDataFor: 1] fork.
>>   Processor yield.
>>   Transcript cr; show: serverSocket statusString, ' [server]';
>>         cr; show: clientSocket statusString, ' [client]';
>>         cr; show: sessionSocket statusString, ' [session],  
>> dataAvailable: '
>>                 , sessionSocket dataAvailable storeString;
>>         cr; show: 'worker: ', worker browserPrintString.
>>   [clientSocket close] on: Exception do: [:ex|].
>>   Processor yield.
>>   Transcript cr; show: serverSocket statusString, ' [server]';
>>         cr; show: clientSocket statusString, ' [client]';
>>         cr; show: sessionSocket statusString, ' [session],  
>> dataAvailable: '
>>                 , sessionSocket dataAvailable storeString;
>>         cr; show: 'worker: ', worker browserPrintString; cr.
>>   [sessionSocket destroy] on: Exception do: [:ex|].
>>   [clientSocket destroy] on: Exception do: [:ex|].
>>   [serverSocket destroy] on: Exception do: [:ex|]
>>
>>
>>
>
>



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Igor Stasenko
On 25/02/2008, Klaus D. Witzel <[hidden email]> wrote:

> On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote:
>
>  > I think it was done intentionally,
>  > when socket closed , it signals that data available, to awake process
>  > which waiting for data. Then, when process tries to read it, it
>  > returns 0 bytes.
>
>
> Nothing speaks against such behavior except the method's comment "Wait for
>  the given nr of seconds for data to arrive. Signal a time out or
>  connection close exception if either happens before data becomes
>  available."
>
>
>  > I think it's same as with socket's read() function.
>  > If remote side closed gracefully, a blocking read() function returns
>  > with 0, indicating that there 0 bytes read, and connection is closed.
>
>
> So senders of #waitForDataFor: cannot know about closed connections (even
>  if the comment says the opposite) and *must* do at least #receiveSomeData
>  because #waitForDataFor: can't handle all the possible situations?
>

I really don't know how primitives handling this. So it's only my
guess why data signaled when there is no data at all.

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

johnmci
Some thoughts at

http://www.smalltalkconsulting.com/html/OTNotes1.html
http://www.smalltalkconsulting.com/html/OTNotes2.html
http://www.smalltalkconsulting.com/html/OTNotes3.html
http://www.smalltalkconsulting.com/html/OTNotes4.html
http://www.smalltalkconsulting.com/html/OTNotes5.html

These might not match reality any more.

On Feb 25, 2008, at 9:31 AM, Igor Stasenko wrote:

> I really don't know how primitives handling this. So it's only my
> guess why data signaled when there is no data at all.
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Socket>>#waitForDataFor: and #primSocketReceiveDataAvailable

Klaus D. Witzel
In reply to this post by Igor Stasenko
The situation is even more strange with one particular sender of  
#waitForDataFor*, when attempting to receive data *after* the Socket had  
been disconnected on this side:

  | localhost serverSocket clientSocket worker |

  localhost := NetNameResolver localHostAddress.
"warning" Socket allInstancesDo: [:socket | socket destroy].
  serverSocket := Socket newTCP listenOn: 7680.
  clientSocket := Socket newTCP connectTo: localhost port: 7680.
  [clientSocket disconnect] on: Exception do: [:ex|].
  (Delay forMilliseconds: 125) wait.
  worker := [clientSocket receiveDataTimeout: 1
        into: (ByteArray new: 1) startingAt: 1]
                forkAt: Processor activeProcess priority.
  (Delay forMilliseconds: 125) wait.
  Transcript cr; show: serverSocket statusString, ' [server]';
        cr; show: clientSocket statusString, ' [client], dataAvailable: '
                , clientSocket dataAvailable storeString;
        cr; show: 'worker: ', worker browserPrintString; cr.
  [clientSocket destroy] on: Exception do: [:ex|].
  [serverSocket destroy] on: Exception do: [:ex|]

No exception: #receiveDataTimeout* passes empty blocks to #waitForDataFor*  
:(

- http://bugs.squeak.org/view.php?id=6951

On Mon, 25 Feb 2008 18:31:51 +0100, Igor Stasenko wrote:

> On 25/02/2008, Klaus D. Witzel wrote:
>> On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote:
>>
>>  > I think it was done intentionally,
>>  > when socket closed , it signals that data available, to awake process
>>  > which waiting for data. Then, when process tries to read it, it
>>  > returns 0 bytes.
>>
>>
>> Nothing speaks against such behavior except the method's comment "Wait  
>> for
>>  the given nr of seconds for data to arrive. Signal a time out or
>>  connection close exception if either happens before data becomes
>>  available."
>>
>>
>>  > I think it's same as with socket's read() function.
>>  > If remote side closed gracefully, a blocking read() function returns
>>  > with 0, indicating that there 0 bytes read, and connection is closed.
>>
>>
>> So senders of #waitForDataFor: cannot know about closed connections  
>> (even
>>  if the comment says the opposite) and *must* do at least  
>> #receiveSomeData
>>  because #waitForDataFor: can't handle all the possible situations?
>>
>
> I really don't know how primitives handling this. So it's only my
> guess why data signaled when there is no data at all.
>