Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
5362-ensure_loaded-should-check-with-code-serve...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5362-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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor