Skip to content

Commit 5d33830

Browse files
committed
Only make module available after inference to avoid races
1 parent c01a47e commit 5d33830

File tree

1 file changed

+13
-24
lines changed

1 file changed

+13
-24
lines changed

lib/elixir/lib/module/parallel_checker.ex

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ defmodule Module.ParallelChecker do
7171
{^ref, :cache} ->
7272
Process.link(pid)
7373

74-
module_tuple =
74+
{mode, module_tuple} =
7575
cond do
7676
is_binary(info) ->
7777
location =
@@ -86,13 +86,14 @@ defmodule Module.ParallelChecker do
8686
{:ok, module_map} <- backend.debug_info(:elixir_v1, module, data, []) do
8787
cache_from_module_map(table, module_map)
8888
else
89-
_ -> nil
89+
_ -> {:not_found, nil}
9090
end
9191

9292
is_tuple(info) ->
9393
info
9494
end
9595

96+
:ets.insert(table, {module, mode})
9697
send(checker, {ref, :cached})
9798

9899
receive do
@@ -416,21 +417,22 @@ defmodule Module.ParallelChecker do
416417
true ->
417418
{mode, exports} = info_exports(module)
418419
deprecated = info_deprecated(module)
419-
cache_info(table, module, exports, deprecated, %{}, mode)
420+
cache_info(table, module, exports, deprecated, %{})
421+
mode
420422

421423
false ->
422424
# Or load exports from chunk
423425
with {^module, binary, _filename} <- object_code,
424426
{:ok, {^module, [exports: exports]}} <- :beam_lib.chunks(binary, [:exports]) do
425-
cache_info(table, module, exports, %{}, %{}, :erlang)
427+
cache_info(table, module, exports, %{}, %{})
428+
:erlang
426429
else
427-
_ ->
428-
:ets.insert(table, {module, :not_found})
429-
nil
430+
_ -> :not_found
430431
end
431432
end
432433
end
433434

435+
:ets.insert(table, {module, mode})
434436
unlock(checker, module, mode)
435437
end
436438
end
@@ -461,26 +463,15 @@ defmodule Module.ParallelChecker do
461463
behaviour_exports(map) ++
462464
for({function, :def, _meta, _clauses} <- map.definitions, do: function)
463465

464-
cache_info(
465-
table,
466-
map.module,
467-
exports,
468-
Map.new(map.deprecated),
469-
map.signatures,
470-
elixir_mode(map.attributes)
471-
)
472-
473-
module_map_to_module_tuple(map)
466+
cache_info(table, map.module, exports, Map.new(map.deprecated), map.signatures)
467+
{elixir_mode(map.attributes), module_map_to_module_tuple(map)}
474468
end
475469

476-
defp cache_info(table, module, exports, deprecated, sigs, mode) do
470+
defp cache_info(table, module, exports, deprecated, sigs) do
477471
Enum.each(exports, fn fa ->
478472
reason = Map.get(deprecated, fa)
479473
:ets.insert(table, {{module, fa}, reason, Map.get(sigs, fa, :none)})
480474
end)
481-
482-
:ets.insert(table, {module, mode})
483-
mode
484475
end
485476

486477
defp cache_chunk(table, module, contents) do
@@ -497,9 +488,7 @@ defmodule Module.ParallelChecker do
497488
)
498489
end)
499490

500-
mode = Map.get(contents, :mode, :elixir)
501-
:ets.insert(table, {module, mode})
502-
mode
491+
Map.get(contents, :mode, :elixir)
503492
end
504493

505494
defp behaviour_exports(%{defines_behaviour: true}), do: [{:behaviour_info, 1}]

0 commit comments

Comments
 (0)