Skip to content

Commit 28824e8

Browse files
author
José Valim
committed
Ensure child task cannot link after parent unlinks
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
1 parent 3edc407 commit 28824e8

File tree

2 files changed

+15
-23
lines changed

2 files changed

+15
-23
lines changed

lib/elixir/lib/task/supervised.ex

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,21 @@ defmodule Task.Supervised do
1010
{:ok, :proc_lib.spawn_link(__MODULE__, :noreply, [info, fun])}
1111
end
1212

13-
def start_link(caller, link, info, fun) do
14-
{:ok, spawn_link(caller, link, info, fun)}
13+
def start_link(caller, monitor, info, fun) do
14+
{:ok, spawn_link(caller, monitor, info, fun)}
1515
end
1616

17-
def spawn_link(caller, link \\ :nolink, info, fun) do
18-
:proc_lib.spawn_link(__MODULE__, :reply, [caller, link, info, fun])
17+
def spawn_link(caller, monitor \\ :nomonitor, info, fun) do
18+
:proc_lib.spawn_link(__MODULE__, :reply, [caller, monitor, info, fun])
1919
end
2020

21-
def reply(caller, link, info, mfa) do
21+
def reply(caller, monitor, info, mfa) do
2222
initial_call(mfa)
23-
case link do
24-
:link ->
25-
try do
26-
Process.link(caller)
27-
catch
28-
:error, :noproc ->
29-
exit({:shutdown, :noproc})
30-
end
31-
reply(caller, nil, @ref_timeout, info, mfa)
23+
case monitor do
3224
:monitor ->
3325
mref = Process.monitor(caller)
3426
reply(caller, mref, @ref_timeout, info, mfa)
35-
:nolink ->
27+
:nomonitor ->
3628
reply(caller, nil, :infinity, info, mfa)
3729
end
3830
end

lib/elixir/lib/task/supervisor.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ defmodule Task.Supervisor do
106106
"""
107107
@spec async_nolink(Supervisor.supervisor, module, atom, [term]) :: Task.t
108108
def async_nolink(supervisor, module, fun, args) do
109-
do_async(supervisor, :monitor, module, fun, args)
109+
do_async(supervisor, :nolink, module, fun, args)
110110
end
111111

112112
@doc """
@@ -181,7 +181,7 @@ defmodule Task.Supervisor do
181181
Enumerable.t
182182
def async_stream_nolink(supervisor, enumerable, module, function, args, options \\ [])
183183
when is_atom(module) and is_atom(function) and is_list(args) do
184-
build_stream(supervisor, :monitor, enumerable, {module, function, args}, options)
184+
build_stream(supervisor, :nolink, enumerable, {module, function, args}, options)
185185
end
186186

187187
@doc """
@@ -197,7 +197,7 @@ defmodule Task.Supervisor do
197197
@spec async_stream_nolink(Supervisor.supervisor, Enumerable.t, (term -> term), Keyword.t) ::
198198
Enumerable.t
199199
def async_stream_nolink(supervisor, enumerable, fun, options \\ []) when is_function(fun, 1) do
200-
build_stream(supervisor, :monitor, enumerable, fun, options)
200+
build_stream(supervisor, :nolink, enumerable, fun, options)
201201
end
202202

203203
@doc """
@@ -250,20 +250,20 @@ defmodule Task.Supervisor do
250250

251251
defp do_async(supervisor, link_type, module, fun, args) do
252252
owner = self()
253-
args = [owner, link_type, get_info(owner), {module, fun, args}]
253+
args = [owner, :monitor, get_info(owner), {module, fun, args}]
254254
{:ok, pid} = Supervisor.start_child(supervisor, args)
255255
if link_type == :link, do: Process.link(pid)
256256
ref = Process.monitor(pid)
257257
send pid, {owner, ref}
258258
%Task{pid: pid, ref: ref, owner: owner}
259259
end
260260

261-
defp build_stream(supervisor, type, enumerable, fun, options) do
261+
defp build_stream(supervisor, link_type, enumerable, fun, options) do
262262
&Task.Supervised.stream(enumerable, &1, &2, fun, options, fn owner, mfa ->
263-
args = [owner, type, get_info(owner), mfa]
263+
args = [owner, :monitor, get_info(owner), mfa]
264264
{:ok, pid} = Supervisor.start_child(supervisor, args)
265-
if type == :link, do: Process.link(pid)
266-
{type, pid}
265+
if link_type == :link, do: Process.link(pid)
266+
{link_type, pid}
267267
end)
268268
end
269269
end

0 commit comments

Comments
 (0)