read() does not return after a call to close()
Opened this issue · 4 comments
In the main()
, I'm opening a can-isotp socket, and I perform write()
operation on it. This part is working, the expected CAN frames are sent on the bus.
Now, I'm performing a blocking call to read()
on a separated thread. This part is also working, I'm receiving the expected CAN frames.
The issue arises when I'm calling close()
on the main()
function. I would expect the read()
function to return an error (such as EBADF
or something similar), but instead of this, it keeps blocking, while the close()
function returns 0.
Is it the expected behaviour? If it is the case, what is the proper way to exit from a blocking read()
?
I was not aware about this blocking read in a multithreaded environment. So I googled it for myself and found this:
https://stackoverflow.com/questions/16637086/linux-cancel-blocking-read
I don't know if this is a general problem with multithreading and if other Kernel syscall interfaces have a 'better' solution that returns the read
call when closing the socket.
The isotp implementation passes received PDUs via sock_queue_rcv_skb(sk, skb)
, see here:
https://elixir.bootlin.com/linux/v5.10.8/source/net/can/isotp.c#L239
So I only pass the data to the receive queue which is then passed 'somehow' to the user space.
I wonder if we can add some code to isotp_release()
that triggers blocking readers to return?!?
I will take a look into other sockets 'release' code in the kernel ...
Thanks for the hint! I'll take a look at it.
I got a similar report a while back on my JavaCAN lib (a thin wrapper around SocketCAN) and the reporter had the same issue with a CAN_RAW socket too. Back then I found this which made sense to me.