-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Open
Labels
Description
The following code tries to send a UDP packet to socat -v PIPE udp-recvfrom:9809,fork and then receive the echo response, but it consistently fails.
julia> using Sockets
julia> sock = UDPSocket()
bind(sock, ip"127.0.0.1", 0)
errormonitor(@async println(String(recv(sock))))
send(sock, ip"127.0.0.1", 9809, "hello")
sleep(1)
close(sock)
Unhandled Task ERROR: EOFError: read end of file
Stacktrace:
[1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
@ Base ./task.jl:958
[2] wait()
@ Base ./task.jl:1022
[3] wait(c::Base.GenericCondition{Base.Threads.SpinLock}; first::Bool)
@ Base ./condition.jl:130
[4] wait
@ ./condition.jl:125 [inlined]
[5] recvfrom(sock::UDPSocket)
@ Sockets ~/.julia/juliaup/julia-1.11.2+0.x64.apple.darwin14/share/julia/stdlib/v1.11/Sockets/src/Sockets.jl:359
[6] recv
@ ~/.julia/juliaup/julia-1.11.2+0.x64.apple.darwin14/share/julia/stdlib/v1.11/Sockets/src/Sockets.jl:324 [inlined]
[7] (::var"#7#8")()
@ Main ./REPL[6]:4The problem is that the send() "activates" the UDP socket and yields to the async task, and then the recv() notices that the socket is already "active" and skips registering the libuv callback.
julia/stdlib/Sockets/src/Sockets.jl
Lines 346 to 350 in 5e9a32e
| if ccall(:uv_is_active, Cint, (Ptr{Cvoid},), sock.handle) == 0 | |
| err = ccall(:uv_udp_recv_start, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), | |
| sock, | |
| @cfunction(Base.uv_alloc_buf, Cvoid, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid})), | |
| @cfunction(uv_recvcb, Cvoid, (Ptr{Cvoid}, Cssize_t, Ptr{Cvoid}, Ptr{Cvoid}, Cuint))) |
Original discussion: https://discourse.julialang.org/t/async-udp-socket-usage/
notthetup, attdona and Seelengrab