Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read() in separate thread not returning on close() #29

Closed
ekuemmel opened this issue Jan 15, 2021 · 6 comments
Closed

read() in separate thread not returning on close() #29

ekuemmel opened this issue Jan 15, 2021 · 6 comments
Labels
wontfix This will not be worked on

Comments

@ekuemmel
Copy link

Hello Phillip. I like that implementation and use it on a Raspberry. So far I had only one issue and this is about proper shutdown of an application. I have CAN socket (e.g. rawCanChannel) read() running in a separate thread and it should return when a close() is called from main thread. This is not happening (if i am not mistaken) and therefore the whole application can not be terminated since it hangs in read() forever.
Thanks
Eberhard

@pschichtel
Copy link
Owner

pschichtel commented Jan 15, 2021

Are you using blocking IO?

Would it be possible to provide a minimal reproducer for your issue?

@ekuemmel
Copy link
Author

ekuemmel commented Jan 15, 2021

Thank you for the quick reply. I created a small example application attached here.

demo.zip

I would expect that a read() done in a reader thread returns either with an exception or with null when the socket is closed from main thread.
This example listens max. 10 seconds to the CAN and closes then. The close is hanging and the application never terminates.

@pschichtel
Copy link
Owner

Thanks the reproducer. I wasn't sure my self if this is something that is even supposed to work and found this after a bit of googling: https://stackoverflow.com/questions/40301754/c-blocking-read-should-return-if-filedescriptor-is-deleted

So this is not a JavaCAN problem, but basically a misuse of the socket API. If the reproducer is representitve of your program, I can really recommend event-driven IO using a the EPollSelector (this will create a standard Java Selector in the 2.x branch or a custom IOSelector on master). The Selector API allows to be interrupted. You might also want to have a look at the CanBroker and maybe even the EventLoop.

@pschichtel pschichtel added the wontfix This will not be worked on label Jan 15, 2021
@ekuemmel
Copy link
Author

At least it works for streams. Closing the stream from another thread is same as reaching end of stream. The reaction is:

"Reads the next byte of data from the input stream. The value byte isreturned as an int in the range 0 to 255. If no byte is available because the end of the streamhas been reached, the value -1 is returned. This methodblocks until input data is available, the end of the stream is detected,or an exception is thrown. "

But maybe this is also not a safe way to do it. Thanks again for support.

@pschichtel
Copy link
Owner

The RawCanChannel class (same for IsotpCanChannel) is a pretty thin wrapper around the C socket(), read(), write() and close() syscalls. JavaCAN should behave exactly how these syscalls would in a C program, so in case things are unclear around the behaviour, you might also want to check the man pages of them. I'll add hints about this to the readme.

I generally consider wrong usage a documentation bug, so feel free to report more of these as they come up :)

@ekuemmel
Copy link
Author

ekuemmel commented Jan 15, 2021

I'll modify my code by calling read() only after a selector event.

pschichtel added a commit that referenced this issue Jan 15, 2021
JavaCAN is pretty low level.

Also properly through ClosedChannelException when operating on a closed channel (EBADF error)

See #29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants