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

close() is asynchronous? #36

Open
pallix opened this issue Feb 9, 2018 · 2 comments
Open

close() is asynchronous? #36

pallix opened this issue Feb 9, 2018 · 2 comments

Comments

@pallix
Copy link

pallix commented Feb 9, 2018

We have observed failure in our unit tests when the serial cannot be opened, as if it has not been closed properly during the termination of a previous test process.

At first I thought I would have to explicitly terminate it by trapping exit in another process but the GenServer documentation states:

Therefore it is not guaranteed that terminate/2 is called when a GenServer exits. For such reasons, we usually recommend important clean-up rules to happen in separated processes either by use of monitoring or by links themselves. For example if the GenServer controls a port (e.g. :gen_tcp.socket) or File.io_device/0, they will be closed on receiving a GenServer’s exit signal and do not need to be closed in terminate/2.

So I am assuming this is the case for Nerves also, so there is no need to explicitly close it.

Looking at the implementation of close/1, it is synchronous (GenServer.call is used) but internally it uses call_port which use message passing with the port.

Is it possible that this internal message passing is asynchronous and one of the test in the suite open the serial while the message to close it from the previous invocation has not been processed?

Adding a small delay ( :timer.sleep(100)) in the ExUnit setup function solves the problem. However I am not big fan of the solution, as solving problems with timers have a tendency to not be reliable and cause later problem when it is not expected.

If my hypothesis is true (asynchronous call is used internally), what approach would you suggest to solve the problem?

@entone
Copy link

entone commented Feb 9, 2018

You probably need to call Nerves.UART.stop(pid) to shutdown the GenServer

I ran into this issue yesterday, and that worked for me. It appears close doesn't fully release the file handler. I was on Ubuntu 16.04

@pallix
Copy link
Author

pallix commented Feb 9, 2018

I did but it did not solve the problem. Also, looking at the code, Nerves.UART close the port upon termination.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants