@@ -167,7 +167,8 @@ function dummy_uuid(project_file::String)
167167 end
168168 project_path = try
169169 realpath (project_file)
170- catch
170+ catch ex
171+ ex isa IOError || rethrow ()
171172 project_file
172173 end
173174 uuid = uuid5 (ns_dummy_uuid, project_path)
@@ -367,15 +368,15 @@ function locate_package(pkg::PkgId)::Union{Nothing,String}
367368 for env in load_path ()
368369 # look for the toplevel pkg `pkg.name` in this entry
369370 found = project_deps_get (env, pkg. name)
370- found === nothing && continue
371- if pkg == found
372- # pkg.name is present in this directory or project file,
373- # return the path the entry point for the code, if it could be found
374- # otherwise, signal failure
375- return implicit_manifest_uuid_path (env, pkg)
371+ if found != = nothing
372+ @assert found. name == pkg. name
373+ if found. uuid === nothing
374+ # pkg.name is present in this directory or project file,
375+ # return the path the entry point for the code, if it could be found
376+ # otherwise, signal failure
377+ return implicit_manifest_uuid_path (env, pkg)
378+ end
376379 end
377- @assert found. uuid != = nothing
378- return locate_package (found) # restart search now that we know the uuid for pkg
379380 end
380381 else
381382 for env in load_path ()
848849# or an Exception that describes why it couldn't be loaded
849850# and it reconnects the Base.Docs.META
850851function _include_from_serialized (pkg:: PkgId , path:: String , depmods:: Vector{Any} )
852+ assert_havelock (require_lock)
851853 sv = ccall (:jl_restore_incremental , Any, (Cstring, Any), path, depmods)
852854 if isa (sv, Exception)
853855 return sv
@@ -881,6 +883,7 @@ function _include_from_serialized(pkg::PkgId, path::String, depmods::Vector{Any}
881883end
882884
883885function run_package_callbacks (modkey:: PkgId )
886+ assert_havelock (require_lock)
884887 unlock (require_lock)
885888 try
886889 for callback in package_callbacks
@@ -897,34 +900,51 @@ function run_package_callbacks(modkey::PkgId)
897900end
898901
899902function _tryrequire_from_serialized (modkey:: PkgId , build_id:: UInt64 , modpath:: Union{Nothing, String} , depth:: Int = 0 )
903+ assert_havelock (require_lock)
904+ local loaded = nothing
900905 if root_module_exists (modkey)
901906 M = root_module (modkey)
902907 if PkgId (M) == modkey && module_build_id (M) === build_id
903- return M
908+ loaded = M
904909 end
905910 else
906- if modpath === nothing
907- modpath = locate_package (modkey)
908- modpath === nothing && return nothing
911+ loading = get (package_locks, modkey, false )
912+ if loading != = false
913+ # load already in progress for this module
914+ return wait (loading)
909915 end
910- mod = _require_search_from_serialized (modkey, String (modpath), depth)
911- get! (PkgOrigin, pkgorigins, modkey). path = modpath
912- if ! isa (mod, Bool)
913- run_package_callbacks (modkey)
914- for M in mod:: Vector{Any}
915- M = M:: Module
916- if PkgId (M) == modkey && module_build_id (M) === build_id
917- return M
916+ package_locks[modkey] = Threads. Condition (require_lock)
917+ try
918+ if modpath === nothing
919+ modpath = locate_package (modkey)
920+ modpath === nothing && return nothing
921+ end
922+ mod = _require_search_from_serialized (modkey, String (modpath), depth)
923+ get! (PkgOrigin, pkgorigins, modkey). path = modpath
924+ if ! isa (mod, Bool)
925+ for M in mod:: Vector{Any}
926+ M = M:: Module
927+ if PkgId (M) == modkey && module_build_id (M) === build_id
928+ loaded = M
929+ break
930+ end
918931 end
919932 end
933+ finally
934+ loading = pop! (package_locks, modkey)
935+ notify (loading, loaded, all= true )
936+ end
937+ if loaded != = nothing
938+ run_package_callbacks (modkey)
920939 end
921940 end
922- return nothing
941+ return loaded
923942end
924943
925944function _require_from_serialized (pkg:: PkgId , path:: String )
926945 # loads a precompile cache file, ignoring stale_cachfile tests
927946 # load all of the dependent modules first
947+ assert_havelock (require_lock)
928948 local depmodnames
929949 io = open (path, " r" )
930950 try
@@ -953,6 +973,7 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
953973# returns `false` if the module isn't known to be precompilable
954974# returns the set of modules restored if the cache load succeeded
955975@constprop :none function _require_search_from_serialized (pkg:: PkgId , sourcepath:: String , depth:: Int = 0 )
976+ assert_havelock (require_lock)
956977 timing_imports = TIMING_IMPORTS[] > 0
957978 try
958979 if timing_imports
@@ -969,7 +990,8 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
969990 staledeps = staledeps:: Vector{Any}
970991 try
971992 touch (path_to_try) # update timestamp of precompilation file
972- catch # file might be read-only and then we fail to update timestamp, which is fine
993+ catch ex # file might be read-only and then we fail to update timestamp, which is fine
994+ ex isa IOError || rethrow ()
973995 end
974996 # finish loading module graph into staledeps
975997 for i in 1 : length (staledeps)
@@ -987,6 +1009,7 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
9871009 if staledeps === true
9881010 continue
9891011 end
1012+ # @debug "Loading cache file $path for $pkg at $sourcepath"
9901013 restored = _include_from_serialized (pkg, path_to_try, staledeps)
9911014 if isa (restored, Exception)
9921015 @debug " Deserialization checks failed while attempting to load cache from $path_to_try " exception= restored
@@ -1165,18 +1188,19 @@ const pkgorigins = Dict{PkgId,PkgOrigin}()
11651188require (uuidkey:: PkgId ) = @lock require_lock _require_prelocked (uuidkey)
11661189
11671190function _require_prelocked (uuidkey:: PkgId )
1168- just_loaded_pkg = false
1191+ assert_havelock (require_lock)
11691192 if ! root_module_exists (uuidkey)
1170- _require (uuidkey)
1193+ newm = _require (uuidkey)
1194+ if newm === nothing
1195+ error (" package `$(uuidkey. name) ` did not define the expected \
1196+ module `$(uuidkey. name) `, check for typos in package module name" )
1197+ end
11711198 # After successfully loading, notify downstream consumers
11721199 run_package_callbacks (uuidkey)
1173- just_loaded_pkg = true
1174- end
1175- if just_loaded_pkg && ! root_module_exists (uuidkey)
1176- error (" package `$(uuidkey. name) ` did not define the expected \
1177- module `$(uuidkey. name) `, check for typos in package module name" )
1200+ else
1201+ newm = root_module (uuidkey)
11781202 end
1179- return root_module (uuidkey)
1203+ return newm
11801204end
11811205
11821206const loaded_modules = Dict {PkgId,Module} ()
@@ -1249,18 +1273,19 @@ function set_pkgorigin_version_path(pkg, path)
12491273 pkgorigin. path = path
12501274end
12511275
1252- # Returns `nothing` or the name of the newly-created cachefile
1276+ # Returns `nothing` or the new(ish) module
12531277function _require (pkg:: PkgId )
1278+ assert_havelock (require_lock)
12541279 # handle recursive calls to require
12551280 loading = get (package_locks, pkg, false )
12561281 if loading != = false
12571282 # load already in progress for this module
1258- wait (loading)
1259- return
1283+ return wait (loading)
12601284 end
12611285 package_locks[pkg] = Threads. Condition (require_lock)
12621286
12631287 last = toplevel_load[]
1288+ loaded = nothing
12641289 try
12651290 toplevel_load[] = false
12661291 # perform the search operation to select the module file require intends to load
@@ -1277,7 +1302,7 @@ function _require(pkg::PkgId)
12771302 if JLOptions (). use_compiled_modules != 0
12781303 m = _require_search_from_serialized (pkg, path)
12791304 if ! isa (m, Bool)
1280- return
1305+ return m
12811306 end
12821307 end
12831308
@@ -1312,7 +1337,7 @@ function _require(pkg::PkgId)
13121337 if isa (m, Exception)
13131338 @warn " The call to compilecache failed to create a usable precompiled cache file for $pkg " exception= m
13141339 else
1315- return
1340+ return m
13161341 end
13171342 end
13181343 end
@@ -1329,7 +1354,7 @@ function _require(pkg::PkgId)
13291354 unlock (require_lock)
13301355 try
13311356 include (__toplevel__, path)
1332- return
1357+ loaded = get (loaded_modules, key, nothing )
13331358 finally
13341359 lock (require_lock)
13351360 if uuid != = old_uuid
@@ -1339,9 +1364,9 @@ function _require(pkg::PkgId)
13391364 finally
13401365 toplevel_load[] = last
13411366 loading = pop! (package_locks, pkg)
1342- notify (loading, all= true )
1367+ notify (loading, loaded, all= true )
13431368 end
1344- nothing
1369+ return loaded
13451370end
13461371
13471372# relative-path load
0 commit comments