poll_fd fix

@JeffBezanson This implements julep #4401 in order to fix the issues with poll_fd (#6563)

julep #4401 is implemented by separating the steps involved with a call to `wait` into their component parts:

`waitq` --> prepares the wait call
`waitresult` --> extract a result from wait (if present)
`waitcleanup` --> cleanup after the wait call (remove from waitq)
`waitkill` --> additional cleanup (destructors) after the wait call

if these specialized methods don't exist, it simply falls back to calling `wait` in a Task (graceful degradation means a loss in performance, but not in functionality)

client code can plug into these methods, just like they currently can extend `wait`. for example, see `Timer`

also notable: `sleep(::Real)` is now an alias for `wait()`, since `wait(::Real)` was defined to mean `wait for timeout`
I fully agree that we should abstract the multiple-waiting pattern. I just
don't yet believe that `waitkill` is a meaningful operation. It is
surprising that waiting for multiple things would need 4 new concepts.
On Jun 16, 2014 8:02 PM, "Jameson Nash" <notifications@github.com> wrote:

> In base/stream.jl:
>
> > @@ -503,6 +503,15 @@ function sleep(sec::Real)
> >      end
> >      nothing
>
> if I wanted to avoid some code duplication (but still avoid creating an
> extra Tasks just to add a timeout), I could have written:
>
> function wait(sec::Real)
>     killq = Array(Timer,1); resize!(killq, 0)
>     w = waitq(sec, killq)
>     try
>         wait(w)
>     finally
>         for t in killq
>             waitkill(t, current_task())
>         end
>     end
>     nothingend
>
> Or just left the method out entirely (the body of this method is
> essentially equivalent to the wait(...) method, and not that much more
> efficient). But it didn't seem like that much of a code copy to really care
> about.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/JuliaLang/julia/pull/7275/files#r13836995>.
>