Nonblocking recvfrom?

Hi,
Is it a non-blocking alternative to recvfrom() ?
My application consist of two threads, where one of them is listening on a socket for incoming packets. The other thread then sends a signal to this thread after x seconds to tell it to return. This is done by using a Channel. But, it seems that recvfrom is blocking so that it don’t see that a signal is received on the channel… Does anyone have any suggestions to how I can solve this?

Timer on the waiting thread? No need for inter-thread communication here.

No I don’t use a Timer here. Just two threads, where one of them need to tell the other to stop. But it will not see this stop message, because recvfrom is blocking…

Yes, I got that. I was suggesting to use a Timer on the thread that’s waiting in recvfrom instead of using a Channel for that. Using a Channel means you have to actively check it, a Timer will interrupt you.

I want my main thread be the one that tells the second thread (which has the recvfrom) to quit. So I don’t want my second thread to tell itself when to quit…

Well, as far as I know, there is no nonblocking recvfrom (assuming you’re talking about Sockets.recvfrom). There’s also no good way to interrupt a running async task, which is why I suggested using a Timer to periodically interrupt the blocking behavior, then check the Channel for whether or not the thread should terminate or not, then relaunch a Timer and block again.

recvfrom is also written in Julia, you could roll your own

https://github.com/JuliaLang/julia/blob/master/stdlib/Sockets/src/Sockets.jl#L331-L365

I tried implementing a MWE now, and to my surprise this works fine. So after 2 seconds, the signal is sent, and the thread successfully quits… But, why does this work? I thought recvfrom was a blocking call?

using Sockets

function recv_data()
    insock = UDPSocket()
    from = Sockets.InetAddr(ip"127.0.0.1", 3000)
    bind(insock, from.host, from.port)

    while !(isready(running) && fetch(running) isa Stop)
        from, data = recvfrom(insock)
    end

    close(insock)
    return 
end

struct Stop end
running = Channel{Stop}(1)

t1 = @Threads.spawn recv_data()

sleep(2)
put!(running, Stop())

The docs say it blocks

Read a UDP packet from the specified socket, and return the bytes received. This call blocks.

Yes, it does. But then I thought in MWE that recv_data() would not exit as it does, because in the while-loop the recvfrom will block… But it do exit successfully… Why??

Are you sure this is working? It doesn’t appear it is to me:

using Sockets

function recv_data()
       insock = UDPSocket()
       from = Sockets.InetAddr(ip"127.0.0.1", 3000)
       bind(insock, from.host, from.port)

       while !(isready(running) && fetch(running) isa Stop)
           println("listening...")
           from, data = recvfrom(insock)
       end
       println("done.")
       close(insock)
       return
   end


struct Stop end
running = Channel{Stop}(1)

t1 = @Threads.spawn recv_data()

sleep(2)
put!(running, Stop())

sleep(2)
@show istaskdone(t1)

Outputs:

listening...
istaskdone(t1) = false

Which indicates that the recvfrom call is blocking t1 from exiting.