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

Fix network.erl race conditions #1487

Open
wants to merge 3 commits into
base: release-0.6
Choose a base branch
from

Conversation

petermm
Copy link
Contributor

@petermm petermm commented Jan 22, 2025

As evidenced by failing simtest CI on release-0.6 etc.

  1. startup should use continue/handle_continue and avoid races + cleaner DRY code.

  2. network:stop was using nonblocking call to stop network_port- so rapid stop/start would give the last network:start an old whereis(network_port) that was still shutting down, and lead to errors.

  3. somewhat unrelated: sta_rssi was using get_port(), and would crash on no network started - guarded it erlang side, added test.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

Cleaner, DRY code - and avoid any potential races.

Signed-off-by: Peter M <[email protected]>
network:stop through terminate was using nonblocking call to stop network_port- so rapid stop/start would give the second network:start an old whereis(network_port) that was still shutting down, and lead to errors.

Now waits for port DOWN.

Signed-off-by: Peter M <[email protected]>
Calling network:sta_rssi() would crash if network was not started.

Handle this and return error tuple, and added test.

Signed-off-by: Peter M <[email protected]>
Copy link
Contributor

@arpunk arpunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick

% Handle unexpected messages if necessary
wait_for_port_close(PortMonitor, Pid)
% Timeout after 4000 milliseconds
after 4000 ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to be able to pass the timeout as an option at startup and default to 4_000 if not provided.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on that idea.

Copy link
Collaborator

@UncleGrumpy UncleGrumpy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, thanks for spotting my error in sta_rssi/0! Of course I should not have stated a new network_port if it was not yet open.

Ref = make_ref(),
Pid = State#state.port,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call it Port ;-)
Also, the monitor could be set up in init/1 and used as Ref in #state.

@@ -25,6 +25,7 @@
start() ->
case verify_platform(atomvm:platform()) of
ok ->
network:sta_rssi(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we assert (match) the result?

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

Successfully merging this pull request may close these issues.

4 participants