File 2107-Add-module_status-0-and-make-module_status-1-accept-.patch of Package erlang
From fe9b29382853e31c930f1442afd6e514dca12345 Mon Sep 17 00:00:00 2001
From: Richard Carlsson <richardc@klarna.com>
Date: Mon, 10 Jun 2019 12:04:52 +0200
Subject: [PATCH] Add module_status/0 and make module_status/1 accept a list of
modules
This allows checking the statuses of a large number of modules without
performing an excessive amount of file system operations.
---
lib/kernel/doc/src/code.xml | 17 +++++++++++++++--
lib/kernel/src/code.erl | 19 +++++++++++++++----
lib/kernel/test/code_SUITE.erl | 10 ++++++++++
3 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 4aa9e8b9d2..268eb5e839 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -314,6 +314,9 @@ zip:create("mnesia-4.4.7.ez",
<datatype>
<name name="load_error_rsn"/>
</datatype>
+ <datatype>
+ <name name="module_status"/>
+ </datatype>
<datatype>
<name name="prepared_code"/>
<desc><p>An opaque term holding prepared code.</p></desc>
@@ -900,11 +903,21 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
identical names and writes a report to <c>stdout</c>.</p>
</desc>
</func>
+ <func>
+ <name name="module_status" arity="0"/>
+ <fsummary>Return the statuses of all loaded modules.</fsummary>
+ <type name="module_status"/>
+ <desc>
+ <p>See <seealso marker="#module_status/1"><c>module_status/1</c></seealso> and <seealso marker="#all_loaded/0"><c>all_loaded/0</c></seealso> for details.</p>
+ </desc>
+ </func>
<func>
<name name="module_status" arity="1"/>
- <fsummary>Return the status of the module in relation to object file on disk.</fsummary>
+ <fsummary>Return the status of a module or modules in relation to the
+ object files on disk.</fsummary>
+ <type name="module_status"/>
<desc>
- <p>Returns:</p>
+ <p>The status of a module can be one of:</p>
<taglist>
<tag><c>not_loaded</c></tag>
<item><p>If <c><anno>Module</anno></c> is not currently loaded.</p></item>
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 964ede9bc9..f8893ede36 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -72,6 +72,7 @@
where_is_file/2,
set_primary_archive/4,
clash/0,
+ module_status/0,
module_status/1,
modified_modules/0,
get_mode/0]).
@@ -80,6 +81,7 @@
-export_type([load_error_rsn/0, load_ret/0]).
-export_type([prepared_code/0]).
+-export_type([module_status/0]).
-include_lib("kernel/include/file.hrl").
@@ -915,8 +917,19 @@ load_all_native_1([{Mod,BeamFilename}|T], ChunkTag) ->
load_all_native_1([], _) ->
ok.
+-type module_status() :: not_loaded | loaded | modified | removed.
+
+%% Returns the list of all loaded modules and their current status
+-spec module_status() -> [{module(), module_status()}].
+module_status() ->
+ module_status([M || {M, _} <- all_loaded()]).
+
%% Returns the status of the module in relation to object file on disk.
--spec module_status(Module :: module()) -> not_loaded | loaded | modified | removed.
+-spec module_status (Module :: module() | [module()]) ->
+ module_status() | [{module(), module_status()}].
+module_status(Modules) when is_list(Modules) ->
+ PathFiles = path_files(),
+ [{M, module_status(M, PathFiles)} || M <- Modules];
module_status(Module) ->
module_status(Module, code:get_path()).
@@ -991,9 +1004,7 @@ get_beam_chunk(Path, Chunk) ->
%% Returns a list of all modules modified on disk.
-spec modified_modules() -> [module()].
modified_modules() ->
- PathFiles = path_files(),
- [M || {M, _} <- code:all_loaded(),
- module_status(M, PathFiles) =:= modified].
+ [M || {M, modified} <- module_status()].
%% prefetch the directory contents of code path directories
path_files() ->
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 6b133f8d6b..665f9061d7 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -1880,6 +1880,11 @@ module_status() ->
loaded = code:module_status(erlang), % preloaded
loaded = code:module_status(?MODULE), % normal known loaded
+ %% module_status/0 returns status for each loaded module
+ true = (lists:sort([{M, code:module_status(M)}
+ || {M, _} <- code:all_loaded()])
+ =:= lists:sort(code:module_status())),
+
non_existing = code:which(?TESTMOD), % verify dummy name not in path
code:purge(?TESTMOD), % ensure no previous version in memory
code:delete(?TESTMOD),
@@ -1892,6 +1897,11 @@ module_status() ->
"" = code:which(?TESTMOD), % verify empty string for source file
loaded = code:module_status(?TESTMOD),
+ %% module_status/1 also accepts a list of modules
+ [] = code:module_status([]),
+ [{erlang, loaded},{?MODULE,loaded},{?TESTMOD,loaded}] =
+ code:module_status([erlang, ?MODULE, ?TESTMOD]),
+
%% deleting generated code
true = code:delete(?TESTMOD),
non_existing = code:which(?TESTMOD), % verify still not in path
--
2.16.4