Ian Piumarta <ian.piumarta(a)inria.fr> wrote:
> > Bad ... I just looked at the plugin side of it and it turns out that the
> > code for receiveDataAvailable _cannot_ return an error code. The return
> > code is converted into a boolean and any non-zero return value will be
> > interpreted as "true". There ya go. Gotta check my own code now.
>
> Well spotted!
>
> FWIW, I've looked over the socket code and I can't see any obvious
> reason for the "extraneous" signals. The semaphores are "enabled" (or
> "armed" or "primed" or whatever) in precisely those two places implied
> by John Mc's socket document (i.e., recvDataAvail and sendDone).
> `pendingEvents' (local to each socket) is ORed with a mask indicating
> if read and/or write signals are wanted. If select() finds that a
> socket is readable/writable then it invokes dataHandler() for the
> socket; if dataHandler() sees that the socket's read and/or write
> sempahore is "enabled" (corresponding bit set in pendingEvents) then
> the sempahore(s) is/are signaled before resetting pendingEvents to
> zero.
>
> The logic seems infallible.
Ok, thanks for the runthrough. And I think I might have misunderstood
it.
The call:
PSP(s)->pendingEvents|= READ_NOTIFY;
In:
> > int sqSocketReceiveDataAvailable(SocketPtr s)
> > {
> > if (!socketValid(s))
> > return -1;
> > if (SOCKETSTATE(s) == Connected)
> > {
> > if (socketReadable(SOCKET(s)))
> > return true;
> > PSP(s)->pendingEvents|= READ_NOTIFY;
> > aioHandle(SOCKET(s), dataHandler, PSP(s), AIO_RW);
> > }
> > return false;
> > }
that line is just "enabling" subsequent signals to the semaphore (of
course).
Somehow I mistakenly got the impression that this was a "pending signal"
in itself.
> On the other hand, there *does* seem to be a problem with the use of
> recvDataAvail and sendDone as "guard clauses" (John's words, my quotation
> marks). If the timeout expires before the semaphore is signaled, the
> semaphore remains "enabled". A subsequent change of state on the socket
> will signal the semaphore, even though the image is no longer waiting on
> it. This additional "excess signal" seems to be the one that you (Goran)
> are seeing -- although it's difficult to see how the signal gets there in
> the first place, since senders of waitForDataUntil: tend to raise an error
> if the deadline expires. Hmm...
Hmmm indeed.
Did you run through my somewhat clumsy test that I posted?
Just so that you have seen it yourself. :-)
> BTW, I suspect that your "initSignals" hack might work if you move the
> send of initSignals to the beginning of the method; i.e., send initSignals
> just _once_, and do it _before_ the first send of recvDataAvail.
>
> (This is not the right solution though, and I don't endorse it in any way,
> since there is a still race between the return from initSignals [which can
> checkForInterrupts, causing i/o semaphores to be signaled] and the
> subsequent send of recvDataAvail. Caveat emptor.)
Ok... Might try it but as you say, it's not a solution.
> TTFN,
>
> Ian
regards, Göran