changed CHANGELOG.md
 
@@ -1,10 +1,16 @@
1
1
# Changelog
2
2
3
- ## v2.0.0 - 2022-11-12
3
+ ## v2.0.1 - 2024-01-14
4
+
5
+ * Changes
6
+ * Fix race condition when multiple processes load the NIF simultaneously that
7
+ would cause an unnecessary crash.
8
+
9
+ ## v2.0.0 - 2023-11-12
4
10
5
11
Official v2.0.0 release. No changes from v2.0.0-pre.0.
6
12
7
- ## v2.0.0-pre.0 - 2022-05-30
13
+ ## v2.0.0-pre.0 - 2023-05-30
8
14
9
15
This is a major update to Circuits.SPI that removes the requirement to use
10
16
Nerves or Linux. The API is almost the same and the default is to compile and
changed README.md
 
@@ -7,8 +7,7 @@
7
7
8
8
`Circuits.SPI` lets you communicate with hardware devices using the SPI protocol.
9
9
10
- *This is the v2.0 development branch. It's not ready yet. Most users will want
11
- to follow the [maint-v1.x branch](https://github.com/elixir-circuits/circuits_spi/tree/maint-v1.x).*
10
+ *This is Circuits.SPI v2. Circuits.SPI v1.x is still maintained in the [maint-v1.x branch](https://github.com/elixir-circuits/circuits_spi/tree/maint-v1.x).*
12
11
13
12
`Circuits.SPI` v2.0 is an almost backwards compatible update to `Circuits.SPI`
14
13
v1.x. Here's what's new:
changed hex_metadata.config
 
@@ -1,7 +1,7 @@
1
1
{<<"links">>,
2
2
[{<<"GitHub">>,<<"https://github.com/elixir-circuits/circuits_spi">>}]}.
3
3
{<<"name">>,<<"circuits_spi">>}.
4
- {<<"version">>,<<"2.0.0">>}.
4
+ {<<"version">>,<<"2.0.1">>}.
5
5
{<<"description">>,<<"Use SPI in Elixir">>}.
6
6
{<<"elixir">>,<<"~> 1.10">>}.
7
7
{<<"app">>,<<"circuits_spi">>}.
changed lib/spi/spi_nif.ex
 
@@ -5,15 +5,19 @@
5
5
defmodule Circuits.SPI.Nif do
6
6
@moduledoc false
7
7
8
- defp load_nif() do
8
+ defp load_nif_and_apply(fun, args) do
9
9
nif_binary = Application.app_dir(:circuits_spi, "priv/spi_nif")
10
- :erlang.load_nif(to_charlist(nif_binary), 0)
10
+
11
+ # Optimistically load the NIF. Handle the possible race.
12
+ case :erlang.load_nif(to_charlist(nif_binary), 0) do
13
+ :ok -> apply(__MODULE__, fun, args)
14
+ {:error, {:reload, _}} -> apply(__MODULE__, fun, args)
15
+ error -> error
16
+ end
11
17
end
12
18
13
19
def open(bus_name, mode, bits_per_word, speed_hz, delay_us, lsb_first) do
14
- with :ok <- load_nif() do
15
- apply(__MODULE__, :open, [bus_name, mode, bits_per_word, speed_hz, delay_us, lsb_first])
16
- end
20
+ load_nif_and_apply(:open, [bus_name, mode, bits_per_word, speed_hz, delay_us, lsb_first])
17
21
end
18
22
19
23
def config(_ref), do: :erlang.nif_error(:nif_not_loaded)
 
@@ -22,7 +26,6 @@ defmodule Circuits.SPI.Nif do
22
26
def max_transfer_size(), do: :erlang.nif_error(:nif_not_loaded)
23
27
24
28
def info() do
25
- :ok = load_nif()
26
- apply(__MODULE__, :info, [])
29
+ load_nif_and_apply(:info, [])
27
30
end
28
31
end
changed mix.exs
 
@@ -1,7 +1,7 @@
1
1
defmodule Circuits.SPI.MixProject do
2
2
use Mix.Project
3
3
4
- @version "2.0.0"
4
+ @version "2.0.1"
5
5
@description "Use SPI in Elixir"
6
6
@source_url "https://github.com/elixir-circuits/circuits_spi"