Skip to content

Commit 57704ee

Browse files
committed
fix race condition in require: if multiple tasks require() the same thing,
one should load it, and the others should wait for that one to finish. fixes #2805
1 parent 7e9cead commit 57704ee

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

Diff for: base/loading.jl

+11-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ find_in_node1_path(name) = myid()==1 ?
2828

2929
# Store list of files and their load time
3030
package_list = (ByteString=>Float64)[]
31+
# to synchronize multiple tasks trying to require something
32+
package_locks = (ByteString=>Any)[]
3133
require(fname::String) = require(bytestring(fname))
3234
require(f::String, fs::String...) = (require(f); for x in fs require(x); end)
3335

@@ -38,7 +40,11 @@ function require(name::ByteString)
3840
end
3941
end
4042
path = find_in_node1_path(name)
41-
has(package_list,path) || reload_path(path)
43+
if has(package_list,path)
44+
wait(package_locks[path])
45+
else
46+
reload_path(path)
47+
end
4248
end
4349

4450
function reload(name::String)
@@ -95,6 +101,9 @@ end
95101

96102
function reload_path(path)
97103
had = has(package_list, path)
104+
if !had
105+
package_locks[path] = RemoteRef()
106+
end
98107
package_list[path] = time()
99108
tls = task_local_storage()
100109
prev = delete!(tls, :SOURCE_PATH, nothing)
@@ -108,6 +117,7 @@ function reload_path(path)
108117
tls[:SOURCE_PATH] = prev
109118
end
110119
end
120+
put(package_locks[path],nothing)
111121
nothing
112122
end
113123

0 commit comments

Comments
 (0)