diff --git a/lib/sweet_xml.ex b/lib/sweet_xml.ex index 8d3646e..f0e2fe1 100644 --- a/lib/sweet_xml.ex +++ b/lib/sweet_xml.ex @@ -490,7 +490,7 @@ defmodule SweetXml do {ref, pid, monref, do_after} -> _ = Process.demonitor(monref) _ = SweetXml.Options.clean_up(do_after) - flush_halt(pid, ref) + flush_halt(pid, ref, monref) end end @@ -545,7 +545,7 @@ defmodule SweetXml do {ref, pid, monref, do_after} -> _ = Process.demonitor(monref) _ = SweetXml.Options.clean_up(do_after) - flush_halt(pid, ref) + flush_halt(pid, ref, monref) end end @@ -843,12 +843,20 @@ defmodule SweetXml do end end - defp flush_halt(pid, ref) do + defp flush_halt(pid, ref, monref) do receive do {:event, ^ref, _} -> - flush_halt(pid, ref) # flush all emitted elems after :halt + # flush all emitted elems after :halt + flush_halt(pid, ref, monref) + {:wait, ^ref} -> - send(pid, {:halt, ref}) # tell the continuation function to halt the underlying stream + # tell the continuation function to halt the underlying stream + send(pid, {:halt, ref}) + :done + + {:DOWN, ^monref, :process, ^pid, :normal} -> + # flush down message from possibly dead process before demonitoring + :done end end diff --git a/test/issue_97_test.exs b/test/issue_97_test.exs new file mode 100644 index 0000000..10ee9c0 --- /dev/null +++ b/test/issue_97_test.exs @@ -0,0 +1,29 @@ +defmodule Issue97Test do + use ExUnit.Case + + test "stream_tags doesn't hang when used with stream take on empty xml" do + parent = self() + ref = make_ref() + spawn_link fn -> + "" + |> SweetXml.stream_tags(:feed) + |> Stream.take(1) + |> Enum.to_list() + send(parent, {ref, :ok}) + end + assert_receive {^ref, :ok}, :timer.seconds(1) + end + + test "stream_tags! doesn't hang when used with stream take on empty xml" do + parent = self() + ref = make_ref() + spawn_link fn -> + "" + |> SweetXml.stream_tags!(:feed) + |> Stream.take(1) + |> Enum.to_list() + send(parent, {ref, :ok}) + end + assert_receive {^ref, :ok}, :timer.seconds(1) + end +end