diff --git a/base/stream.jl b/base/stream.jl index ef2ce91558d13..37d229aac87be 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -640,6 +640,7 @@ end macro uv_write(n,call) esc(quote + check_open(s) uvw = c_malloc(_sizeof_uv_write+$(n)) err = $call if err < 0 @@ -661,7 +662,6 @@ function write!{T}(s::AsyncStream, a::Array{T}) end end function write!(s::AsyncStream, p::Ptr, nb::Integer) - check_open(s) @uv_write nb ccall(:jl_write_no_copy, Int32, (Ptr{Void}, Ptr{Void}, Uint, Ptr{Void}, Ptr{Void}), handle(s), p, nb, uvw, uv_jl_writecb::Ptr{Void}) return nb end @@ -672,9 +672,21 @@ function _uv_hook_writecb(s::AsyncStream, req::Ptr{Void}, status::Int32) nothing end +# Do not task-block TTY methods. These writes are process-blocking anyway, so we use the non-copying versions +write(t::TTY, b::Uint8) = @uv_write 1 ccall(:jl_putc_copy, Int32, (Uint8, Ptr{Void}, Ptr{Void}, Ptr{Void}), b, handle(s), uvw, uv_jl_writecb::Ptr{Void}) +write(s::TTY, c::Char) = @uv_write utf8sizeof(c) ccall(:jl_pututf8_copy, Int32, (Ptr{Void},Uint32, Ptr{Void}, Ptr{Void}), handle(s), c, uvw, uv_jl_writecb::Ptr{Void}) +function write{T}(s::TTY, a::Array{T}) + if isbits(T) + n = uint(length(a)*sizeof(T)) + @uv_write n ccall(:jl_write_no_copy, Int32, (Ptr{Void}, Ptr{Void}, Uint, Ptr{Void}, Ptr{Void}), handle(s), a, n, uvw, uv_jl_writecb::Ptr{Void}) + else + check_open(s) + invoke(write,(IO,Array),s,a) + end +end +write(s::TTY, p::Ptr, nb::Integer) = @uv_write nb ccall(:jl_write_no_copy, Int32, (Ptr{Void}, Ptr{Void}, Uint, Ptr{Void}, Ptr{Void}), handle(s), p, nb, uvw, uv_jl_writecb::Ptr{Void}) function write(s::AsyncStream, b::Uint8) - check_open(s) if isdefined(Main.Base,:Scheduler) && current_task() != Main.Base.Scheduler @uv_write 1 ccall(:jl_putc_copy, Int32, (Uint8, Ptr{Void}, Ptr{Void}, Ptr{Void}), b, handle(s), uvw, uv_jl_writecb_task::Ptr{Void}) uv_req_set_data(uvw,current_task()) @@ -685,7 +697,6 @@ function write(s::AsyncStream, b::Uint8) return 1 end function write(s::AsyncStream, c::Char) - check_open(s) if isdefined(Main.Base,:Scheduler) && current_task() != Main.Base.Scheduler @uv_write utf8sizeof(c) ccall(:jl_pututf8_copy, Int32, (Ptr{Void},Uint32, Ptr{Void}, Ptr{Void}), handle(s), c, uvw, uv_jl_writecb_task::Ptr{Void}) uv_req_set_data(uvw,current_task()) @@ -696,7 +707,6 @@ function write(s::AsyncStream, c::Char) return utf8sizeof(c) end function write{T}(s::AsyncStream, a::Array{T}) - check_open(s) if isbits(T) if isdefined(Main.Base,:Scheduler) && current_task() != Main.Base.Scheduler n = uint(length(a)*sizeof(T)) @@ -708,16 +718,17 @@ function write{T}(s::AsyncStream, a::Array{T}) end return int(length(a)*sizeof(T)) else + check_open(s) invoke(write,(IO,Array),s,a) end end function write(s::AsyncStream, p::Ptr, nb::Integer) - check_open(s) if isdefined(Main.Base,:Scheduler) && current_task() != Main.Base.Scheduler @uv_write nb ccall(:jl_write_no_copy, Int32, (Ptr{Void}, Ptr{Void}, Uint, Ptr{Void}, Ptr{Void}), handle(s), p, nb, uvw, uv_jl_writecb_task::Ptr{Void}) uv_req_set_data(uvw,current_task()) wait() else + check_open(s) ccall(:jl_write, Uint, (Ptr{Void},Ptr{Void},Uint), handle(s), p, uint(nb)) end return int(nb)