File 3662-ensure_loaded-should-check-with-code-server-for-pend.patch of Package erlang

From c9e6925c2ebef688f682f07e87c0ea025648b658 Mon Sep 17 00:00:00 2001
From: frazze-jobb <frazze@erlang.org>
Date: Wed, 8 Feb 2023 06:47:18 +0100
Subject: [PATCH 2/2] ensure_loaded should check with code server, for pending
 on_load

---
 lib/kernel/src/code.erl        | 19 +++++----
 lib/kernel/src/code_server.erl | 71 +++++++++++++++-------------------
 2 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index c56bbab4e5..932b48f300 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -186,7 +186,7 @@ objfile_extension() ->
 load_file(Mod) when is_atom(Mod) ->
     case get_object_code(Mod) of
         error -> {error,nofile};
-        {Mod,Binary,File} -> load_module(Mod, File, Binary, false)
+        {Mod,Binary,File} -> load_module(Mod, File, Binary, false, false)
     end.
 
 -spec ensure_loaded(Module) -> {module, Module} | {error, What} when
@@ -195,7 +195,12 @@ load_file(Mod) when is_atom(Mod) ->
 ensure_loaded(Mod) when is_atom(Mod) ->
     case erlang:module_loaded(Mod) of
         true -> {module, Mod};
-        false -> call({ensure_loaded,Mod})
+        false ->
+            case get_object_code(Mod) of
+                error -> call({sync_ensure_on_load, Mod});
+                {Mod,Binary,File} ->
+                    load_module(Mod, File, Binary, false, true)
+            end
     end.
 
 %% XXX File as an atom is allowed only for backwards compatibility.
@@ -213,7 +218,7 @@ load_abs(File, M) when (is_list(File) orelse is_atom(File)), is_atom(M) ->
             FileName = code_server:absname(FileName0),
             case erl_prim_loader:get_file(FileName) of
                 {ok,Bin,_} ->
-                    load_module(M, FileName, Bin, false);
+                    load_module(M, FileName, Bin, false, false);
                 error ->
                     {error, nofile}
             end;
@@ -231,16 +236,16 @@ load_abs(File, M) when (is_list(File) orelse is_atom(File)), is_atom(M) ->
 load_binary(Mod, File, Bin)
   when is_atom(Mod), (is_list(File) orelse is_atom(File)), is_binary(Bin) ->
     case modp(File) of
-        true -> load_module(Mod, File, Bin, true);
+        true -> load_module(Mod, File, Bin, true, false);
         false -> {error,badarg}
     end.
 
-load_module(Mod, File, Bin, Purge) ->
+load_module(Mod, File, Bin, Purge, EnsureLoaded) ->
     case erlang:prepare_loading(Mod, Bin) of
         {error,_}=Error ->
             Error;
         Prepared ->
-            call({load_module, Prepared, Mod, File, Purge})
+            call({load_module, Prepared, Mod, File, Purge, EnsureLoaded})
     end.
 
 modp(Atom) when is_atom(Atom) -> true;
@@ -1183,4 +1188,4 @@ path_files([Path|Tail]) ->
             [{Path,Files} | path_files(Tail)];
         _Error ->
             path_files(Tail)
-    end.
+    end.
\ No newline at end of file
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 8f0f9fba66..b9d4ae7022 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -289,22 +289,13 @@ handle_call({replace_path,Name,Dir}, _From,
 handle_call(get_path, _From, S) ->
     {reply,S#state.path,S};
 
-handle_call({load_module,PC,Mod,File,Purge}, From, S) when is_atom(Mod) ->
+handle_call({load_module,PC,Mod,File,Purge,EnsureLoaded}, From, S)
+  when is_atom(Mod) ->
     case Purge andalso erlang:module_loaded(Mod) of
 	true -> do_purge(Mod);
 	false -> ok
     end,
-    try_finish_module(File, Mod, PC, From, S);
-
-handle_call({ensure_loaded,Mod}, From, St) when is_atom(Mod) ->
-    case erlang:module_loaded(Mod) of
-	true ->
-	    {reply,{module,Mod},St};
-	false when St#state.mode =:= interactive ->
-	    ensure_loaded(Mod, From, St);
-	false ->
-	    {reply,{error,embedded},St}
-    end;
+    try_finish_module(File, Mod, PC, EnsureLoaded, From, S);
 
 handle_call({delete,Mod}, _From, St) when is_atom(Mod) ->
     case catch erlang:delete_module(Mod) of
@@ -350,6 +341,20 @@ handle_call(get_mode, _From, S=#state{mode=Mode}) ->
 handle_call({finish_loading,Prepared,EnsureLoaded}, _From, S) ->
     {reply,finish_loading(Prepared, EnsureLoaded, S),S};
 
+%% Handles pending on_load events when we cannot find any
+%% object code in code:ensure_loaded/1. It's possible that
+%% the user has loaded a binary that has an on_load
+%% function, and in that case we need to suspend them until
+%% the on_load function finishes.
+handle_call({sync_ensure_on_load, Mod}, From, S) ->
+    handle_pending_on_load(
+        fun(_, St) ->
+                case erlang:module_loaded(Mod) of
+                    true -> {reply, {module, Mod}, St};
+                    false -> {reply, {error, nofile}, St}
+                end
+        end, Mod, From, S);
+
 handle_call(Other,_From, S) ->
     error_msg(" ** Codeserver*** ignoring ~w~n ",[Other]),
     {noreply,S}.
@@ -1077,9 +1082,21 @@ add_paths(Where,[Dir|Tail],Path,NameDb) ->
 add_paths(_,_,Path,_) ->
     {ok,Path}.
 
-try_finish_module(File, Mod, PC, From, St) ->
+try_finish_module(File, Mod, PC, true, From, St) ->
+    Action = fun(_, S) ->
+                    case erlang:module_loaded(Mod) of
+                        true ->
+                            {reply,{module,Mod},S};
+                        false when S#state.mode =:= interactive ->
+                            try_finish_module_1(File, Mod, PC, From, S);
+                        false ->
+                            {reply,{error,embedded},S}
+                    end
+             end,
+    handle_pending_on_load(Action, Mod, From, St);
+try_finish_module(File, Mod, PC, false, From, St) ->
     Action = fun(_, S) ->
-		     try_finish_module_1(File, Mod, PC, From, S)
+		    try_finish_module_1(File, Mod, PC, From, S)
 	     end,
     handle_pending_on_load(Action, Mod, From, St).
 
@@ -1114,30 +1131,6 @@ int_list([H|T]) when is_integer(H) -> int_list(T);
 int_list([_|_])                    -> false;
 int_list([])                       -> true.
 
-ensure_loaded(Mod, From, St0) ->
-    Action = fun(_, S) ->
-		     case erlang:module_loaded(Mod) of
-			 true ->
-			     {reply,{module,Mod},S};
-			 false ->
-			     ensure_loaded_1(Mod, From, S)
-		     end
-	     end,
-    handle_pending_on_load(Action, Mod, From, St0).
-
-ensure_loaded_1(Mod, From, St) ->
-    case get_object_code(St, Mod) of
-	error ->
-	    {reply,{error,nofile},St};
-	{Mod,Binary,File} ->
-            case erlang:prepare_loading(Mod, Binary) of
-                {error, _} = Error ->
-                    {reply, Error, St};
-                PC ->
-	          try_finish_module_1(File, Mod, PC, From, St)
-            end
-    end.
-
 get_object_code(#state{path=Path}, Mod) when is_atom(Mod) ->
     ModStr = atom_to_list(Mod),
     case erl_prim_loader:is_basename(ModStr) of
@@ -1410,4 +1403,4 @@ archive_extension() ->
     init:archive_extension().
 
 to_list(X) when is_list(X) -> X;
-to_list(X) when is_atom(X) -> atom_to_list(X).
+to_list(X) when is_atom(X) -> atom_to_list(X).
\ No newline at end of file
-- 
2.35.3

openSUSE Build Service is sponsored by