Rob Withers <slosher2(a)home.com> wrote:
> Lex Spoon wrote:
> >
> > It seems reasonable to me to tap when there is a *change* in the read or
> > write flag. In fact, if the image sockets code is modified to drain
> > semaphores instead of just reading one signal at a time, then we could
> > completely stop checking whether we think the image is watching or not,
> > and just signal any events that someone in the image might be interested
> > in.
>
> Right on. In that scenario, I think we would only have one Semaphore in
> the platform socket code to serialize the interaction of the socket
> commands (create, listen, accept, connect, close, shutdown, read, write)
> and the async handlers. If we link into Tims's event code and buffer in
> the socket code (performance), then we could wait on an image semaphore
> (for that socket), perhaps with a timeout, and upon a signal from the
> arrival of an event, we would check socket state or read data. There
> could also be a write buffer in the platform socket code, so it should
> be thread safe.
I didn't follow all this, but it sounds pretty cool. Certainly socket
events could go through a global event stream. Also certainly, they
don't have to, and things are okay as they are. Either way seems okay.
>
> I am not sure I am following you on the change in flags. In fact, if we
> make the sockets eventful, then we would always send an event when
> anything happens (connect, read, write, exception).
select() tells you whether a socket is read-able or not, but it doesn't
tell you when it *becomes* readable. So you have to watch for a
transition from unreadable to readable. The image will only see
events, but the VM authors have to actually manufacture those events.
>
> > In Unix, this would suggest that dataHandler and friends be given seven
> > arguments:
> >
> > the fd
> > the current read, write, and exceptions flags
> > the previous read, write, and exceptions flags
> >
> > The data handlers can then signal the relevant semaphore whenever read
> > or write goes from 0 to 1.
>
> > This approach *does* require some slight trickery in order to make the
> > select() wait properly: do one select to wait for stuff to happen, and
> > then do another select() to update all three flags for all open sockets.
> > (Note you can't ask select() to watch for a flag changing from 1 to 0).
>
> I am confused about this. The tapFlags in the current code are to
> inform the async handlers of intent. If the intent flags get set in the
> sendDone or dataAvailable primitives, then the client is going to wait
> on the semaphore, so tap on it. The scenario you painted with the read,
> write, and excpetion flags sound like the FD flags for select. I am not
> entirely sure about the select() call but isn't it known when the select
> occurs that whatever the current flags are set, is the event that
> occu
Keeping track of whether someone is watching for read events seems a
little complicated. Furthermore, it still sends events that get
ignored: for example, I've written a good bit of network code that does
call sendDone but which doesn't use waitForSendDone:. This code doesn't
wait on the semaphore until it closes the socket down.
So I propose, just signal every event, and if no one is interested, they
can just ignore them. The image code should then be updated to deal with a
slew of identical events arriving in a row.
-Lex