Sigbjorn Finne wrote:

> "Dean Herington" <[EMAIL PROTECTED]> writes:
> >
> ...
> >
> > When a thread wants to read from a file descriptor, its logic looks like:
> >
> >         threadWaitRead (fdToInt fd)
> >         ([char], 1) <- locked (fdRead fd 1)
> >
> > where `locked` obtains and holds the aforementioned lock for the duration
> of
> > its argument action.
> >
> > Reflecting on the above, I now realize that the recent change
> > (/fptools/ghc/rts/Select.c?rev=1.22 in GHC 5.04) to wake up all threads
> when
> > select() returns an EBADF error, though well-intentioned, is
> inappropriate.
> > The point of `threadWaitRead` and `threadWaitWrite` is to block the
> calling
> > thread until it's known that a subsequent call involving the given file
> > descriptor will not block.  Allowing all threads to continue--even those
> > whose file descriptor is not yet ready--allows for exactly the deadlock
> that
> > `threadWaitRead` and `threadWaitWrite` are designed to avoid.
> >
>
> The assumption is that FDs are marked as non-blocking, so this won't
> be a problem. Do you have a good reason not to have your FDs marked
> as such?

One reason is complexity.  If  I mark my FDs with O_NONBLOCK, don't I need to
wrap a loop around the `threadWaitRead`/`fdRead` combination, repeating when
`fdRead` returns error `EAGAIN`?

A second reason is that, even if I did the above, I'd still get deadlock on my
`locked` call (which is required to support cleaning up unwanted threads in
forked processes).

The bottom line, in my view, is that `threadWaitRead` and `threadWaitWrite`
must not return until it is sure that a subsequent read or write FD operation
will return immediately, independent of the nonblocking status of the FD.

> > I consider it a bug in select() that, when EBADF is reported, the sets of
> > "ready" file descriptors are not also reported.
>
> That would be the wrong thing to do, assuming the FD_SETs are in any
> way valid when select() returns failure.

I don't understand your comment.  I fear I wasn't clear enough.  I meant that
it would be better for select() to identify the FDs which are invalid in the
case it returns `EBADF`.  Then the clumsy code I suggested would not be
necessary.

Dean

_______________________________________________
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to