[UNIX][ALPHA][NET] When to tap the r/w sems?

Lex Spoon lex at cc.gatech.edu
Wed Jul 26 13:21:44 UTC 2000


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.

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).

-Lex



Rob Withers <slosher2 at home.com> wrote:
> Below are the code chunks.  The only time we are going to be waiting on
> the semaphore is if we call one of the 'checking' methods
> (SendDone/DataAvailable).  I am checking the readFlag in the async
> handler, that was installed for data ops, and SETting the flag for
> semaphore tap.  This means that I'm always tapping, but I thought I was
> only to do it during an intent call.   Should I remove the SET_.. calls
> in the async handler?
> 
> thanks,
> Rob
> 
> The SET_... sets a flag that the tapSemaphores(pss) method checks for,
> taps is set, then clears the flag.
> Here are two chunks of code from the unix network code:
> 
> /* async handler for data operation */
> static void dataHandler(privateSocketStruct *pss, int errFlag, int
> readFlag)
> {
>         aioSuspend(pss);
> 
>         FPRINTF((stderr, "dataHandler(%d,%d,%d)\n", pss->s, errFlag,
> readFlag));
>         if (errFlag)
>                 pss->sockState = OtherEndClosed;   /* error: almost
> certainly "connection closed by peer" */
>         if (readFlag) {
>                 SET_TAPREADSEM(pss);
>         } else {
>                 SET_TAPWRITESEM(pss);
>         }
>         tapSemaphores(pss);  
> }
> 
> 
> And the two primitives for checking for readAvailable and sendDone:
> 
> /* answer whether the socket has data available for reading */
> int sqSocketReceiveDataAvailable(SocketPtr s)
> {
>   if (!socketValid(s)) return -1;
>   if (SOCKETSTATE(s) == Connected) {
>     if (socketReadable(SOCKET(s))) return true;
>     SET_TAPREADSEM(PSP(s));
>     aioHandle(PSP(s), dataHandler, AIO_RW);
>   }
>   return false;
> }
> 
> /* answer whether the socket has space to receive more data */
> int sqSocketSendDone(SocketPtr s)
> {
>   if (!socketValid(s)) return -1;
>   if (SOCKETSTATE(s) == Connected) {
>     if (socketWritable(SOCKET(s))) return true;
>     SET_TAPWRITESEM(PSP(s));
>     aioHandle(PSP(s), dataHandler, AIO_RW);
>   }
>   return false;
> }
> 
> 
> -- 
> --------------------------------------------------
> Smalltalking by choice.  Isn't it nice to have one!





More information about the Squeak-dev mailing list