Skip to content

Instantly share code, notes, and snippets.

@josevalim
Created April 11, 2014 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josevalim/10479623 to your computer and use it in GitHub Desktop.
Save josevalim/10479623 to your computer and use it in GitHub Desktop.
diff --git a/lib/task/sup.ex b/lib/task/sup.ex
index 3070aa2..4cc4968 100644
--- a/lib/task/sup.ex
+++ b/lib/task/sup.ex
@@ -66,10 +66,14 @@ defmodule Task.Sup do
"""
@spec async(Supervisor.supervisor, module, atom, [term]) :: Task.t
def async(supervisor, module, fun, args) do
- { :ok, pid } = Supervisor.start_child(supervisor, [self(), { module, fun, args }])
+ lock = make_ref()
+ Process.put(__MODULE__, lock)
+ { :ok, pid } = Supervisor.start_child(supervisor, [self(), { module, fun, args }, lock])
ref = Process.monitor(pid)
send pid, { self(), ref }
%Task{pid: pid, ref: ref}
+ after
+ Process.delete(__MODULE__)
end
@doc """
diff --git a/lib/task/supervised.ex b/lib/task/supervised.ex
index 78df117..341f3c7 100644
--- a/lib/task/supervised.ex
+++ b/lib/task/supervised.ex
@@ -5,8 +5,8 @@ defmodule Task.Supervised do
:proc_lib.start_link(__MODULE__, :noreply, [fun])
end
- def start_link(caller, fun) do
- :proc_lib.start_link(__MODULE__, :reply, [caller, fun])
+ def start_link(caller, fun, lock) do
+ :proc_lib.start_link(__MODULE__, :reply, [caller, fun, lock])
end
def async(caller, { module, fun, args }) do
@@ -27,7 +27,12 @@ defmodule Task.Supervised do
end
end
- def reply(caller, mfa) do
+ def reply(caller, mfa, lock) do
+ { :dictionary, dict } = Process.info(caller, :dictionary)
+ if dict[Task.Sup] != lock do
+ exit(:nocaller)
+ end
+
:erlang.link(caller)
:proc_lib.init_ack({ :ok, self() })
async(caller, mfa)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment