Subject: [clisp-list] Re: proposed modifications to SOCKET-STATUS

From: [email-masked] (Don Cohen)
Date: Wed Jan 29 19:48:06 2003

> please read
 > <http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/clisp/clisp/doc/impnotes.html?rev=HEAD&content-type=text/html#so-status>

  (SOCKET:SOCKET-STREAM . direction)
            Return the status in the specified direction 
Just to be sure, this means if direction is :input then the
value is one of nil, :input, :eof ?
[All these questions should be explicit in doc.]
Any direction other than :input or :output is an error?
It would also be reasonable to make :io legal.

  If you want to avoid CONSing up a fresh list, you can make the
  elements of socket-stream-or-list to be
      (socket-stream direction . x) or (socket-stream) or
You really have to change (socket-stream) to (socket-stream . x)
since after the first call that's what it'll be.
At least for x in the set of results (not (cons direction x)),
And similarly for socket-server below.

  (socket-server). Then SOCKET:SOCKET-STATUS
  will destructively modify its argument and replace x or NIL with
  the status and return the modified list.

It's also an error to supply a list where some elements are of that
form and others are not?

  The second value returned is the number of objects with non-NIL
  status, i.e., "actionable" objects.
This is for both cases of lists (mapcar and destructive) ?

I suggest that the direction inputs be changed from 
{input, output, nil} to {input, output, io} and get rid of
(stream . x) in favor of (stream :io . x)

I'd still like to know what the timeout is all about.  What
information is not available immediately?  If status starts out as
:output then if I wait it might change to :io ?  Why is that not
waiting for input?

Also, I'm afraid man select didn't tell me much about :error.
It looks to me like input, output, exception are all independent.
So there should be 3 separate dimensions.

What exactly are exceptions?  Do they all generate lisp errors?
Is select really consistent accross OS's ?

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 30 08:35:02 2003

> * In message <[email-masked]>
> * On the subject of "Re: proposed modifications to SOCKET-STATUS"
> * Sent on Wed, 29 Jan 2003 19:45:49 -0800
> * Honorable [email-masked] (Don Cohen) writes:
>
>  > please read

what is not clear here?

Additionally, for a SOCKET:SOCKET-STREAM, we define "status" in the
given direction (one of :INPUT, :OUTPUT, and :IO) to be

:INPUT status:

NIL
    reading will block 
:INPUT
    some input is available 
:EOF
    the stream has reached its end 

:OUTPUT status:

NIL
    writing will block 
:OUTPUT
    output to the stream will not block 

Table 30-8. :IO status
                        input status
output status           NIL      :INPUT          :EOF
NIL                     NIL      :INPUT          :EOF
:OUTPUT                 :OUTPUT  :IO             :APPEND

> since after the first call that's what it'll be.

I cannot: if the status happens to be :input, then the next call will
check the status only in the input direction.

> It's also an error to supply a list where some elements are of that

no - but the only way to avoid consing is to have all elements in the
specified form.

> This is for both cases of lists (mapcar and destructive) ?

of course - why would you think otherwise?!

> I'd still like to know what the timeout is all about.

it's about waiting for input to arrive or output to be cleared or
connection to come our way.

> If status starts out as :output then if I wait it might change to :io?

if the status now is :OUTPUT, you will not wait.
to wait for input you need to do (SOCK :INPUT).

> Why is that not waiting for input?

huh?

> Also, I'm afraid man select didn't tell me much about :error.  It
> looks to me like input, output, exception are all independent.  So
> there should be 3 separate dimensions.

exception obviously overrides all the others: if there is an exception,
then no i/o is possible.

> Is select really consistent accross OS's ?

I know just as much as you do.
I have never seen SOCKET-STATUS return :ERROR

why don't you play with SOCKET-STATUS a little bit and see whether it
does what you expect?
In particular, if you think that the doc says FOO, please try FOO with
SOCKET-STATUS and see if that is the case.  If it is NOT, please read
the doc again.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
I'd give my right arm to be ambidextrous.

---

From: [email-masked] (Don Cohen)
Date: Thu Jan 30 09:42:09 2003

[Oops, you're right that some of my questions were answered in doc.
I hate to get such questions too, so sincerely apologize and will 
try harder not to let it happen again.]

 > check the status only in the input direction.

I think (hope) we're complaining about the same thing here.
I think you should be able to do:
 (setf arg (list (list stream)))
 (socket-status arg)
and if arg is now ((<stream> . :output))
you should be able to again do
 (socket-status arg)
with the possibility of ending up with arg being ((<stream> . :io))
That is, the list element (<stream> . nil) is interpreted as
(<stream> . x) where x is to be replaced, and in fact, so is
(<stream> . :input) or any other (<stream> . x) where x is one
of the possible outputs.  The fact that we have to distinguish here
the case of x being :output vs (:output) is why I suggested that
this case be eliminated and replaced by 
(<stream> <:input/:output/:io> . x)

 > no - but the only way to avoid consing is to have all elements in the
So if one has that form and another doesn't then no smashing is done
and you get mapcar behavior?  Or you smash the ones with the right
format and still return a new list?  I think it would be more useful
to generate an error in the mixed case.  Otherwise people who
generate mixed cases accidentally are going to be very confused.

 > of course - why would you think otherwise?!
Even if I did think it was obvious, obvious doesn't always imply correct.

I take it the first value in the smashing case is the input list?
(That's a little more obvious, but still worth saying.)

 > > Why is that not waiting for input?
This is what I don't understand:
  Note that this function never waits for input or output to arrive,
  only for information on input or output presence
This seems to indicate that there's some information about whether
input or output is NOW possible that is not available yet and we
could get it if we wait.

I think you're saying that it DOES wait for input to arrive if none
is available and you ask whether input is possible with a non-zero
timeout.

Perhaps it should be something like:
  The only case where this function waits at all is when the answer
  for every stream/direction argument would be nil.
(Is that true?  Or does it wait if ANY answer would be nil?)

 > I know just as much as you do.
(a sad state of affairs!)
 > I have never seen SOCKET-STATUS return :ERROR
That's at least somewhat encouraging.  Neither have I.

 > why don't you play with SOCKET-STATUS a little bit and see whether it
You suggest blind search, and that only to see what one particular
implementation does, whereas I really want a spec.

---

From: Sam Steingold <[email-masked]>
Date: Thu Jan 30 11:42:11 2003

please look at
<http://clisp.cons.org/impnotes-new.html#so-status>
<http://clisp.cons.org/impnotes-new/socket.html#so-status>
before replying to this message.

> * In message <[email-masked]>
> * On the subject of "[clisp-list] Re: proposed modifications to SOCKET-STATUS"
> * Sent on Thu, 30 Jan 2003 09:38:44 -0800

I am confused.

Unambiguous arguments are:
        (stream direction . x)
and
        stream

how should (stream . :input) be interpreted?
I argue for a backward compatible interpretation (which is tenuous since
the backward compatibility has been broken already by higher status
granularity).

> generate mixed cases accidentally are going to be very confused.

right now we so "smashing" whenever possible and cons a list whenever
necessary.
(please make sure this is actually the case :-)

> (That's a little more obvious, but still worth saying.)

it does say that:

        If you want to avoid CONSing up a fresh list, you can make the
        elements of socket-stream-or-list to be (socket-stream direction
        . x) or (socket-stream) or (socket-server). Then
        SOCKET:SOCKET-STATUS will destructively modify its argument and
        replace x or NIL with the status and return the modified list.

>   only for information on input or output presence

this is a quote from the select(2) manual.

> (Is that true?  Or does it wait if ANY answer would be nil?)

yes.

        The second value returned is the number of objects with non-NIL
        status, i.e., "actionable" objects. SOCKET:SOCKET-STATUS returns
        either due to a timeout or when this number is positive, i.e.,
        if the timeout was NIL and SOCKET:SOCKET-STATUS did return, then
        the second value is positive.

> implementation does, whereas I really want a spec.

I suggest that you __TEST__ CLISP.
It is important to discuss the spec, but it is also important to check
that the code works.  When you say "let's change the spec like this",
please do supply a test case where CLISP works against your desires.

And don't tell me "spec first". :-)

--
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
UNIX is a way of thinking.  Windows is a way of not thinking.

---

From: [email-masked] (Don Cohen)
Date: Thu Jan 30 12:22:26 2003

> the backward compatibility has been broken already by higher status

I finally understand - this is backward compatible.
In that case I suggest that it NOT be acceptable for the smashing
case.  (I'd also be happy if it were not acceptable at all.)

 > right now we so "smashing" whenever possible and cons a list whenever
(but never a combination)

 > this is a quote from the select(2) manual.
not in mine (linux) - I wonder what it means

 > > (Is that true?  Or does it wait if ANY answer would be nil?)

I take it you think "every" is right.
I must say the select doc leaves something to be desired too.
It says "waits for a number of file descriptors to change status."
That seems to mean that if you use only fds that are both
readable and writable then it waits (since this status doesn't change)
but I'd expect from the point of view of what's useful for it to
return immediately, i.e., it waits for the following condition:
 some fd in the input set is readable or some fd in the output set
 is writable or some fd in the exception set has an exception

So if timeout >0 then the answer should either be 0 (and the timeout
has been reached) or 1 (unless multiple status changes can happen at
once).