Rob Withers slosher2@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
Lex Spoon wrote:
Rob Withers slosher2@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.
That's definitely true, and I'm not suggesting changing the current implementation. We have to support backwards (at least until a major number change). This is all predicated on a feel that having all io go though events, would result in a clearer and more direct framework. We would get tremendous amounts of reuse and controlling all devices as the same beastie would be interesting.
I got my flags confused there, the ones that are sent with the select() is what I missed.
Rob
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
squeak-dev@lists.squeakfoundation.org